论坛原始地址(持续更新):http://www.armbbs.cn/forum.php?mod=viewthread&tid=99514
第21章 ThreadX定时器组
本章节为大家讲解ThreadX支持的定时器组,或者叫软件定时器,又或者叫用户定时器均可。软件定时器的功能比较简单,也容易掌握。被称为定时器组是因为用户可以创建多个定时器,创建的个数是可配置的。
21.1 定时器组介绍
21.2 使用软件定时器组注意事项
21.3 定时器组创建函数tx_timer_create
21.4 定时器组激活函数tx_timer_activate
21.5 实验例程
21.6 总结
21.1 定时器组介绍
ThreadX软件定时器组的时基是基于系统时钟节拍实现的,之所以叫软件定时器是因为它的实现不需要使用任何硬件定时器,而且可以创建很多个,综合这些因素,这个功能就被称之为软件定时器组。
既然是定时器,那么它实现的功能与硬件定时器也是类似的。在硬件定时器中,我们是在定时器中断中实现需要的功能,而使用软件定时器时,我们是在创建软件定时器时指定软件定时器的回调函数,在回调函数中实现相应的功能。
21.1.1 单次模式和周期模式
ThreadX提供的软件定时器支持单次模式和周期性模式,单次模式就是用户创建了定时器并启动了定时器后,定时时间到将不再重新执行,这就是单次模式软件定时器的含义。周期模式就是此定时器会按照设置的时间周期重复去执行,这就是周期模式软件定时器的含义。另外就是单次模式或者周期模式的定时时间到后会调用定时器的回调函数,用户可以回调函数中加入需要执行的工程代码。
21.2 使用软件定时器组注意事项
定时器回调函数是在定时器任务中执行的,实际应用中切不可在定时器回调函数中调用任何将定时
器任务挂起的函数,比如tx_thread_sleep以及非零延迟的消息队列和信号量相关的函数。将定时器任务挂起,会导致定时器任务负责的相关功能都不能正确执行了。
21.3 定时器组创建函数tx_timer_create
函数原型:
UINT tx_timer_create( TX_TIMER *timer_ptr, CHAR *name_ptr, VOID (*expiration_function)(ULONG), ULONG expiration_input, ULONG initial_ticks, ULONG reschedule_ticks, UINT auto_activate);
函数描述:
此函数用于创建定时器组。
1、 第1个参数是定时器组控制块。
2、 第2个参数是定时器组名字。
3、 第3个参数是定时器计数溢出后调用的回调函数。
4、 第4个参数是第3个参数所设置函数的形参。
5、 第5个参数设置定时器时间溢出的初始延迟,单位ThreadX系统时间节拍数,范围1 到0xFFFFFFFF。注意不可以是0。
6、 第6个参数设置初始延迟后的定时器运行周期,如果设置为0,表示单次定时器。
7、 第7个参数支持如下两个选项:
- TX_AUTO_ACTIVATE 表示激活定时器。
- TX_NO_ACTIVATE 表示未激活定时器
8、 返回值
- TX_SUCCESS (0x00) 互斥信号量创建成功。
- TX_TIMER_ERROR (0x15) 无效的定时器组控制块。或者定时器组已经创建。又或者指针为NULL。
- TX_TICK_ERROR (0x16) 表示函数第5个形参为0。
- TX_ACTIVATE_ERROR(0x17)表示第7个形参无效。
- TX_CALLER_ERROR (0x13) 表示无效的调用。
注意事项:
可以在初始化和任务中调用。
使用举例:
TX_TIMER AppTimer; /* 定时器组 */ tx_timer_create(&AppTimer, "App Timer", TimerCallback, 0, /* 传递的参数 */ 100, /* 设置定时器时间溢出的初始延迟,单位ThreadX系统时间节拍数 */ 200, /* 设置初始延迟后的定时器运行周期,如果设置为0,表示单次定时器 */ TX_AUTO_ACTIVATE); /* 激活定时器 */
21.4 定时器组激活函数tx_timer_activate
函数原型:
UINT tx_timer_activate(TX_TIMER *timer_ptr);
函数描述:
用于激活定时器组。
函数参数:
1、 第1个参数是定时器组控制块。
2、 返回值
- TX_SUCCESS(0x00)设置成功。
- TX_TIMER_ERROR (0x15) 无效的定时器组控制块。
- TX_ACTIVATE_ERROR(0x17)表示已经激活,或者单次定时器模式。
注意事项:
- 可以在初始化,任务,定时器组里面调用。
使用举例:
TX_TIMER my_timer;
UINT status;
status = tx_timer_activate(&AppTimer);
21.5 实验例程
配套例子:
V7-3016_ThreadX Timer
实验目的:
- 学习ThreadX定时器组
实验内容:
1、共创建了如下几个任务,通过按下按键K1可以通过串口或者RTT打印任务堆栈使用情况
========================================================
CPU利用率 = 0.89%
任务执行时间 = 0.586484645s
空闲执行时间 = 85.504470575s
中断执行时间 = 0.173225395s
系统总执行时间 = 86.264180615s
=======================================================
任务优先级 任务栈大小 当前使用栈 最大栈使用 任务名
Prio StackSize CurStack MaxStack Taskname
2 4092 303 459 App Task Start
5 4092 167 167 App Msp Pro
4 4092 167 167 App Task UserIF
5 4092 167 167 App Task COM
0 1020 191 191 System Timer Thread
串口软件可以使用SecureCRT或者H7-TOOL RTT查看打印信息。
App Task Start任务 :启动任务,这里用作BSP驱动包处理。
App Task MspPro任务 :消息处理。
App Task UserIF任务 :按键消息处理。
App Task COM任务 :这里用作LED闪烁。
System Timer Thread任务:系统定时器任务
2、(1) 凡是用到printf函数的全部通过函数App_Printf实现。
(2) App_Printf函数做了信号量的互斥操作,解决资源共享问题。
3、默认上电是通过串口打印信息,如果使用RTT打印信息
(1) MDK AC5,MDK AC6或IAR通过使能bsp.h文件中的宏定义为1即可
#define Enable_RTTViewer 1
(2) Embedded Studio继续使用此宏定义为0, 因为Embedded Studio仅制作了调试状态RTT方式查看。
串口打印信息方式(AC5,AC6和IAR):
波特率 115200,数据位 8,奇偶校验位无,停止位 1
RTT打印信息方式(AC5,AC6和IAR):
Embedded Studio仅支持调试状态RTT打印:
由于Embedded Studio不支持中文,所以中文部分显示乱码,不用管。
程序执行框图:
21.6 总结
本章节主要为大家讲解了ThreadX的定时器组,使用中注意满足本章第2小结使用说明。