LiteOS 软件定时器

参考:

  1. 【野火】物联网操作系统 LiteOS 开发实战指南
  2. Huawei LiteOS | 中文网

7. 软件定时器

7.1 基本概念

7.1.1 概念
  • 软件定时器,是基于系统Tick时钟中断,且由软件来模拟的定时器,当经过设定的Tick时钟计数值后触发用户定义的回调函数(类似硬件的中断服务函数)
  • 定时精度与系统Tick时钟的周期有关
  • 定时器的定时周期,是两次触发回调函数的时间间隔
  • 软件定时器回调函数的上下文任务,且回调函数也要快进快出,且回调函数中不能有任何阻塞任务运行的情况
7.1.2 功能支持
  • 裁剪:能通过宏关闭软件定时器功能
  • 软件定时器创建
  • 软件定时器启动
  • 软件定时器停止
  • 软件定时器删除
  • 软件定时器剩余Tick数获取
7.1.3 支持模式
  • 单次模式

    • 当用户创建了定时器并启动定时器后,定时时间到了,只执行一次回调函数就将该定时器删除,不再重新执行
  • 周期模式

    • 这个定时器会按照设定的定时时间循环执行回调函数,直到用户将定时器删除

    在这里插入图片描述

7.1.4 定时器管理
  • LiteOS通过一个软件定时器任务osSwTmrTask来管理软件定时器
  • 软件定时器任务的优先级是0,也就是最高优先级,是在LiteOS核心初始化的时候自动创建
  • osSwTmrTask任务会在其执行期间检查用户启动的时间周期溢出的定时器,并调用其回调函数

7.2 应用场景

  • 弥补硬件定时器受限的场景
  • 适用于对时间精度要求不高的任务,一些辅助型的任务
  • 不足
    • 精度较硬件定时器中断较差,因软件定时器的定时过程中极有可能被其他中断所打断

7.3 运作机制

7.3.1 精度说明
  • 操作系统中,软件定时器以系统节拍周期为计时单位
  • 系统节拍配置为LOSCFG_BASE_CORE_TICK_PER_SECOND,在 target_config.h中定义
  • 软件定时器所定时数值必须是这个节拍周期的整数倍
7.3.2 机制
  • 软件定时器使用了系统的一个队列和一个任务资源,软件定时器的出发遵循队列规则,先进先出,定时器短的总是比定时时间长的靠近队列头
  • 软件定时器以Tick为基本定时单位,当用户创建并启动一个软件定时器时,LiteOS会根据当前系统Tick时间及用户设置的定时时间间隔确定该定时器的到期Tick时间,并将该定时器控制结构挂入计时全局链表
  • 当Tick中断到来时,在Tick中断处理函数中扫描定时器的计时全局链表,看是否有定时器超时若有,则将超时的定时器记录下来
  • 如果软件定时器的定时时间到来,那么在Tick中断处理函数结束后,软件定时器任务osSwTmrTask(优先级最高)被唤醒,在该任务中调用之前记录下来的定时器的超时函数
7.3.3 定时器状态
  • OS_SWTMR_STATUS_UNUSED(未使用)
    • 系统在定时器模块初始化的时候将系统中所有定时器资源初始化成该状态
  • OS_SWTMR_STATUS_CREATED(创建未启动/停止)
    • 在未使用状态下,调用LOS_SwtmrCreate()函数,或者是定时器启动后调用LOS_SwtmrStop()函数后,定时器变成该状态
  • OS_SWTMR_STATUS_TICKING(计数)
    • 在定时器创建后调用LOS_SwtmrStart()函数,定时器将变成该状态,表示定时器运行时的状态

7.4 使用注意点

  • 软件定时器的回调函数中不要做过多操作,不要使用可能引起任务挂起或者阻塞的接口,如 LOS_TaskDelay()
  • 软件定时器使用了系统的一个队列和一个任务资源,软件定时器任务的优先级设定为 0,且不允许修改
  • 系统可配置的软件定时器资源个数是指:整个系统可使用的软件定时器资源总个数,而并非是用户可使用的软件定时器资源个数
  • 创建单次软件定时器,该定时器超时执行完回调函数后,系统会自动删除该软件定时器,并回收资源

7.5 开发说明

注意:使用时需要包含头文件:los_swtmr.h

7.5.1 控制块
typedef struct tagSwTmrCtrl
{
    struct tagSwTmrCtrl *pstNext;       /* 指向下一个软件定时器的指针 */
    UINT8               ucState;        /* 软件定时器状态 */
    UINT8               ucMode;         /* 软件定时器模式 */
#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES)/* 如果定义了LOSCFG_BASE_CORE_SWTMR_ALIGN */
    UINT8               ucRouses;       /* 使用软件定时器唤醒 */
    UINT8               ucSensitive;    /* 使用软件定时器对齐 */
#endif
    UINT16              usTimerID;      /* 软件定时器ID */
    UINT32              uwCount;        /* 软件定时器计数值,用来记录软件定时器到来的剩余时间 */
    UINT32              uwInterval;     /* 软件定时器的超时时间间隔,或者说定时周期 */
    UINT32              uwArg;          /* 调用处理软件定时器超时的回调函数时传入的参数 */
    SWTMR_PROC_FUNC     pfnHandler;     /* 处理软件定时器超时的回调函数 */
} SWTMR_CTRL_S;
7.5.2 功能函数

Huawei LiteOS系统中的软件定时器模块为用户提供下面几种功能,下面具体的API详见软件定时器对外接口手册。

功能分类接口名描述
创建、删除定时器LOS_SwtmrCreate创建定时器
LOS_SwtmrDelete删除定时器
启动、停止定时器LOS_SwtmrStart启动定时器
LOS_SwtmrStop停止定时器
获得软件定时器剩余Tick数LOS_SwtmrTimeGet获得软件定时器剩余Tick数
7.5.3 开发流程
  1. 配置软件定时器(在target_config.h 中)
    • 确认配置项LOSCFG_BASE_CORE_SWTMRLOSCFG_BASE_IPC_QUEUEYES打开状态
    • 配置LOSCFG_BASE_CORE_SWTMR_LIMIT最大支持的软件定时器数
    • 配置 OS_SWTMR_HANDLE_QUEUE_SIZE 软件定时器队列最大长度
  2. 创建定时器,调用 LOS_SwtmrCreate()
    • 创建一个指定定时时长,指定超时处理函数,指定触发模式的软件定时器
    • 返回函数运行结果,成功或失败
  3. 启动定时器,调用LOS_SwtmrStart()
  4. 获得定时器剩余Tick数,调用LOS_SwtmrTimeGet()
  5. 停止定时器,调用 LOS_SwtmrStop()
  6. 删除定时器,调用LOS_SwtmrDelete()
7.5.4 功能函数简介
  • 定时器创建函数LOS_SwtmrCreate()

    UINT32 LOS_SwtmrCreate( UINT32 uwInterval,			/*软件定时器定时时间*/
    						UINT8 ucMode,				/*软件定时器工作模式*/
    						SWTMR_PROC_FUNC pfnHandler, /*软件定时器回调函数*/
    						UINT16 *pusSwTmrID,			/*软件定时器id*/
    						UINT32 uwArg,				/*软件定时器传入参数*/
    #if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES)			/**/
                        	UINT8 ucRouses,				/**/
                        	UINT8 ucSensitive			/**/
    #endif
                      	  )
    

    软件定时器工作模式:

    enum enSwTmrType {
    					LOS_SWTMR_MODE_ONCE, 			/**< 单次模式 */
    					LOS_SWTMR_MODE_PERIOD, 			/**< 周期模式 */
    					LOS_SWTMR_MODE_NO_SELFDELETE,	/**< 单次模式,但不能删除自己 */
    					LOS_SWTMR_MODE_OPP, 			/**<在一次性定时器完成定时后,启用定期软件定时器。 暂时不支持此模式。 */
    };
    
  • 定时器删除函数LOS_SwtmrDelete()

    • 注意,要删除的软件定时器必须是已经被创建的
    UINT32 LOS_SwtmrDelete(UINT16 usSwTmrID)			/* 定时器ID */
    
  • 定时器启动函数 LOS_SwtmrStart()

    • 软件定时器需要手动启动
    UINT32 LOS_SwtmrStart(UINT16 usSwTmrID)				/* 定时器ID */
    
    • 在启动的过程中,会将要插入的软件定时器按照其被唤醒的时间进行排序, 距离唤醒时间越短的软件定时器排在前边,距离唤醒时间越长的排在后面。

    • 比如软件定时器队列中一开始只有一个周期为200Tick的软件定时器A,那么A定时器在200Tick后就会调用一次回调函数,但是,现在插入一个周期为100Tick的软件定时器B,那么100个Tick之后,软件定时器B的回调函数就要调用一次,而原来在200个Tick后调用回调函数的软件定时器A就会变成在软件定时器B调用之后的100个Tick进行唤醒,然后调用对应的回调函数,如下图所示:
      在这里插入图片描述
      在这里插入图片描述

  • 定时器停止函数LOS_SwtmrStop()

    • 删除某个软件定时器之前应先把软件定时器停止
    UINT32 LOS_SwtmrStop(UINT16 usSwTmrID)			/* 定时器ID */
    
  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值