最近学习白问网韦东山老师在B站开源的freeRTOS课程,网址:韦东山直播公开课:RTOS实战项目之实现多任务系统 第1节:裸机程序框架和缺陷_哔哩哔哩_bilibili和7天物联网训练营【第2期】7天物联网智能家居实战训练营
在学习过程中按照韦老师的方法分析了下freeRTOS源码,如果有不对的地方请指证。
vTaskDelayUntil源码分析,基于cubemx生成的freeRTOS工程。
void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement )
{
//下次任务要唤醒的系统节拍值
TickType_t xTimeToWake;
//xAlreadyYielded:表示是否已经进行了任务切换
//xShouldDelay:表示是否需要进行延时处理
BaseType_t xAlreadyYielded, xShouldDelay = pdFALSE;
//挂起调度器
vTaskSuspendAll();
{
/* 获取系统节拍值 */
const TickType_t xConstTickCount = xTickCount;
/* 获取任务下次唤醒的系统节拍值 */
xTimeToWake = *pxPreviousWakeTime + xTimeIncrement;
//pxPreviousWakeTime指向上一次保存的任务的唤醒节拍值
//这个时候如果大于当前系统节拍值,无非两种可能
// 1、延时周期已经到达了
2、整个tick计数值,已经溢出了
if( xConstTickCount < *pxPreviousWakeTime )
{
/*1、下次要唤醒的系统节拍值小于上次要唤醒节拍值 ----- 这个就表示:系统节拍值计数溢出了
2、下次要唤醒的系统节拍值大于当前的系统节拍值 ----- 表示需要延时
*/
if( ( xTimeToWake < *pxPreviousWakeTime ) && ( xTimeToWake > xConstTickCount ) )
{
//标记需要延时
xShouldDelay = pdTRUE;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
/*
1、下次要唤醒的系统节拍值小于上次唤醒的系统节拍值 --- 证明系统节拍值溢出,需要进行延时
2、下次要唤醒的系统节拍值大于当前系统节拍值---------证明延时周期,在当前的时间之后
*/
if( ( xTimeToWake < *pxPreviousWakeTime ) || ( xTimeToWake > xConstTickCount ) )
{
//标记延时状态
xShouldDelay = pdTRUE;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
/* 保存下次唤醒的节拍值,所以传入pxPreviousWakeTime是指针类型 */
*pxPreviousWakeTime = xTimeToWake;
//判断是否需要延时
if( xShouldDelay != pdFALSE )
{
traceTASK_DELAY_UNTIL( xTimeToWake );
/* 添加任务到延时列表中去 */
prvAddCurrentTaskToDelayedList( xTimeToWake - xConstTickCount, pdFALSE );
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
//调度器恢复,如果调度器内部已经进行了任务切换,返回一个true
xAlreadyYielded = xTaskResumeAll();
/* 如果 调度器没有进行任务切换,那么要进行任务切换*/
if( xAlreadyYielded == pdFALSE )
{
//进行PendSV异常触发
portYIELD_WITHIN_API();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}