news 2026/7/7 21:40:57

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/7/7 13:54:14

公网IPv4建站的过程

把用公网IPv4建站的过程&#xff0c;比喻成“开一家有自己独立门牌号的店铺”&#xff0c;这样会非常通俗易懂。核心比喻你的电脑/服务器 你的店铺仓库&#xff08;里面放着你的网站文件&#xff09;。公网IPv4地址 你店铺独一无二的 “经纬度坐标” 或 “门牌号”&#xff0…

作者头像 李华
网站建设 2026/7/7 12:33:18

Wan2.2-T2V-A14B在游戏过场动画预演中的应用场景

Wan2.2-T2V-A14B在游戏过场动画预演中的应用场景 你有没有经历过这样的场景&#xff1f;策划写完一段史诗级BOSS战脚本&#xff0c;导演眉头紧锁&#xff1a;“这镜头到底该怎么拍&#xff1f;”美术组一脸茫然&#xff1a;“你说‘雷电劈下武器充能’……那光效是蓝紫色渐变还…

作者头像 李华
网站建设 2026/7/7 14:42:57

挖矿小游戏-jshook对抗 | AST插件还原多层For-Swtich控制流实战

【作者主页】&#xff1a;小鱼神1024 【擅长领域】&#xff1a;JS逆向、小程序逆向、AST还原、验证码突防、Python开发、浏览器插件开发、React前端开发、NestJS后端开发等等 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;不提供完整代码&#…

作者头像 李华
网站建设 2026/7/7 11:33:27

LeetCode876/141/142/143 快慢指针应用:链表中间 / 环形 / 重排问题

目录 一、876. 链表的中间节点&#xff08;快慢指针基础&#xff09; 题目核心 核心难点拆解 深度思路&#xff08;盒子 - 标签 - 纸条模型&#xff09; 代码实现&#xff08;带关键点标注&#xff09; 易踩坑点 & 底层原理 二、141. 环形链表&#xff08;判环的必然…

作者头像 李华
网站建设 2026/7/7 8:29:04

CoreProtect快速部署指南:高效守护Minecraft服务器数据安全

CoreProtect快速部署指南&#xff1a;高效守护Minecraft服务器数据安全 【免费下载链接】CoreProtect CoreProtect is a blazing fast data logging and anti-griefing tool for Minecraft servers. 项目地址: https://gitcode.com/gh_mirrors/co/CoreProtect 作为Minec…

作者头像 李华
网站建设 2026/7/7 18:34:41

【国产】华为欧拉操作系统openEuler-LTS-22.03安装Docker-Compose保姆级教程

本文主要介绍华为欧拉操作系统 openEuler-LTS-22.03 安装Docker-Compose保姆级教程。后面文章将介绍通过 Docker Compose 一键部署应用。 一、Docker Compose介绍 Docker-Compose是Docker官方的开源项目&#xff0c;负责实现对Docker容器集群的快速编排。 Docker-Compose作用…

作者头像 李华