#if ( INCLUDE_vTaskDelay == 1 ) //延時特定時間xTicksToDelay,這個時間需要轉(zhuǎn)換為喚醒絕對時間xTimeToWake, //這樣才能在與vTaskIncrementTick函數(shù)中操作的數(shù)值是一致的xTicksToDelay:延時的節(jié)拍數(shù) void vTaskDelay( const TickType_t xTicksToDelay ) { TickType_t xTimeToWake; BaseType_t xAlreadyYielded = pdFALSE; if( xTicksToDelay > ( TickType_t ) 0U )//若延遲的時間是0,就是調(diào)度器的重新啟動。若延時時間大于0,執(zhí)行延時操作。 { configASSERT( uxSchedulerSuspended == 0 ); vTaskSuspendAll();//系統(tǒng)維護一個uxSchedulerSuspended計數(shù)值,當其大于0時表示禁止調(diào)度;等于0時則表示允許調(diào)度。 { traceTASK_DELAY(); //計算喚醒時間--這可能會溢出,但不會有問題 ,大家會問為什么 //大家可以自己做個試驗,兩個uCHAR型數(shù)據(jù)相加,如果超過255,則等于多少? xTimeToWake = xTickCount + xTicksToDelay;//任務(wù)的喚醒時間更新。 if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )//若刪除完后鏈表中沒有任務(wù) //把任務(wù)從當前運行鏈表中移除出去,然后把它添加到阻塞鏈表里面 { //當前任務(wù)必須在就緒鏈表中,所以其是不必檢查的,下面的宏定義可以直接調(diào)用 portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority ); } else { mtCOVERAGE_TEST_MARKER(); } prvAddCurrentTaskToDelayedList( xTimeToWake ); //prvAddCurrentTaskToDelayedList是一個函數(shù),它是把當前的任務(wù)控制塊, //放進DelayedList鏈表中,而DelayedList有兩個鏈表,一個是溢出的,一個是正在應用的, //所以要根據(jù)傳遞進的參數(shù)xTimeToWake進行分別設(shè)置,如果是在當前的延時鏈表里就添加進現(xiàn)在的延時鏈表, //如果計算出來后是溢出鏈表,則添加進溢出鏈表里面 } xAlreadyYielded = xTaskResumeAll();//得到任務(wù)切換的具體情況,pdTRUE切換成功否則切換失敗。 } else { mtCOVERAGE_TEST_MARKER(); } if( xAlreadyYielded == pdFALSE )//若上面的切換失敗,或不需要延遲。直接進行切換。 { portYIELD_WITHIN_API(); //實際就是終端控制及狀態(tài)寄存器ICSR,寫位28為1懸起PendSV,進入到xPortPendSVHandler。 } else { mtCOVERAGE_TEST_MARKER(); } } #endif #if ( INCLUDE_vTaskDelayUntil == 1 ) void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement ) //參數(shù):pxPreviousWakeTime---上一次調(diào)用本函數(shù)的時間 // xTimeIncrement---相對于pxPreviousWakeTime本次延時的節(jié)拍數(shù) //由于調(diào)用此函數(shù)的任務(wù)解除阻塞的時間是絕對時刻,比起相對于調(diào)用時刻的相對時間更精確(即比調(diào)用vTaskDelay()可以實現(xiàn)更精確的周期性)。 //pxPreviousWakeTime: 此參數(shù)命名時假定vTaskDelayUntil()用于實現(xiàn)某個任務(wù)以固定頻率周期性執(zhí)行。這種情況下pxPreviousWakeTime // 保存了任務(wù)上一次離開阻塞態(tài)(被喚醒)的時刻。這個時刻被用作一個參考點來計算該任務(wù)下一次離開阻塞態(tài)的時刻。 //xTimeIncrement: 此參數(shù)命名時同樣是假定vTaskDelayUntil()用于實現(xiàn)某個任務(wù)以固定頻率周期性執(zhí)行 —— 這個頻率就是由xTimeIncrement 指定的。 // *xTimeIncrement 的單位是心跳周期, 可以使用常量portTICK_RATE_MS 將毫秒轉(zhuǎn)換為心跳周期 { TickType_t xTimeToWake;//和vTaskDelay函數(shù)中一樣定義,最終得到xTimeToWake賦值給xGenericListItem .xItemValue BaseType_t xAlreadyYielded, xShouldDelay = pdFALSE; configASSERT( pxPreviousWakeTime ); configASSERT( ( xTimeIncrement > 0U ) ); configASSERT( uxSchedulerSuspended == 0 ); vTaskSuspendAll();//調(diào)度器掛起 { const TickType_t xConstTickCount = xTickCount;//xTickCount在這個函數(shù)里面不能改變,所以采用另外一個變量做優(yōu)化。 xTimeToWake = *pxPreviousWakeTime + xTimeIncrement; //計算下次喚醒的時刻. if( xConstTickCount < *pxPreviousWakeTime )//說明 xTickCount 溢出了 { //pxPreviousWakeTime指向上一次的喚醒時間,這個地方有點難理解,可以這樣說明:時間軸是一個往前的軸, //是不會有溢出之說法,也就是說xTickCount永遠都是大于喚醒時間的而不管哪一次的喚醒時間都是大于, //但由于溢出的存在,所以有時候xTickCount會小于喚醒時間,這里就說明是小于上一次設(shè)置的喚醒時間,如果是就說明是溢出了 //::T3::::::T2:::::::::::::::::::::T1:::::::::::::::::::::::::::::::::::::T2:::::::::::::::::T3:::::::::*/ // xTickCount *pxPreviousWakeTime xTickCount xTimeToWake*/ //T1對應*pxPreviousWakeTime ,T2對應xTickCount,T3對應xTimeToWake*/ //因為在運行這個程序時,任務(wù)因為運行了其它程序,造成了xTickCount和喚醒時間不是在同一個點上,要么大于*pxPreviousWakeTime, //要么小于*pxPreviousWakeTime,就像T2一樣,如果運行到T第一個T0處,那么,就相當于xTickCount已經(jīng)溢出了,那么需要不 //需要延時,就要看xTimeToWake所處的位置了,如果沒溢出,則說明不需要延時就可以調(diào)度任務(wù) //,如果溢出了,還要看是否大于xTickCount,如果是才能算的上是真正的需要放入延時鏈表里面 if( ( xTimeToWake < *pxPreviousWakeTime ) && ( xTimeToWake > xConstTickCount ) ) //這時只有 xTimeToWake 也溢出了,并且 xTimeToWake > xConstTickCount 才需要休眠 { xShouldDelay = pdTRUE; } else { mtCOVERAGE_TEST_MARKER(); } } else { //下面兩種情況才需要休眠 if( ( xTimeToWake < *pxPreviousWakeTime ) || ( xTimeToWake > xConstTickCount ) ) { xShouldDelay = pdTRUE; } else { mtCOVERAGE_TEST_MARKER(); } } //為下一次 Delay 更新 pxPreviousWakeTime. *pxPreviousWakeTime = xTimeToWake;//把需要喚醒的絕對時間保存起來,保存到pxPreviousWakeTime指針變量里面 if( xShouldDelay != pdFALSE )//這時需要休眠,由上面的判斷任務(wù)是否進入延時鏈表,如果不需要,則仍是當前運行的任務(wù) { traceTASK_DELAY_UNTIL(); //從 Ready 鏈表中刪除,加入 Blocked List if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 ) { portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority ); } else { mtCOVERAGE_TEST_MARKER(); } prvAddCurrentTaskToDelayedList( xTimeToWake ); } else { mtCOVERAGE_TEST_MARKER(); } } xAlreadyYielded = xTaskResumeAll(); //在運行上面臨界區(qū)的程序時,可能有任務(wù)需要調(diào)度,但因為調(diào)度器的掛起而沒有被調(diào)度,只是給出了登記, //而這個xTaskResumeAll函數(shù)就是要把放進xPendingReadyList鏈表中的任務(wù)節(jié)點轉(zhuǎn)移到真正的就緒鏈表pxReadyTasksLists里面, //如果任務(wù)是因為tick缺失或者因為在恢復實際走過的滴答數(shù)時有任務(wù)需要搶占CPU,則 xAlreadyYielded 都為真, //從而導致下面不會運行,如果沒有被搶占也就是說當前還是處于最高級任務(wù),但是上面的延時已經(jīng)使其阻塞,從而在下面發(fā)生搶占 if( xAlreadyYielded == pdFALSE ) //強制自己交出CPU,使自身進入等待延時。個人認為:此處并不需要強制交出,如果上面并不需要加入延時鏈表, //表示還是運行的當前任務(wù),如果這個任務(wù)仍然是最高級的,則并不需要切換 { portYIELD_WITHIN_API(); } else { mtCOVERAGE_TEST_MARKER(); } } #endif 原文鏈接:
FreeRTOS(V8.0.1)系統(tǒng)之vTaskDelay()和vTaskDelayUntil()
相關(guān)推薦
FreeRTOS嵌入式實時操作系統(tǒng)
![](https://skin.elecfans.com/images/2021-soft/eye.png)
![](https://file1.elecfans.com//web2/M00/A5/B2/wKgZomUMOaiABurJAAH1RuVQWuQ285.jpg)
FreeRTOS 9.0 vTaskDelayUntil( )函數(shù)源碼問題如何解決
FreeRTOS V9.0.0 的相關(guān)資料推薦
FreeRTOS與RISC-V——適用于RISC-V的FreeRTOS概述
FreeRTOS兩種延時函數(shù)的區(qū)別是什么?
FreeRTOS創(chuàng)建任務(wù)操作Flash運行時系統(tǒng)調(diào)度出現(xiàn)錯誤
FreeRTOS學習筆記(三)——FreeRTOS內(nèi)核配置說明
FreeRTOS操作系統(tǒng)實用教程分享?
FreeRTOS有何功能
FreeRTOS退出中斷函數(shù)后系統(tǒng)切換到串口通信任務(wù)中
FreeRtos如何進行任務(wù)切換
freeRTOS里面vTaskDelay的輸入?yún)?shù)是什么?
freeRtos和裸機 跑同樣一個程序,效率不一樣
freertos中的任務(wù)執(zhí)行時間問題求解
freertos多任務(wù)運行,為什么只能跑一個任務(wù)
vTaskDelay系統(tǒng)延時函數(shù)時間到后是否為調(diào)用此函數(shù)的任務(wù)重新執(zhí)行?
vTaskDelay延時不準怎么解決?
vTaskDelayUntil絕對延時,vTaskDelay相對延時有什么區(qū)別呢?
CH32V307VCT6用FreeRTOS例程增加一段代碼后系統(tǒng)無法運行了
ESP8266報錯CONFIG_FREERTOS_HZ未定義的原因?如何解決?
ETH-CH32v20x_v307在Freertos中添加以太網(wǎng)
STM32 FreeRTOS 外部中斷服務(wù)函數(shù)注意事項 精選資料推薦
STM32之FreeRTOS學習筆記 精選資料推薦
delay_xms()和vTaskDelay()函數(shù)區(qū)別問題如何解決
stm32f103的FreeRTOS工程文件源碼分享
【Atmel WINC1500-XSTK試用體驗】+移植freertos
【HAL庫每天一例】第118例:FreeRTOS移植
【MAX32660試用體驗】freertos+dht11+rgy燈
【設(shè)計技巧】從單片機到操作系統(tǒng)(7)-FreeRTOS延時介紹
什么是多任務(wù)系統(tǒng)?FreeRTOS任務(wù)與協(xié)程簡析
使用FreeRTOS操作系統(tǒng),創(chuàng)建幾個任務(wù)后進入prvTaskExitError第四個任務(wù)不正常的原因?
關(guān)于FreeRTOS 任務(wù)狀態(tài)機之阻塞的筆記,給大家分享下
關(guān)于freertos任務(wù)切換問題誰來解答一下
函數(shù)vTaskDelay能引發(fā)任務(wù)切換嗎?
在freertos的幾個任務(wù)中,能不能既有任務(wù)使用vTaskDelay也有任務(wù)使用vtaskdelayuntil?
在GD32F310開發(fā)板移植FreeRTOS系統(tǒng)
如何在RISC-V處理器上使用FreeRTOS?
開發(fā)實戰(zhàn)+編程指南,教你快速學習FreeRTOS系統(tǒng)
怎樣去設(shè)計FreeRTOS操作系統(tǒng)?
淺析FreeRTOS任務(wù)系統(tǒng)
添加第二個USART和第五個任務(wù)會殺死vTaskDelay
第30章 FreeRTOS低功耗之睡眠模式
第31章 FreeRTOS低功耗之停機模式
第32章 FreeRTOS低功耗之待機模式
請問FreeRTOS v8.23系統(tǒng)支持FPU, lwip功能嗎?
請問FreeRTOS中vTaskDelay延時不正確的原因是什么?
轉(zhuǎn):移植FreeRTOS到KEA128
轉(zhuǎn):第5章 FreeRTOS操作系統(tǒng)移植(MDK版)
闡述FreeRTOS系統(tǒng)中機制的實現(xiàn)原理
FreeRTOS(V8.0.1)系統(tǒng)之vTaskDelete()
![](https://skin.elecfans.com/images/2021-soft/eye.png)
FreeRTOS(V8.0.1)系統(tǒng)之vTaskSuspendAll()和xTaskResumeAll()
![](https://skin.elecfans.com/images/2021-soft/eye.png)
FreeRTOS(V8.0.1)系統(tǒng)之xTaskGenericCreate()
![](https://skin.elecfans.com/images/2021-soft/eye.png)
FreeRTOS代碼剖析之1:內(nèi)存管理Heap
![](https://skin.elecfans.com/images/2021-soft/eye.png)
![](https://file1.elecfans.com//web2/M00/A6/A8/wKgZomUMP2-AXEPPAAAcXbfhrWQ977.png)
FreeRTOS代碼剖析之2:內(nèi)存管理Heap
![](https://skin.elecfans.com/images/2021-soft/eye.png)
![](https://file1.elecfans.com//web2/M00/A6/A8/wKgZomUMP2-Af1DuAAAM-f5jrT8382.png)
FreeRTOS代碼剖析之3:內(nèi)存管理Heap
![](https://skin.elecfans.com/images/2021-soft/eye.png)
FreeRTOS嵌入式開源實時操作系統(tǒng)介紹
![](https://skin.elecfans.com/images/2021-soft/eye.png)
基于FreeRTOS的嵌入式實時操作系統(tǒng)的原理和實現(xiàn)
![](https://skin.elecfans.com/images/2021-soft/eye.png)
什么是操作系統(tǒng)?FreeRTOS中文實用教程讓你快速入門FreeRTOS
![](https://skin.elecfans.com/images/2021-soft/load.png)
FreeRTOS任務(wù)控制API函數(shù)介紹
![](https://skin.elecfans.com/images/2021-soft/eye.png)
基于FreeRTOS的嵌入式云臺控制系統(tǒng)設(shè)計
![](https://skin.elecfans.com/images/2021-soft/load.png)
嵌入式操作系統(tǒng)FREERTOS的移植.
![](https://skin.elecfans.com/images/2021-soft/load.png)
嵌入式操作系統(tǒng)FreeRTOS的原理實現(xiàn)
![](https://skin.elecfans.com/images/2021-soft/load.png)
嵌入式操作系統(tǒng)FREERTOS移植
![](https://skin.elecfans.com/images/2021-soft/load.png)
基于FreeRTOS的直流系統(tǒng)主監(jiān)控的設(shè)計
![](https://skin.elecfans.com/images/2021-soft/load.png)
STM32移植FreeRTOS(圖文實操)
![](https://skin.elecfans.com/images/2021-soft/load.png)
從0到1學習FreeRTOS:FreeRTOS 內(nèi)核應用開發(fā):(一)移植FreeRTOS到STM32第一部分
![](https://skin.elecfans.com/images/2021-soft/load.png)
初入FreeRTOS
![](https://skin.elecfans.com/images/2021-soft/load.png)
菜鳥入門7,what is FreeRTOS?
![](https://skin.elecfans.com/images/2021-soft/load.png)
【轉(zhuǎn)載】AT32 FreeRTOS應用筆記
![](https://skin.elecfans.com/images/2021-soft/load.png)
FreeRTOS —— 0.前言
![](https://skin.elecfans.com/images/2021-soft/load.png)
FreeRTOS學習(1)——FreeRTOS移植
![](https://skin.elecfans.com/images/2021-soft/load.png)
FreeRTOS入門學
![](https://skin.elecfans.com/images/2021-soft/load.png)
FreeRTOS高級篇9---FreeRTOS系統(tǒng)延時分析
![](https://skin.elecfans.com/images/2021-soft/load.png)
FreeRTOS高級篇2---FreeRTOS任務(wù)創(chuàng)建分析
![](https://skin.elecfans.com/images/2021-soft/load.png)
FreeRTOS系列第8篇---FreeRTOS內(nèi)存管理
![](https://skin.elecfans.com/images/2021-soft/load.png)
FreeRTOS給任務(wù)傳遞兩個參數(shù)LEDpin和vTaskDelay
![](https://skin.elecfans.com/images/2021-soft/eye.png)
STM32G0開發(fā)筆記:使用FreeRTOS系統(tǒng)
![](https://skin.elecfans.com/images/2021-soft/eye.png)
![](https://file.elecfans.com/web2/M00/8A/DF/poYBAGPE90WAWzvUAAJdbkXfW9k951.png)
freeRTOS的任務(wù)
![](https://skin.elecfans.com/images/2021-soft/eye.png)
![](https://file.elecfans.com/web2/M00/8F/BA/poYBAGPls6KAIydMAAQsn1y3Z9c801.jpg)
FreeRTOS:一個迷你的實時操作系統(tǒng)內(nèi)核
![](https://skin.elecfans.com/images/2021-soft/eye.png)
![](https://file1.elecfans.com/web2/M00/8B/B5/wKgZomSdSn6AfapKAAC9H46ZAvo324.jpg)
基于STM32的FreeRTOS開發(fā)(1)----FreeRTOS簡介
![](https://skin.elecfans.com/images/2021-soft/eye.png)
![](https://file1.elecfans.com/web2/M00/8D/EB/wKgaomTBzP-Abdm8AADYzLBC-Bw325.png)
Brocade Fabric操作系統(tǒng)訪問網(wǎng)關(guān)管理指南8.0.1
![](https://skin.elecfans.com/images/2021-soft/load.png)
FreeRTOS任務(wù)實現(xiàn)和控制塊
![](https://skin.elecfans.com/images/2021-soft/eye.png)
評論