news 2026/5/6 14:24:33

Zephyr 的 Counter alarm

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Zephyr 的 Counter alarm

Zephyr 的 Counter 驱动支持“相对闹钟”和“绝对闹钟”两种触发语义。区别在于struct counter_alarm_cfg里的flagsticks的含义。

关键结构体:

struct counter_alarm_cfg { counter_alarm_callback_t callback; //回调 uint32_t ticks; //不同模式下含义不同(见下) void *user_data; //给callback做回调参数 uint32_t flags; //标志闹钟模式 };

常用标志位(flags

  • alarm_cfg.flags = COUNTER_ALARM_CFG_ABSOLUTE
    绝对闹钟ticks表示计数器周期空间内的绝对计数值(例如下一次的目标计数点)。需要你自己处理取模(wrap)。
  • 缺省(alarm_cfg.flags = 0
    相对闹钟ticks表示相对当前的延迟,即“从现在开始延迟多少 ticks 后触发”。

设定闹钟函数

intcounter_set_channel_alarm(conststructdevice*dev,uint8_tchannel_id,conststructcounter_alarm_cfg*alarm_cfg);

不同模式下ticks的含义

相对闹钟

相对闹钟alarm_cfg.flags = 0

  • ticks表示从现在起ticks后触发(相对当前计数值),通常允许的最大延迟受计数器的拓展/回卷周期(top)以及驱动“保护期(guard period)”限制。

  • 使用情况:需求是“每隔固定时长触发”(周期性任务),最简单且不需要考虑取模。注意不要累加延迟。

  • 参考代码实现,通过信号量释放while循环阻塞,1s触发一次:

#include<zephyr/drivers/counter.h>staticstructcounter_alarm_cfgalarm_cfg;staticuint32_tperiod_ticks;staticstructk_semsem;staticvoidalarm_cb(conststructdevice*dev,uint8_tchan_id,uint32_tticks,void*user_data){structcounter_alarm_cfg*config=user_data;// 周期性:固定相对延迟为 period_ticks(不要累加)// config.ticks = period_ticks; 这个不用动interr=counter_set_channel_alarm(dev,chan_id,&config);if(err){printk("re-arm failed: %d\n",err);}k_sem_give(&sem);}voidmain(void){conststructdevice*dev=DEVICE_DT_GET(TIMER);// 你的计时器设备if(!device_is_ready(dev)){printk("counter not ready\n");return;}k_sem_init(&sem,0,1);// 计算 1 秒对应的 ticksperiod_ticks=counter_us_to_ticks(dev,1000000U);//(可选)设置保护期,避免过近设置失败//counter_set_guard_period(dev, counter_us_to_ticks(dev, 200U), COUNTER_GUARD_PERIOD_LATE);// 启动计数器counter_start(dev);// 首次设置:相对 1 秒后触发alarm_cfg.flags=0;// 相对模式alarm_cfg.ticks=period_ticks;// 相对延迟alarm_cfg.callback=alarm_cb;alarm_cfg.user_data=&alarm_cfg;// 让回调能访问配置interr=counter_set_channel_alarm(dev,0,&alarm_cfg);if(err){printk("set alarm failed: %d\n",err);}while(1){k_sem_take(&sem,K_FOREVER);// 可在此做一些cycle性质的工作}}

绝对闹钟

绝对闹钟alarm_cfg.flags = COUNTER_ALARM_CFG_ABSOLUTE

  • ticks表示计数器周期空间内的绝对目标值(比如“当计数值到 N 时触发”)。

  • 使用情况:

    需要保证你设置的下一个闹钟值落在[0, top)区间内。所以需要注意自己取模。如果不做取模,传入的绝对值超出范围,驱动一般会返回-EINVAL

    如果计数器是向下计数,你可以用原始硬件计数空间或把它转换成统一的“向上空间”,但要一致

  • 参考代码实现

#include<zephyr/drivers/counter.h>#include<zephyr/kernel.h>#include<zephyr/sys/printk.h>staticstructcounter_alarm_cfgalarm_cfg;staticuint32_tperiod_ticks;staticuint32_ttop;staticstructk_semsem;staticvoidalarm_cb(conststructdevice*dev,uint8_tchan_id,uint32_tfired_ticks,void*user_data){ARG_UNUSED(user_data);// fired_ticks 是这次触发的绝对计数值(在周期空间内)// 下一个绝对触发点 = 本次触发点 + 周期(取模 top)uint64_tnext=(uint64_t)fired_ticks+(uint64_t)period_ticks;uint32_tnext_ticks=(uint32_t)(next%top);printk("Alarm fired (absolute). now=%u next=%u\n",fired_ticks,next_ticks);alarm_cfg.ticks=next_ticks;alarm_cfg.flags=COUNTER_ALARM_CFG_ABSOLUTE;interr=counter_set_channel_alarm(dev,chan_id,&alarm_cfg);if(err){printk("re-arm failed: %d\n",err);}k_sem_give(&sem);}voidmain(void){conststructdevice*dev=DEVICE_DT_GET(TIMER);if(!device_is_ready(dev)){printk("counter not ready\n");return;}k_sem_init(&sem,0,1);period_ticks=counter_us_to_ticks(dev,1000000U);top=counter_get_top_value(dev);counter_start(dev);// 读取当前绝对计数值作为起点uint32_tnow;interr=counter_get_value(dev,&now);if(err){printk("get value failed: %d\n",err);return;}// 第一次触发点 = 当前值 + 周期(取模)uint32_tfirst=(now+period_ticks)%top;alarm_cfg.flags=COUNTER_ALARM_CFG_ABSOLUTE;alarm_cfg.ticks=first;// 绝对目标值alarm_cfg.callback=alarm_cb;alarm_cfg.user_data=&alarm_cfg;err=counter_set_channel_alarm(dev,0,&alarm_cfg);if(err){printk("set alarm failed: %d\n",err);}while(1){k_sem_take(&sem,K_FOREVER);// 与回调同步}}
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/28 0:04:41

C++面向对象与类和对象(一)----C++重要基础入门知识

hello&#xff0c;这里是AuroraWanderll。 兴趣方向&#xff1a;C&#xff0c;算法&#xff0c;Linux系统&#xff0c;游戏客户端开发 欢迎关注&#xff0c;我将更新更多相关内容&#xff01;个人主页 这是类和对象系列的第一篇文章&#xff1a; 之前由于第一次发布时篇幅过长&…

作者头像 李华
网站建设 2026/4/28 17:04:44

Flomo到Obsidian数据迁移终极指南:一键同步您的知识宝库

Flomo到Obsidian数据迁移终极指南&#xff1a;一键同步您的知识宝库 【免费下载链接】flomo-to-obsidian Make Flomo Memos to Obsidian Notes 项目地址: https://gitcode.com/gh_mirrors/fl/flomo-to-obsidian 还在为Flomo和Obsidian之间的数据迁移而烦恼吗&#xff1f…

作者头像 李华
网站建设 2026/5/3 7:03:58

ShellCheck VS Code扩展终极配置指南

ShellCheck VS Code扩展终极配置指南 【免费下载链接】vscode-shellcheck Integrates ShellCheck into VS Code, a linter for Shell scripts. 项目地址: https://gitcode.com/gh_mirrors/vs/vscode-shellcheck Shell脚本开发中常常遇到语法错误、潜在问题难以发现&…

作者头像 李华
网站建设 2026/5/4 11:35:09

9 个继续教育文献综述工具,AI 写作降重推荐

9 个继续教育文献综述工具&#xff0c;AI 写作降重推荐 论文写作的“重灾区”&#xff1a;文献综述与降重的双重挑战 在继续教育的学习过程中&#xff0c;撰写文献综述是一项既重要又令人头疼的任务。它不仅是对已有研究成果的梳理和总结&#xff0c;更是展现学术思维与研究能力…

作者头像 李华