跳到主要内容

Timer(定时器)

LibXR::Timer 实现了跨平台的周期性任务调度,支持高精度多任务定时执行。它提供统一的定时任务创建、启动、停止、删除及周期调整等接口,底层利用 Thread::SleepUntil 实现精确调度,适配多线程和裸机场景。可用于定时回调、周期控制、异步定时任务等各种需求。

设计要点

目标说明
跨平台统一定时调度机制与 OS 解耦,兼容多线程与裸机环境。
多任务支持支持并发多个周期性任务调度,任务独立注册与管理。
高精度任务调度精度达 1ms,基于 Thread::SleepUntil 精确控制。
灵活接口支持任务周期动态调整、启动/停止/删除/添加等全生命周期操作。
线程安全可裁剪内部自动管理任务线程,裸机模式下自动刷新,无需用户主动调用。

公开接口速览

方法作用
template <typename Arg> static TimerHandle CreateTask(void (*fun)(Arg), Arg arg, uint32_t cycle)创建周期性任务(周期 ms),返回任务句柄。
static void Start(TimerHandle handle)启动指定任务。
static void Stop(TimerHandle handle)停止指定任务。
static void SetCycle(TimerHandle handle, uint32_t cycle)修改任务周期。
static void Remove(TimerHandle handle)删除指定任务。
static void Add(TimerHandle handle)将任务添加到调度列表(首次添加会自动启动管理线程)。
static void Refresh()主动刷新所有任务(轮询场景下调用,通常由定时线程自动执行)。
static void RefreshTimerInIdle()在裸机下由 Thread 延时/Mutex/信号量自动调用,用户无需手动调用。

提示:所有定时任务周期单位均为毫秒,所有任务由 Timer 管理线程或主循环自动调度,无需手动管理任务遍历与时间计算。裸机场景下,Thread 延时、Mutex 和信号量等待时会自动刷新定时器,无需用户干预。

典型用法

#include <timer.hpp>

void PrintHello(int* value) {
printf("Hello, value = %d\n", *value);
}

int main() {
int arg = 123;
// 创建定时任务,每 1000ms 调用一次 PrintHello
auto handle = LibXR::Timer::CreateTask(PrintHello, &arg, 1000);

LibXR::Timer::Add(handle); // 加入调度并自动启动定时线程
LibXR::Timer::Start(handle); // 启动任务

while (1) {
// 主循环,裸机下无需主动刷新定时器
// 多线程下可执行其它任务
LibXR::Thread::Sleep(UINT32_MAX);
}
}

平台适配概览

场景关键实现调度机制说明
多线程/RTOSThread::SleepUntil + 管理线程自动启动管理线程,1ms 精度循环检查并调度任务。
裸机/单线程RefreshTimerInIdle 自动调用Thread 延时/Mutex/信号量等待时自动刷新,无需手动调用。

移植到新平台时,仅需保证 Thread 及 Timebase 支持,无需修改 Timer 主体逻辑。

参考实现细节

  • 每个定时任务都封装为 ControlBlock,通过 List 链表统一管理;
  • CreateTask 支持带参数回调,内部类型安全,无需手动绑定上下文;
  • Add 第一次调用会自动分配任务列表与管理线程(多线程环境);
  • Refresh 遍历所有已启用任务,按周期自动计数与触发,无需用户管理遍历与计时;
  • 裸机下,Thread 延时/Mutex/信号量等待自动刷新定时器,确保任务及时调度;
  • 支持任务周期动态调整、运行中启停与删除,接口灵活安全;
  • 断言机制保证非法操作(如多次添加、错误删除)即时报错。