鸿蒙南向开发教程 Day 4:OpenHarmony 软件定时器
目标掌握 OpenHarmony 轻量系统的软件定时器创建、启动、停止和删除前置条件已完成 Day 3 的线程管理教程一、工程结构app/ ├── BUILD.gn └── 02_timer/ # 模块目录 ├── BUILD.gn └── demo.c # 定时器测试代码1.1app/BUILD.gnimport(//build/lite/config/component/lite_component.gni) lite_component(app) { features [ 02_timer:timer_demo, # 引用 02_timer 模块 ] }1.202_timer/BUILD.gnstatic_library(timer_demo) { sources [ demo.c ] include_dirs [ //utils/native/lite/include, //kernel/liteos_m/components/cmsis/2.0, # CMSIS-RTOS2 头文件 ] }二、完整代码详解2.1 头文件#includestdio.h// 标准输入输出#includeunistd.h// UNIX 标准函数#includeohos_init.h// OpenHarmony 系统初始化#includecmsis_os2.h// CMSIS-RTOS2 接口2.2 宏定义#defineSTACK_SIZE(1024)// 线程栈大小#defineDELAY_TICKS_100(100)// 100 个 tick 延时#defineTEST_TIMES(3)// 定时器触发次数上限staticinttimes0;// 全局计数器记录定时器触发次数2.3 定时器回调函数voidcb_timeout_periodic(void){times;// 每次触发计数器 1}重要定时器回调函数不能阻塞不能调用osDelay()等阻塞操作。回调函数在中断上下文或定时器线程中执行应保持简短快速。2.4 周期性定时器测试voidtimer_periodic(void){// 1. 创建周期性定时器osTimerId_tperiodic_tidosTimerNew(cb_timeout_periodic,// 回调函数osTimerPeriodic,// 定时器类型周期性NULL,// 回调参数无NULL// 定时器属性默认);if(periodic_tidNULL){printf([Timer Test] osTimerNew(periodic timer) failed.\r\n);return;}else{printf([Timer Test] osTimerNew(periodic timer) success, tid: %p.\r\n,periodic_tid);}// 2. 启动定时器周期 100 tickosStatus_tstatusosTimerStart(periodic_tid,DELAY_TICKS_100);if(status!osOK){printf([Timer Test] osTimerStart(periodic timer) failed.\r\n);return;}else{printf([Timer Test] osTimerStart(periodic timer) success, wait a while and stop.\r\n);}// 3. 等待定时器触发 TEST_TIMES 次while(timesTEST_TIMES){printf([Timer Test] times:%d.\r\n,times);osDelay(DELAY_TICKS_100);// 主线程延时让出 CPU}// 4. 停止定时器statusosTimerStop(periodic_tid);printf([Timer Test] stop periodic timer, status :%d.\r\n,status);// 5. 删除定时器释放资源statusosTimerDelete(periodic_tid);printf([Timer Test] kill periodic timer, status :%d.\r\n,status);}2.5 系统入口staticvoidTimerTestTask(void){osThreadAttr_tattr{.nametimer_periodic,.attr_bits0U,.cb_memNULL,.cb_size0U,.stack_memNULL,.stack_sizeSTACK_SIZE,.priorityosPriorityNormal,};if(osThreadNew((osThreadFunc_t)timer_periodic,NULL,attr)NULL){printf([TimerTestTask] Failed to create timer_periodic!\n);}}APP_FEATURE_INIT(TimerTestTask);// 应用初始化入口三、CMSIS-RTOS2 定时器 API 详解3.1osTimerNew— 创建定时器osTimerId_tosTimerNew(osTimerFunc_tfunc,// 回调函数osTimerType_ttype,// 定时器类型void*argument,// 传给回调函数的参数constosTimerAttr_t*attr// 定时器属性NULL 为默认);定时器类型类型值说明osTimerOnce0一次性定时器触发一次后自动停止osTimerPeriodic1周期性定时器触发后自动重启循环执行3.2osTimerStart— 启动定时器osStatus_tosTimerStart(osTimerId_ttimer_id,uint32_tticks);参数说明timer_idosTimerNew返回的定时器 IDticks定时周期单位 tick由osKernelGetTickFreq()决定通常 1 tick 1ms3.3osTimerStop— 停止定时器osStatus_tosTimerStop(osTimerId_ttimer_id);停止后定时器不再触发但资源未释放可重新osTimerStart启动。3.4osTimerDelete— 删除定时器osStatus_tosTimerDelete(osTimerId_ttimer_id);释放定时器资源删除后timer_id失效。3.5 返回值状态码状态码值含义osOK0成功osError-1未指定的错误osErrorTimeout-2超时osErrorResource-3资源不足osErrorParameter-4参数错误osErrorNoMemory-5内存不足osErrorISR-6不允许在中断中调用四、定时器 vs 线程延时的区别特性软件定时器 (osTimer)线程延时 (osDelay)执行方式回调函数异步触发当前线程阻塞等待资源占用轻量不占用独立线程栈占用当前线程资源适用场景周期性任务、超时检测、心跳包简单延时、任务调度精度受系统 tick 频率影响同左阻塞风险回调函数不能阻塞线程本身就在阻塞五、底层实现LiteOS 原生定时器CMSIS-RTOS2 的osTimerXxx在 LiteOS-M 中的映射CMSIS-RTOS2LiteOS-M 原生osTimerNewLOS_SwtmrCreateosTimerStartLOS_SwtmrStartosTimerStopLOS_SwtmrStoposTimerDeleteLOS_SwtmrDeleteLiteOS-M 使用**软件定时器Swtmr**实现基于 tick 中断驱动不依赖硬件定时器。六、编译与验证6.1 编译烧录VSCode 点击Build→Upload串口波特率115200。6.2 预期输出[Timer Test] osTimerNew(periodic timer) success, tid: 0x20001xxx. [Timer Test] osTimerStart(periodic timer) success, wait a while and stop. [Timer Test] times:0. [Timer Test] times:1. [Timer Test] times:2. [Timer Test] times:3. [Timer Test] stop periodic timer, status :0. [Timer Test] kill periodic timer, status :0.七、总结要点内容定时器类型osTimerOnce一次性和osTimerPeriodic周期性生命周期创建 → 启动 → 运行→ 停止 → 删除回调限制不能阻塞不能调用osDelay底层映射LiteOS-MLOS_SwtmrXxx软件定时器与线程区别定时器是异步回调线程延时是同步阻塞八、下一步Day 5 预告互斥锁Mutex—— 多线程共享资源保护。需要继续 Day 5 的内容吗