4.5.4 定时器 API
2026/7/16大约 7 分钟内核组件内核时间管理定时器 API代码示例
4.5.4 定时器 API
📚 本节导读
学习时长: 约 30 分钟
难度级别: ⭐⭐☆☆☆
前置知识: 系统时钟概念、定时器类型、C 语言回调函数
🎯 学习目标
- 掌握所有定时器 API 的函数签名和使用方法
- 理解各定时器标志的含义和组合方式
- 能够编写单次触发和周期性定时器的代码
- 了解静态创建定时器的方式
一、定时器 API 概览
所有定时器 API 在 kernel/include/os_timer.h 中声明,在 OS_USING_KERNEL_TIMER 宏启用时可用。
| 类别 | API | 功能 |
|---|---|---|
| 创建/销毁 | os_timer_create | 动态创建定时器 |
| 创建/销毁 | OS_TIMER_DEFINE | 静态定义定时器控制块 |
| 创建/销毁 | os_timer_destroy | 销毁定时器 |
| 控制 | os_timer_start | 启动定时器 |
| 控制 | os_timer_stop | 停止定时器 |
| 查询 | os_timer_set_timeout_ticks | 设置超时 tick 数 |
| 查询 | os_timer_get_timeout_ticks | 获取超时 tick 数 |
| 查询 | os_timer_get_remain_ticks | 获取剩余 tick 数 |
| 查询 | os_timer_get_name | 获取定时器名称 |
| 查询 | os_timer_is_active | 检查定时器是否活跃 |
| 模式 | os_timer_set_oneshot | 设为单次模式 |
| 模式 | os_timer_set_periodic | 设为周期模式 |
| 模式 | os_timer_is_periodic | 检查是否为周期模式 |
| 检查 | os_timer_check_exist | 检查定时器是否存在 |
| 分类 | os_timer_is_soft | 检查是否为软件定时器(仅单链表) |
二、定时器标志
#define OS_TIMER_FLAG_ONE_SHOT 0x0U /* 单次触发定时器 */
#define OS_TIMER_FLAG_PERIODIC 0x1U /* 周期性定时器 */
/* 以下标志仅在 OS_USING_SINGLE_LIST_TIMER 下可用 */
#define OS_TIMER_FLAG_HARD_TIMER 0x0U /* 硬件定时器:回调在 tick ISR 中执行 */
#define OS_TIMER_FLAG_SOFT_TIMER 0x4U /* 软件定时器:回调在定时器任务中执行 */标志组合使用:
| 组合 | 含义 |
|---|---|
OS_TIMER_FLAG_ONE_SHOT | 单次触发软件定时器(哈希桶) |
OS_TIMER_FLAG_PERIODIC | 周期性软件定时器(哈希桶) |
OS_TIMER_FLAG_ONE_SHOT | OS_TIMER_FLAG_HARD_TIMER | 单次硬件定时器(单链表) |
OS_TIMER_FLAG_PERIODIC | OS_TIMER_FLAG_HARD_TIMER | 周期性硬件定时器(单链表) |
OS_TIMER_FLAG_ONE_SHOT | OS_TIMER_FLAG_SOFT_TIMER | 单次软件定时器(单链表) |
OS_TIMER_FLAG_PERIODIC | OS_TIMER_FLAG_SOFT_TIMER | 周期性软件定时器(单链表) |
三、创建与销毁
3.1 os_timer_create — 动态创建定时器
os_timer_id os_timer_create(os_timer_dummy_t *timer_cb,
const char *name,
void (*function)(void *parameter),
void *parameter,
os_tick_t timeout,
uint8_t flag);参数说明:
| 参数 | 类型 | 说明 |
|---|---|---|
timer_cb | os_timer_dummy_t * | 定时器控制块内存。若为 OS_NULL,则动态分配 |
name | const char * | 定时器名称(最多 OS_NAME_MAX 字符) |
function | void (*)(void *) | 超时回调函数 |
parameter | void * | 传递给回调函数的参数 |
timeout | os_tick_t | 超时时间(单位:tick),使用 os_tick_from_ms() 转换 |
flag | uint8_t | 定时器标志(见上文) |
返回值:
- 成功:定时器 ID(
os_timer_id,实际上是os_timer_dummy_t *类型) - 失败:
OS_NULL
3.2 OS_TIMER_DEFINE — 静态定义定时器
#define OS_TIMER_DEFINE(name) \
OS_ALIGN(OS_ARCH_STACK_ALIGN_SIZE) \
os_timer_dummy_t name使用方式:
/* 静态定义定时器控制块(全局或静态变量) */
OS_TIMER_DEFINE(my_timer_cb);
/* 使用静态控制块创建定时器 */
os_timer_id timer = os_timer_create(&my_timer_cb, "my_timer", ...);3.3 os_timer_destroy — 销毁定时器
os_err_t os_timer_destroy(os_timer_id timer_id);参数:
timer_id:要销毁的定时器 ID
返回值:
OS_SUCCESS:成功- 其他错误码:失败
注意:销毁定时器前应先停止定时器。如果定时器控制块是通过
timer_cb = OS_NULL动态分配的,销毁时会自动释放内存。
四、启动与停止
4.1 os_timer_start — 启动定时器
os_err_t os_timer_start(os_timer_id timer_id);启动指定的定时器。如果定时器已在运行,此操作会重新启动它(从初始超时时间开始计时)。
4.2 os_timer_stop — 停止定时器
os_err_t os_timer_stop(os_timer_id timer_id);停止指定的定时器。停止后定时器不再触发回调,但不会被销毁,可以再次启动。
五、查询函数
5.1 超时时间相关
/* 设置超时 tick 数 */
os_err_t os_timer_set_timeout_ticks(os_timer_id timer_id, os_tick_t timeout);
/* 获取超时 tick 数 */
os_tick_t os_timer_get_timeout_ticks(os_timer_id timer_id);
/* 获取剩余 tick 数 */
os_tick_t os_timer_get_remain_ticks(os_timer_id timer_id);5.2 状态查询
/* 获取定时器名称 */
const char *os_timer_get_name(os_timer_id timer_id);
/* 检查定时器是否在运行 */
os_bool_t os_timer_is_active(os_timer_id timer_id);
/* 检查定时器是否为周期模式 */
os_bool_t os_timer_is_periodic(os_timer_id timer_id);
/* 检查定时器是否存在 */
os_bool_t os_timer_check_exist(os_timer_id timer_id);5.3 模式切换
/* 设置为单次模式 */
os_err_t os_timer_set_oneshot(os_timer_id timer_id);
/* 设置为周期模式 */
os_err_t os_timer_set_periodic(os_timer_id timer_id);5.4 定时器分类查询(仅单链表定时器)
#ifdef OS_USING_SINGLE_LIST_TIMER
/* 检查是否为软件定时器 */
os_bool_t os_timer_is_soft(os_timer_id timer_id);
#endif六、代码示例
6.1 单次触发定时器
#include <oneos_config.h>
#include <os_timer.h>
#include <os_task.h>
/* 定时器回调函数 */
static void oneshot_timer_callback(void *parameter)
{
os_kprintf("One-shot timer fired! Param: %s\r\n", (char *)parameter);
}
void oneshot_timer_demo(void)
{
os_timer_id timer;
/* 创建单次触发定时器,超时 2000ms */
timer = os_timer_create(OS_NULL,
"oneshot_tmr",
oneshot_timer_callback,
"hello",
os_tick_from_ms(2000),
OS_TIMER_FLAG_ONE_SHOT);
if (timer == OS_NULL)
{
os_kprintf("Failed to create timer\r\n");
return;
}
/* 启动定时器 */
os_timer_start(timer);
os_kprintf("One-shot timer started, will fire in 2000ms\r\n");
/* 定时器到期后会自动停止,可在此处等待或做其他工作 */
os_task_msleep(3000);
/* 销毁定时器 */
os_timer_destroy(timer);
os_kprintf("Timer destroyed\r\n");
}6.2 周期性定时器
static uint32_t periodic_count = 0;
/* 周期性定时器回调 */
static void periodic_timer_callback(void *parameter)
{
periodic_count++;
os_kprintf("Periodic timer fired! Count: %d\r\n", periodic_count);
if (periodic_count >= 10)
{
/* 第 10 次后停止定时器 */
os_timer_id timer = (os_timer_id)parameter;
os_timer_stop(timer);
os_kprintf("Periodic timer stopped after 10 times\r\n");
}
}
void periodic_timer_demo(void)
{
os_timer_id timer;
/* 创建周期性定时器,每 500ms 触发一次 */
timer = os_timer_create(OS_NULL,
"periodic_tmr",
periodic_timer_callback,
OS_NULL, /* 后续通过 start/stop 引用 */
os_tick_from_ms(500),
OS_TIMER_FLAG_PERIODIC);
if (timer == OS_NULL)
{
os_kprintf("Failed to create periodic timer\r\n");
return;
}
/* 启动定时器 */
os_timer_start(timer);
os_kprintf("Periodic timer started, fires every 500ms\r\n");
/* 等待定时器工作 */
os_task_msleep(6000);
/* 销毁定时器 */
os_timer_destroy(timer);
os_kprintf("Periodic timer destroyed\r\n");
}6.3 停止和重启定时器
static void restartable_timer_callback(void *parameter)
{
os_kprintf("Timer fired!\r\n");
}
void restart_demo(void)
{
os_timer_id timer;
timer = os_timer_create(OS_NULL, "restart_tmr",
restartable_timer_callback, OS_NULL,
os_tick_from_ms(1000),
OS_TIMER_FLAG_ONE_SHOT);
if (timer == OS_NULL)
return;
/* 启动定时器 */
os_timer_start(timer);
os_kprintf("Timer started, will fire in 1000ms\r\n");
/* 在 500ms 时停止定时器 */
os_task_msleep(500);
if (os_timer_is_active(timer))
{
os_timer_stop(timer);
os_kprintf("Timer stopped before firing\r\n");
os_kprintf("Remaining ticks: %d\r\n", os_timer_get_remain_ticks(timer));
}
/* 重新启动定时器 */
os_timer_start(timer);
os_kprintf("Timer restarted, will fire in 1000ms\r\n");
os_task_msleep(2000);
os_timer_destroy(timer);
}6.4 查询定时器状态
void timer_query_demo(void)
{
os_timer_id timer;
timer = os_timer_create(OS_NULL, "query_tmr",
OS_NULL, OS_NULL,
os_tick_from_ms(5000),
OS_TIMER_FLAG_PERIODIC);
if (timer == OS_NULL)
return;
/* 查询定时器信息 */
os_kprintf("Timer name: %s\r\n", os_timer_get_name(timer));
os_kprintf("Is periodic: %s\r\n", os_timer_is_periodic(timer) ? "yes" : "no");
os_kprintf("Timeout ticks: %d\r\n", os_timer_get_timeout_ticks(timer));
os_timer_start(timer);
os_kprintf("Is active: %s\r\n", os_timer_is_active(timer) ? "yes" : "no");
os_task_msleep(1000);
os_kprintf("Remaining ticks: %d\r\n", os_timer_get_remain_ticks(timer));
os_timer_stop(timer);
os_kprintf("Is active after stop: %s\r\n", os_timer_is_active(timer) ? "yes" : "no");
os_timer_destroy(timer);
os_kprintf("Check exist after destroy: %s\r\n",
os_timer_check_exist(timer) ? "yes" : "no");
}6.5 静态创建定时器
/* 静态定义定时器控制块 */
OS_TIMER_DEFINE(static_timer_cb);
static void static_timer_callback(void *parameter)
{
os_kprintf("Static timer fired!\r\n");
}
void static_timer_demo(void)
{
os_timer_id timer;
/* 使用静态控制块创建定时器 */
timer = os_timer_create(&static_timer_cb,
"static_tmr",
static_timer_callback,
OS_NULL,
os_tick_from_ms(1000),
OS_TIMER_FLAG_ONE_SHOT);
if (timer == OS_NULL)
return;
os_timer_start(timer);
os_task_msleep(2000);
/* 销毁定时器(静态控制块不会被释放) */
os_timer_destroy(timer);
}七、API 使用注意事项
- 返回值检查:始终检查
os_timer_create的返回值,创建失败时返回OS_NULL - 回调函数限制:硬件定时器回调在 ISR 中执行,不能调用可能阻塞的 API
- 销毁前停止:建议在销毁定时器前先调用
os_timer_stop确保定时器已停止 - tick 转换:使用
os_tick_from_ms()将毫秒转换为 tick,避免硬编码 tick 值 - 名称唯一性:定时器名称建议在系统中保持唯一,便于调试
- 静态控制块生命周期:使用
OS_TIMER_DEFINE静态定义的控制块,其生命周期由用户管理,销毁定时器不会释放静态控制块的内存
📝 本节小结
本节详细介绍了 OneOS 定时器 API 的完整使用方法。定时器 API 覆盖了创建、销毁、启动、停止、查询和模式切换等全部功能。定时器标志通过位掩码组合实现单次/周期和硬件/软件模式的灵活配置。通过代码示例展示了单次触发、周期性触发、停止重启、状态查询和静态创建等常见使用场景。