=======================================================================
上面這句話什麼意思?說得是“這裡不用加上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 !!!
}
}
、====================================
簡單總結一下:
(0)挂起是令排程器阻止上下文切換,但是卻能繼續使能中斷。
那麼為什麼要挂起呢?因為vTaskSuspendAll和xTaskResumeAll之間的代碼執行時間有點長。
(1)vTaskSuspendAll和xTaskResumeAll必須成雙入對。
(2)可以嵌套,如下:
vTaskSuspendAll();
//DOsomething!!
vTaskSuspendAll();
//DOsomething!!
xTaskResumeAll();
//DOsomething!!
xTaskResumeAll();