0 前言
-
在我们实际开发过程中,一般都用事件开发
-
不要使用死循环
1 Delay函数
1.1 两个Delay函数
FreeRTOS中有两个Delay函数:
- vTaskDelay:至少等待指定个数的Tick Interrupt才能变为就绪状态。
- vTaskDelayUntil:等待到指定的绝对时刻,才能变为就绪态。
这2个函数原型如下:
void vTaskDelay( const TickType_t xTicksToDelay ); /* xTicksToDelay: 等待多少给Tick */
/* pxPreviousWakeTime: 上一次被唤醒的时间
* xTimeIncrement: 要阻塞到(pxPreviousWakeTime + xTimeIncrement)
* 单位都是Tick Count
*/
BaseType_t xTaskDelayUntil( TickType_t * const pxPreviousWakeTime,
const TickType_t xTimeIncrement );
下面画图说明:
Tick中断如下:这里使用vTaskDelay(5)的话,就会等待5个Tick中断,任务再次变成就绪态
如果等到了5个Tick中断,并且查看现在有没有同级别的或者更高优先级的任务,如果没有的话,就会立刻执行这个任务。
现在假设我们运行的任务是这样的
while(1)
{
do_sth(); //这段代码执行的时间长度每次都不相同,假设是1ms、10ms、5ms
vTaskDelay(5); //延时5ms
}
每次执行do_sth();这段代码执行的时间长度每次都不相同,假设是1ms、10ms、5ms
实际的运行流程:
- 先运行1ms的do_sth();,再允许5ms的延时,再运行10ms的do_sth();,再运行5ms的延时,再运行5ms的do_sth();
流程如下图:
- vTaskDelay(5);这个函数运行时间大于等于5个Tick
如果想让这个函数周期运行的话,他们的间隔都是同样一段时间,如下图:
这时候就需要使用领一个函数
BaseType_t xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement );
现在的运行流程就是,先记录Tick的时刻preTime=T1,然后运行do_sth(),直到运行到T1+15=T2这个时刻
运行到T2时刻,需要做什么呢?
- 更新preTime = T2