FreeRTOS源码解析 -> vTaskDelayUntil()

来源:互联网 发布:淘宝联盟 预售 返利 编辑:程序博客网 时间:2024/05/16 06:48

     vTaskDelayUntil()的参数就是用来指定任务离开阻塞态进入就绪态那一刻的精确心跳计数值。

    API函数vTaskDelayUntil()可以用于实现一个固定执行周期的需求(当你需要让你的任务以固定频率周期性执行的时候)。

由于调用此函数的任务解除阻塞的时间是绝对时刻,比起相对于调用时刻的相对时间更精确(即比调用vTaskDelay()可以实现更精确的周期性)。

void vTaskDelayUntil( portTickType *pxPreviousWakeTime, portTickTypexTimeIncrement); 

      pxPreviousWakeTime保存了任务上一次离开阻塞态(被唤醒)的时刻。这个时刻被用作一个参考点来计算该任务下一次离开阻塞的时刻。

       xTimeIncrement此参数命名时同样是假定vTaskDelayUntil()用于实现某个任务以固定频率周期性执行—— 这个频率就是由xTimeIncrement指定的。xTimeIncrement 的单位是心跳周期,可以使用常量portTICK_RATE_MS将毫秒转换为心跳周期。

#if ( INCLUDE_vTaskDelayUntil == 1 )void vTaskDelayUntil( portTickType * const pxPreviousWakeTime, portTickType xTimeIncrement ){portTickType xTimeToWake;portBASE_TYPE xAlreadyYielded, xShouldDelay = pdFALSE;configASSERT( pxPreviousWakeTime );configASSERT( ( xTimeIncrement > 0 ) );        /*通过挂起来创建临界区,保证suspend和resume之间不会切换到其他任务*/vTaskSuspendAll();{/* Generate the tick time at which the task wants to wake. *///pxPreviousWakeTime->上次被唤醒时刻//xTimeIncrement->周期函数周期频率设定//xTimeToWake->下次被唤醒时刻xTimeToWake = *pxPreviousWakeTime + xTimeIncrement;            //当前计数小于上次唤醒时间if( xTickCount < *pxPreviousWakeTime ) /* 说明 xTickCount 溢出了 */ {/* The tick count has overflowed since this function waslasted called.  In this case the only time we should everactually delay is if the wake time has alsooverflowed,and the wake time is greater than the tick time.  When thisis the case it is as if neither time had overflowed. *//* 这时只有 xTimeToWake 也溢出了,并且 xTimeToWake > xTickCount 才需要挂起 */ if( ( xTimeToWake < *pxPreviousWakeTime ) && ( xTimeToWake > xTickCount ) ){xShouldDelay = pdTRUE;}}//当前计数大于上次唤醒时间else{/* The tick time has not overflowed.  In this case we willdelay if either the wake time has overflowed, and/or thetick time is less than the wake time. *//* 下面两种情况才需要挂起 */if( ( xTimeToWake < *pxPreviousWakeTime ) || ( xTimeToWake > xTickCount ) ){xShouldDelay = pdTRUE;}}            /* Update the wake time ready for the next call. *///更新pxPreviousWakeTime*pxPreviousWakeTime = xTimeToWake;            /*这时需要挂起*/ if( xShouldDelay != pdFALSE ){traceTASK_DELAY_UNTIL();/* We must remove ourselves from the ready list before addingourselves to the blocked list as the same list item is used forboth lists. *//* 从 Ready 链表中删除,加入 DelayedList */ vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );prvAddCurrentTaskToDelayedList( xTimeToWake );}}/*操作完毕,离开临界区*/xAlreadyYielded = xTaskResumeAll();/* Force a reschedule if xTaskResumeAll has not already done so, we mayhave put ourselves to sleep. */if( !xAlreadyYielded ){/*强制上下文切换,用在任务环境中调用*/portYIELD_WITHIN_API();}}#endif


0 0
原创粉丝点击