1 概述

1.1 基本概念

软件定时器,是基于系统Tick时钟中断且由软件来模拟的定时器,当经过设定的Tick时钟计数值后会触发用户定义的回调函数。定时精度与系统Tick时钟的周期有关。

硬件定时器受硬件的限制,数量上不足以满足用户的实际需求,因此为了满足用户需求,提供更多的定时器, Huawei LiteOS操作系统提供软件定时器功能。

软件定时器扩展了定时器的数量,允许创建更多的定时业务。

软件定时器功能上支持:

  • 静态裁剪:能通过宏关闭软件定时器功能。
  • 软件定时器创建。
  • 软件定时器启动。
  • 软件定时器停止。
  • 软件定时器删除。
  • 软件定时器剩余Tick数获取

1.2 运作机制

软件定时器是系统资源,在模块初始化的时候已经分配了一块连续的内存,系统支持的最大定时器个数由los_config.h中的LOSCFG_BASE_CORE_SWTMR_LIMIT宏配置。

软件定时器使用了系统的一个队列和一个任务资源,软件定时器的触发遵循队列规

则,先进先出。定时时间短的定时器总是比定时时间长的靠近队列头,满足优先被触发的准则。

软件定时器以Tick为基本计时单位,当用户创建并启动一个软件定时器时, HuaweiLiteOS会根据当前系统Tick时间及用户设置的定时间隔确定该定时器的到期Tick时间,并将该定时器控制结构挂入计时全局链表。

当Tick中断到来时,在Tick中断处理函数中扫描软件定时器的计时全局链表,看是否有定时器超时,若有则将超时的定时器记录下来。Tick中断处理函数结束后,软件定时器任务(优先级为最高)被唤醒,在该任务中调用之前记录下来的定时器的超时回调函数。

定时器状态

  • OS_SWTMR_STATUS_UNUSED(未使用)

系统在定时器模块初始化的时候将系统中所有定时器资源初始化成该状态。

  • OS_SWTMR_STATUS_CREATED(创建未启动/停止)

在未使用状态下调用LOS_SwtmrCreate接口或者启动后调用LOS_SwtmrStop接口后,定

时器将变成该状态。

  • OS_SWTMR_STATUS_TICKING(计数)

在定时器创建后调用LOS_SwtmrStart接口,定时器将变成该状态,表示定时器运行时的状态。

定时器模式

Huawei LiteOS的软件定时器提供二类定时器机制:

  • 第一类是单次触发定时器,这类定时器在启动后只会触发一次定时器事件,然后定时器自动删除。
  • 第二类是周期触发定时器,这类定时器会周期性的触发定时器事件,直到用户手动地停止定时器,否则将永远持续执行下去

2. 开发指导

2.1 使用场景

  • 创建一个单次触发的定时器,超时后执行用户自定义的回调函数。
  • 创建一个周期性触发的定时器,超时后执行用户自定义的回调函数。

2.2 功能

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

功能分类 接口名 描述
创建、删除定时器 LOS_SwtmrCreate 创建定时器
- LOS_SwtmrDelete 删除定时器
启动、停止定时器 LOS_SwtmrStart 启动定时器
- LOS_SwtmrStop 停止定时器
获得软件定时器剩余Tick数 LOS_SwtmrTimeGet 获得软件定时器剩余Tick数

3. 开发流程

软件定时器的典型开发流程:

  1. 配置软件定时器。
  • 确认配置项LOSCFG_BASE_CORE_SWTMR和LOSCFG_BASE_IPC_QUEUE

    为YES打开状态;
  • 配置LOSCFG_BASE_CORE_SWTMR_LIMIT最大支持的软件定时器数;
  • 配置OS_SWTMR_HANDLE_QUEUE_SIZE软件定时器队列最大长度;
  1. 创建定时器LOS_SwtmrCreate。
  • 创建一个指定计时时长、指定超时处理函数、指定触发模式的软件定时器;
  • 返回函数运行结果,成功或失败;
  1. 启动定时器LOS_SwtmrStart。
  2. 获得软件定时器剩余Tick数LOS_SwtmrTimeGet。
  3. 停止定时器LOS_SwtmrStop。
  4. 删除定时器LOS_SwtmrDelete。

4. 软件定时器错误码

对软件定时器存在失败可能性的操作,包括创建、删除、暂停、重启定时器等等,均需要返回对应的错误码,以便快速定位错误原因。

序 号 定义 实际数值 描述 参考解决方案
1 LOS_ERRNO_SWTMR_PTR_NULL 0x02000300 软件定时器回调函数为空 定义软件定时器回调函数
2 LOS_ERRNO_SWTMR_INTERVAL_NOT_SUITD 0x02000301 软件定时器间隔时间为0 重新定义间隔时间
3 LOS_ERRNO_SWTMR_MODE_INVALI D 0x02000302 不正确的软件定时器模式 确认软件定时器模式,范围为[0,2]
4 LOS_ERRNO_SWTMR_RET_PTR_NULL 0x02000303 软件定时器ID指针入参为NULL 定义ID变量,传入指针
5 LOS_ERRNO_SWTMR_MAXSIZE 0x02000304 软件定时器个数超过最大值 重新定义软件定时器最大个数,或者等待一个软件定时器释放资源
6 LOS_ERRNO_SWTMR_ID_INVALID 0x02000305 不正确的软件定时器ID入参 确保入参合法
7 LOS_ERRNO_SWTMR_NOT_CREATED 0x02000306 软件定时器未创建 创建软件定时器
8 LOS_ERRNO_SWTMR_NO_MEMORY 0x02000307 软件定时器链表创建内存不足 申请一块足够大的内存供软件定时器使用
9 LOS_ERRNO_SWTMR_MAXSIZE_INVALID 0x02000308 不正确的软件定时器个数最大值 重新定义该值
10 LOS_ERRNO_SWTMR_HWI_ACTIVE 0x02000309 在中断中使用定时器 修改源代码确保不在中断中使用
11 LOS_ERRNO_SWTMR_HANDLER_POOL_NO_MEM 0x0200030a membox内存不足 扩大内存
12 LOS_ERRNO_SWTMR_QUEUE_CREATE_FAILED 0x0200030b 软件定时器队列创建失败 检查用以创建队列的内存是否足够
13 LOS_ERRNO_SWTMR_TASK_CREATE_FAILED 0x0200030c 软件定时器任务创建失败 检查用以创建软件定时器任务的内存是否足够并重新创建
14 LOS_ERRNO_SWTMR_NOT_STARTED 0x0200030d 未启动软件定时器 启动软件定时器
15 LOS_ERRNO_SWTMR_STATUS_INVALID 0x0200030e 不正确的软件定时器状态 检查确认软件定时器状态
16 LOS_ERRNO_SWTMR_SORTLIST_NULL null 暂无 该错误码暂不使用
17 LOS_ERRNO_SWTMR_TICK_PTR_NULL 0x02000310 用以获取软件定时器超时tick数的入参指针为NULL 创建一个有效的变量

错误码定义:错误码是一个32位的存储单元, 31~24位表示错误等级, 23~16位表示错误码标志, 15~8位代表错误码所属模块, 7~0位表示错误码序号,如下

#define LOS_ERRNO_OS_NORMAL(MID,ERRNO) \
(LOS_ERRTYPE_NORMAL | LOS_ERRNO_OS_ID | ((UINT32)(MID) << 8) | (ERRNO))
LOS_ERRTYPE_NORMAL :Define the error level as critical
LOS_ERRNO_OS_ID :OS error code flag.
MID:OS_MOUDLE_ID
ERRNO:error ID number

例如:

#define LOS_ERRNO_SWTMR_PTR_NULL \
LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x00)

5. 编程实例

5.1 实例描述

在下面的例子中,演示如下功能:

  1. 软件定时器创建、启动、删除、暂停、重启操作。
  2. 单次软件定时器,周期软件定时器使用方法。

5.2 编程示例

前提条件:

  • 在los_config.h中,将LOSCFG_BASE_CORE_SWTMR配置项打开。
  • 配置好LOSCFG_BASE_CORE_SWTMR_LIMIT最大支持的软件定时器数。
  • 配置好OS_SWTMR_HANDLE_QUEUE_SIZE软件定时器队列最大长度。

代码实现如下:

void Timer1_Callback(uint32_t arg); // callback fuction
void Timer2_Callback(uint32_t arg);
UINT32 g_timercount1 = 0;
UINT32 g_timercount2 = 0;
void Timer1_Callback(uint32_t arg)//回调函数1
{
unsigned long tick_last1;
g_timercount1++;
tick_last1=(UINT32)LOS_TickCountGet();//获取当前Tick数
dprintf("g_timercount1=%d\n",g_timercount1);
dprintf("tick_last1=%d\n",tick_last1);
}
void Timer2_Callback(uint32_t arg)//回调函数2
{
unsigned long tick_last2;
tick_last2=(UINT32)LOS_TickCountGet();
g_timercount2 ++;
dprintf("g_timercount2=%d\n",g_timercount2);
dprintf("tick_last2=%d\n",tick_last2);
}
void Timer_example (void) {
UINT16 id1;
UINT16 id2;// timer id
UINT32 uwTick;
/*创建单次软件定时器,Tick数为1000,启动到1000Tick数时执行回调函数1 */
LOS_SwtmrCreate (1000, LOS_SWTMR_MODE_ONCE,Timer1_Callback,&id1,1);
/*创建周期性软件定时器,每100Tick数执行回调函数2 */
LOS_SwtmrCreate(100,LOS_SWTMR_MODE_PERIOD,Timer2_Callback,&id2,1);
dprintf("create Timer1 success\n");
LOS_SwtmrStart (id1); //启动单次软件定时器
dprintf("start Timer1 sucess\n");
LOS_TaskDelay(200);//延时200Tick数
LOS_SwtmrTimeGet(id1,&uwTick);//获得单次软件定时器剩余Tick数
dprintf("uwTick =%d\n",uwTick);
LOS_SwtmrStop(id1);//停止软件定时器
dprintf("stop Timer1 sucess\n");
LOS_SwtmrStart(id1);
LOS_TaskDelay(1000);
LOS_SwtmrDelete(id1);//删除软件定时器
dprintf("delete Timer1 sucess\n");
LOS_SwtmrStart(id2);//启动周期性软件定时器
dprintf("start Timer2\n");
LOS_TaskDelay(1000);
LOS_SwtmrStop(id2);
LOS_SwtmrDelete(id2);
}

5.3 结果验证

得到的结果为:

liteos软件定时器(十)的更多相关文章

  1. rt-thread中软件定时器组件超时界限的一点理解

    @2019-01-15 [小记] 对 rt-thread 中的软件定时器组件中超时界限的一点理解 rt_thread_timer_entry(void *parameter)函数中if ((next_ ...

  2. 【iCore4 双核心板_uC/OS-II】例程四:软件定时器

    一.实验说明: 一些应用程序执行它们的任务时需要延迟一段特定的时间,因此uC/OS-II为我们提供了一些相应的 延时函数,本例程我们使用软件定时器定时500ms点亮相应的LED实现三色LED循环闪烁. ...

  3. 6.1-uC/OS-III软件定时器

    1.软件定时器是 uC/OS 操作系统的一个内核对象,软件定时器是基于时钟节拍和系统管理创建的软件性定时器,理论上可以创建无限多个,但精准度肯定比硬件定时稍逊一筹. 2.软件定时器启动之后是由软件定时 ...

  4. 6.0-uC/OS-III软件定时器管理

    1.软件定时器管理 uC/OS-III提供了软件定时器服务(相关代码在OS_TMR.C中).当设置OS_CFG.H中的OS_CFG_TMR_EN为1时软件定时器服务被使能. 2.uC/OS-III 定 ...

  5. FreeRTOS_软件定时器

    FreeRTOS 软件定时器 实验 创建2个任务,start_task.timercontrol_task. start_stask:创建timercontrol_task任务:创建周期定时器Auto ...

  6. 【STM32H7教程】第22章 STM32H7的SysTick实现多组软件定时器

    完整教程下载地址:http://forum.armfly.com/forum.php?mod=viewthread&tid=86980 第22章       STM32H7的SysTick实现 ...

  7. uC/OS-III 软件定时器(三)

    软件定时器是uC/OS 操作系统的一个内核对象,软件定时器是基于时钟节拍和系统管理创建的软件性定时器,理论上可以创建无限多个,操作简单,但精准度肯定比硬件定时稍逊一筹. 原理和实现过程 要用到的函数: ...

  8. 【TencentOS tiny】深度源码分析(8)——软件定时器

    软件定时器的基本概念 TencentOS tiny 的软件定时器是由操作系统提供的一类系统接口,它构建在硬件定时器基础之上,使系统能够提供不受硬件定时器资源限制的定时器服务,本质上软件定时器的使用相当 ...

  9. 分享一个简单易用的软件定时器模块(MultiTimer)——基于keil+stm32f103zet+hal库(裸机实现)

    公众号上看到一个比较好的一个github项目:https://github.com/0x1abin/MultiTimer 今天看了看,简单的,就移植了- 且看文档的说明, ============== ...

随机推荐

  1. 如何在VIM中保存编辑的只读文件

    我们经常碰到这样的情景:在VIM中编辑了一个系统配置文件,当需要保存时才发现当前的用户对该文件没有写入的权限, 这时候怎么办呢? 当需要保存时,输入以下的命令: :w !sudo tee %

  2. ARM 寻址方式

    寻址方式有 9种 1.寄存器 2.立即数 3.寄存器位移 4.寄存器间接 5.基址 6.多寄存器 7.堆栈 8.块拷贝 9.相对 1. MOV R1,R2 R1 = R2 2. MOV R0,#0x1 ...

  3. jenkins添加TPS与服务器监控变化曲线图

    第一步,首先在测试的脚本中添加你所需要查看的曲线图的监控路径 譬如我想查看TPS变化图 添加hps监控图 添加服务器监控图 把所有jtl文件保存到/opt/workspace/B_Stress_Tes ...

  4. [C11] 推荐系统(Recommender Systems)

    推荐系统(Recommender Systems) 问题阐述(Problem Formulation) 将 推荐系统 纳入这门课程来讲有以下两个原因: 第一.仅仅因为它是机器学习中的一个重要的应用.在 ...

  5. Mybatis介绍(一)

    MyBatis本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis .201 ...

  6. 基于C++的STL的vector实现静态链表,要求包含插入,删除,和查找功能

    //main.cpp部分 #include"List.cpp" int main() { StaticList<int> SL; SL.Insert(,); SL.In ...

  7. SQL Server 迁移数据库 (四)备份和还原

    1. 备份 2. 复制 3. 粘贴 4. 还原 截图软件出问题了,估计重启下就好,但是备份还原比较简单,懂的都懂,马上下班了就不贴图了.

  8. 剑指offer:矩阵中的路径(递归回溯法DFS类似迷宫)

    1. 题目描述 /* 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径. 路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子. 如果一条 ...

  9. 在Ubuntu18.04.2LTS上安装搜狗输入法

    在Ubuntu18.04.2LTS上安装搜狗输入法 一.前言 最近项目使用到了Linux系统,因此就安装了Ubuntu18.04.2这个最新的LTS的OS.整体的使用效果是不敢恭维的,特别是使用虚拟机 ...

  10. torch_12_BigGAN全文解读

    1.摘要: 尽管近来生成图片模型取得了进步,成功生成了高分辨率的图片,但是在复杂的数据集中,样本的多样性仍然是难以捉摸的目标.本文尝试在大规模上训练生成对抗网络,并研究这种规模下的不稳定性.我们发现将 ...