Zephyr 提供了强大的定时器机制,支持单次和周期性定时任务。定时器是实时系统中实现时间控制和任务调度的基础。
这是最常用的定时器,基于内核时钟。
// 定义定时器
struct k_timer my_timer;
// 定时器回调函数
void timer_handler(struct k_timer *timer)
{
printk("Timer expired!\n");
}
// 初始化
k_timer_init(&my_timer, timer_handler, NULL);
// 启动(周期性:100ms周期,0首次延迟)
k_timer_start(&my_timer, K_NO_WAIT, K_MSEC(100));
// 启动(单次:500ms后触发)
k_timer_start(&my_timer, K_MSEC(500), K_NO_WAIT);
// 停止定时器
k_timer_stop(&my_timer);
// 检查是否正在运行
if (k_timer_is_pending(&my_timer)) {
// 定时器正在运行
}
用于微秒级精度的忙等待延迟。
// 忙等待 100 微秒(阻塞CPU)
k_busy_wait(100);
注意:忙等待期间CPU被占用,不执行其他任务。
线程睡眠,让出CPU。
// 睡眠 100 毫秒
k_sleep(K_MSEC(100));
// 睡眠 1 秒
k_sleep(K_SECONDS(1));
// 睡眠直到绝对时间
k_sleep(K_TIMEOUT_ABS_MS(target_ms));
struct k_timer {
struct k_timeout timeout;
struct k_thread *thread;
k_timer_expiry_t expiry_fn;
k_timer_stop_t stop_fn;
uint32_t period;
uint32_t duration;
// ... 内部字段
};
// 到期回调(必需)
void expiry_function(struct k_timer *timer)
{
// 定时器到期时调用
// 在中断上下文执行,需快速返回
}
// 停止回调(可选)
void stop_function(struct k_timer *timer)
{
// 定时器停止时调用
}
// 获取剩余时间(到期前)
int64_t remaining = k_timer_remaining_get(&my_timer);
// 获取已经过时间(从启动开始)
int64_t elapsed = k_timer_elapsed(&my_timer);
// 获取到期计数
uint32_t count = k_timer_status_get(&my_timer);
// 同步等待定时器到期
k_timer_status_sync(&my_timer);
struct k_timer one_shot_timer;
void one_shot_handler(struct k_timer *timer)
{
printk("One-shot timer fired!\n");
// 单次定时器,不需要重新启动
}
void init_one_shot(void)
{
k_timer_init(&one_shot_timer, one_shot_handler, NULL);
// 10秒后触发,不重复
k_timer_start(&one_shot_timer, K_SECONDS(10), K_NO_WAIT);
}
struct k_timer periodic_timer;
int sample_count = 0;
void periodic_handler(struct k_timer *timer)
{
sample_count++;
// 执行周期性任务
read_sensor();
// 每100次后执行额外操作
if (sample_count % 100 == 0) {
printk("Processed %d samples\n", sample_count);
}
}
void init_periodic(void)
{
k_timer_init(&periodic_timer, periodic_handler, NULL);
// 立即开始,每50ms执行一次
k_timer_start(&periodic_timer, K_NO_WAIT, K_MSEC(50));
}
struct k_timer adaptive_timer;
int current_period = 100; // 初始周期100ms
void adaptive_handler(struct k_timer *timer)
{
// 根据处理时间调整周期
int64_t start = k_uptime_get();
do_heavy_work();
int64_t duration = k_uptime_get() - start;
// 动态调整:如果处理时间长,增加周期
if (duration > current_period / 2) {
current_period += 50;
k_timer_start(timer, K_MSEC(current_period), K_MSEC(current_period));
}
}
// 定义超时
k_timeout_t timeout = K_MSEC(100);
// 等待信号量,带超时
int ret = k_sem_take(&my_sem, timeout);
if (ret == -EAGAIN) {
// 超时发生
}
// 特殊超时值
K_NO_WAIT // 立即返回,不等待
K_FOREVER // 永久等待
K_MSEC(n) // 等待n毫秒
K_SECONDS(n) // 等待n秒
K_MINUTES(n) // 等待n分钟
K_HOURS(n) // 等待n小时
struct k_timer sync_timer;
struct k_sem sync_sem;
void timer_sync_handler(struct k_timer *timer)
{
// 定时器到期,释放信号量
k_sem_give(&sync_sem);
}
void worker_thread(void)
{
k_sem_init(&sync_sem, 0, 1);
k_timer_init(&sync_timer, timer_sync_handler, NULL);
while (1) {
// 等待定时器或超时
if (k_sem_take(&sync_sem, K_SECONDS(1)) == 0) {
// 定时器触发
do_periodic_work();
} else {
// 超时,执行备用操作
handle_timeout();
}
}
}
#define NUM_TIMERS 3
struct timer_context {
struct k_timer timer;
int id;
const char *name;
};
struct timer_context timers[NUM_TIMERS] = {
{ .id = 0, .name = "sensor" },
{ .id = 1, .name = "display" },
{ .id = 2, .name = "network" },
};
void multi_timer_handler(struct k_timer *timer)
{
struct timer_context *ctx = CONTAINER_OF(timer, struct timer_context, timer);
switch (ctx->id) {
case 0:
read_sensors();
break;
case 1:
update_display();
break;
case 2:
send_heartbeat();
break;
}
}
void init_multi_timers(void)
{
for (int i = 0; i < NUM_TIMERS; i++) {
k_timer_init(&timers[i].timer, multi_timer_handler, NULL);
}
// 不同周期启动
k_timer_start(&timers[0].timer, K_NO_WAIT, K_MSEC(100)); // sensor: 100ms
k_timer_start(&timers[1].timer, K_NO_WAIT, K_MSEC(500)); // display: 500ms
k_timer_start(&timers[2].timer, K_NO_WAIT, K_SECONDS(30)); // network: 30s
}
// 获取高精度时间戳(微秒)
int64_t now = k_uptime_get();
int64_t now_us = k_uptime_get_32(); // 32位微秒
// 计算时间差
int64_t start = k_uptime_get();
do_work();
int64_t elapsed = k_uptime_get() - start;
printk("Work took %lld ms\n", elapsed);
// 获取CPU周期计数(最高精度)
uint32_t cycles = k_cycle_get_32();
// 场景1:需要精确延迟,不在乎CPU占用
void precise_delay(void)
{
k_busy_wait(100); // 精确100微秒
}
// 场景2:可以容忍一些误差,需要低功耗
void power_efficient_delay(void)
{
k_sleep(K_USEC(100)); // 近似100微秒,允许调度
}
# 系统时钟配置
CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=32768
CONFIG_SYS_CLOCK_TICKS_PER_SEC=1000
# 定时器数量限制
CONFIG_TIMER_RANDOM_INITIAL_STATE=y
CONFIG_TIMERS=y
# 低功耗模式下的定时器
CONFIG_SYSTEM_CLOCK_SLOPPY_IDLE=y
| 方法 | 精度 | CPU占用 | 适用场景 |
|---|---|---|---|
| k_busy_wait | 微秒级 | 100% | 短延迟、时序关键 |
| k_sleep | 毫秒级 | 0% | 常规延迟、低功耗 |
| k_timer | 毫秒级 | 低 | 周期性任务 |
| k_cycle_get | 纳秒级 | - | 性能测量 |
void good_timer_handler(struct k_timer *timer)
{
// ✅ 快速执行,设置标志或提交工作项
k_work_submit(&timer_work);
}
void bad_timer_handler(struct k_timer *timer)
{
// ❌ 不要在回调中执行长时间操作
heavy_computation();
// ❌ 不要在回调中阻塞
k_sem_take(&sem, K_FOREVER);
}
// 安全地重启定时器
void safe_restart(struct k_timer *timer, k_timeout_t period)
{
k_timer_stop(timer);
k_timer_start(timer, period, period);
}
// 修改周期
void change_period(struct k_timer *timer, k_timeout_t new_period)
{
// 先停止再启动(不能使用动态修改)
k_timer_stop(timer);
k_timer_start(timer, new_period, new_period);
}
// 处理32位时间戳回绕
int64_t safe_time_diff(int64_t start, int64_t end)
{
return end - start; // Zephyr 使用64位时间戳,无需担心回绕
}
struct k_timer watchdog_timer;
volatile int watchdog_kicks = 0;
void watchdog_handler(struct k_timer *timer)
{
if (watchdog_kicks == 0) {
// 没有被踢,系统可能死锁
printk("Watchdog timeout! Rebooting...\n");
sys_reboot(SYS_REBOOT_COLD);
}
watchdog_kicks = 0;
}
void watchdog_init(void)
{
k_timer_init(&watchdog_timer, watchdog_handler, NULL);
k_timer_start(&watchdog_timer, K_SECONDS(5), K_SECONDS(5));
}
void watchdog_kick(void)
{
watchdog_kicks++;
}
*学习笔记创建时间: 2026-03-19*