天天看點

freeRTOS Kernel Control-vTaskSuspendAll-xTaskResumeAll

freeRTOS Kernel Control-vTaskSuspendAll-xTaskResumeAll

=======================================================================

freeRTOS Kernel Control-vTaskSuspendAll-xTaskResumeAll

上面這句話什麼意思?說得是“這裡不用加上critical section。想知道原因?那麼到論壇裡看Richard Barry的回複”

然後我一輸入網址打不開。critical section是什麼意思呢?在百度百科的簡介裡面是這麼說得“不論是硬體臨界資源,還是軟體臨界資源,多個線程必須互斥地對它進行通路。每個線程中通路臨界資源的那段代碼稱為臨界區(Critical Section)。”

找了找freertos代碼,感覺作者說得可能是這兩句:

#define portENTER_CRITICAL()vPortEnterCritical()

       #define portEXIT_CRITICAL() vPortExitCritical()

在非作業系統時,也遇到這個知識點,并且印象極其深刻。這是所謂的“原子”操作。關鍵是這個變量“uxSchedulerSuspended”的資料類型與處理器的處理位數的關系。比如說STM32F407是32位處理器那麼如果uxSchedulerSuspended的資料類型若大于32位,則要小心了!因為這個變量就無法被一條彙編語句處理,如果在兩條彙編語句之間進入了中斷服務程式,而中斷服務程式裡面恰好有對這個變量uxSchedulerSuspended的處理,那麼以前的彙編語句可能就讀取錯誤。當然這個錯誤發生機率極低了。有兩種方法處理這個問題,一個是指向含有uxSchedulerSuspended的語句之前禁止中斷,執行完後使能中斷。還有一種方式是弄個臨時變量比較一下。如果兩次的值相同的話就是正确的值。

=================================================================

void vTaskSwitchContext( void )

{

if( uxSchedulerSuspended != ( UBaseType_t ) pdFALSE )

{

xYieldPending = pdTRUE;

}

else

{

                //DO SOMETHING !!!

}

}

freeRTOS Kernel Control-vTaskSuspendAll-xTaskResumeAll
freeRTOS Kernel Control-vTaskSuspendAll-xTaskResumeAll
freeRTOS Kernel Control-vTaskSuspendAll-xTaskResumeAll

、====================================

簡單總結一下:

(0)挂起是令排程器阻止上下文切換,但是卻能繼續使能中斷。

那麼為什麼要挂起呢?因為vTaskSuspendAll和xTaskResumeAll之間的代碼執行時間有點長。

(1)vTaskSuspendAll和xTaskResumeAll必須成雙入對。

(2)可以嵌套,如下:

vTaskSuspendAll();

//DOsomething!!

vTaskSuspendAll();

//DOsomething!!

xTaskResumeAll();

//DOsomething!!

xTaskResumeAll();

繼續閱讀