从这篇文章开始就为大家介绍 FreeRTOS, 让大家快速入门 FreeRTOS。
文章目录
前言
FreeRTOS 课程大纲(目录):FreeRTOS 探秘之路(目录)
一、软件定时器的概念,特性
1. 概念 :
-
问:什么是软件定时器啊?
-
答:软件定时器实际上就是闹钟。
在生活中我们可以设置闹钟,例如:30分钟后起床,50分钟后跑步。我们可以设置无数个闹钟,这无数个闹钟都依赖于一个真实的闹钟。
在 FreeRTOS 里我们也可以设置无数个软件定时器,它们都是基于系统的滴答中断(Tick Interrupt)。
系统滴答中断(Tick Interrupt)通常依赖于 滴答定时器(Tick Timer)。滴答定时器是一种周期性的定时器,其作用是在固定的时间间隔中产生中断。这种定时器通常在系统中用来维护系统的时钟和定时任务。
2. 特性 :
软件定时器有 2 种状态:
- 运行:当指定时间到达后,它的回调函数就会被调用。
- 冬眠:不再运行,它的回调函数不会被调用。
软件定时器有 2 种类型:
- 一次性:定时器启动后,回调函数只会调用一次。
- 自动加载定时器:启动后,时间到达就会自动调用回调函数,周期性的调用。
二、STM32cubeMX配置软件定时器
关于 cubeMX配置FreeRTOS 前面的步骤可以参考我之前的文章:STM32cubeMX配置FreeRTOS工程
创建一个软件定时器:
配置定时器
Timer Name:软件定时器名字
Callback:软件定时器回调函数
Type:软件定时器类型
Parameter:传递给软件定时器回调函数的参数
Allocation:软件定时器创建方式
Control Block Name:软件定时器控制块名字
三、软件定时器函数
1. 创建
osTimerId_t osTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument,
const osTimerAttr_t *attr);
osTimerFunc_t function : 定时器溢出时要执行的回调函数(定时器回调函数的类型定义)。
osTimerType_t type : 定时器类型,可以是单次定时器( osTimerOnce )或周期性定时器( osTimerPeriodic )。
void *argument : 传递给回调函数的参数。
const osTimerAttr_t *attr : 定时器属性,通常为 NULL 。
返回值:
osTimerId_t : 如果创建成功,返回定时器的标识符(ID);否则返回 NULL 。
2. 开启
osStatus_t osTimerStart (osTimerId_t timer_id, uint32_t ticks);
osTimerId_t timer_id : 要启动的定时器的标识符(ID)。
uint32_t ticks : 定时器的初始延迟,单位是系统时钟的滴答数。
返回值:
osStatus_t : 返回操作状态,通常是 osOK 表示成功。
3. 停止
osStatus_t osTimerStop (osTimerId_t timer_id);
osTimerId_t timer_id : 要停止的定时器的标识符(ID)。
返回值:
osStatus_t : 返回操作状态,通常是 osOK 表示成功。
4. 删除
osStatus_t osTimerDelete (osTimerId_t timer_id);
osTimerId_t timer_id : 要删除的定时器的标识符(ID)。
返回值:
osStatus_t : 返回操作状态,通常是 osOK 表示成功。
四、软件定时器实验
创建一个定时器每 1 秒打印一次 Hello World 。
// 开启定时器
osTimerStart(myTimer01Handle, 1000);
/* Callback01 function */
void Callback01(void *argument)
{
/* USER CODE BEGIN Callback01 */
printf("Hello World\r\n");
/* USER CODE END Callback01 */
}
五、实现机理
- 问 :前面提到过软件定时器基于 Tick 来运行,那在哪里执行定时器的函数呢?
- 答:不在 Tick 中断中执行,在守护任务中执行。
- 守护任务
在开启调度器
时会创建软件定时器任务,这个任务也叫做守护任务。
守护任务的调度和普通任务并无差别。当守护任务是当前优先级最高的就绪任务时,它就可以执行定时器的回调函数
,处理命令。通常守护任务的优先级是最高的。
能否及时处理定时器的命令,能否及时执行定时器的回调函数,严重依赖于守护任务的优先级。
- 在守护任务内部创建定时器消息队列:
- 使用定时器开启函数 osTimerStart 内部 其实是向消息队列发送消息。
总结
下一篇文章为大家介绍 FreeRTOS 里的 空闲任务和钩子函数。