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. 2. Java程序的运行机制

    一.完成一个Java程序的流程:编辑Java源代码→编译Java程序→运行Java程序 1. 在记事本中编写Java程序,然后保存为.java类型文件(Java源文件) 2. 使用javac命令将源文 ...

  2. Windows下的命令行终端 cmder

    Windows下有很多比系统自带的cmd或者PowerShell好用的命令行工具,cmder是最为推荐的一款. 1.从cmder官网直接下载,一般下载full版本,下载完成后解压文件到自己指定的目录, ...

  3. nginx目录详解

  4. 小程序的flex布局

    小程序建议使用flex布局进行排版 flex就是一个盒装弹性布局 flex是一个容器,所有子元素都是他的成员 小程序的flex布局 定义布局 display:flex flex容器的属性: flex- ...

  5. BASIC合集

    握手包 给你握手包,flag是Flag_is_here这个AP的密码,自己看着办吧. 提交格式:flag{WIFI密码} 破解wifi密码 丢到kali,用aircrack-ng kali有一个包含常 ...

  6. luoguP4585 [FJOI2015]火星商店问题

    题意 显然商店编号的限制能用可持久化trie解决. 特殊的商品预先判掉就好了,现在只考虑普通的商品. 发现商品的时间是单点,询问时一段时间,于是将询问区间在线段树上拆成\(log\)个区间,分别放上该 ...

  7. GitHub 注册失败的原因 以及解决 。

    1.注册的时候老是卡在第一步: 提交用户名和密码 还有邮箱的时候 提交成功后. 不跳出 第二步.若现在去登录账号和密码,不管输对的还是输错的都是显示错误的.2.查看GitHub官网帮助后,不难发现问题 ...

  8. 数论2&莫&杜

    积性函数: 积性函数定义ok 积性函数指对于所有互质的整数\(a\)和\(b\)有性质\(f(ab)=f(a)f(b)\)的数论函数 除数函数? 莫比乌斯函数\(\mu\)ok \[ \phi(i) ...

  9. Note | Python

    目录 PyCharm+远程服务器 预备工作 Pycharm配置 list方法 os imageio Python Image Libarary (PIL) random time PyCharm+远程 ...

  10. python yield from (二)

    #pep380 #1. RESULT = yield from EXPR可以简化成下面这样 #一些说明 """ _i:子生成器,同时也是一个迭代器 _y:子生成器生产的值 ...