出現問題場景: 作為剛接觸FreeRTOS實時操作系統的菜鳥,我在練習一個程式功能:按鍵3按下,將LED閃爍的任務掛起;按鍵4按下,將LED閃爍的任務恢復到就緒。按鍵使用外部中斷。恢復就緒的語句是 xTaskResumeFromISR(xHandleTaskLED1(該函數用於在中斷中恢復一個被掛起 ...
出現問題場景: 作為剛接觸FreeRTOS實時操作系統的菜鳥,我在練習一個程式功能:按鍵3按下,將LED閃爍的任務掛起;按鍵4按下,將LED閃爍的任務恢復到就緒。按鍵使用外部中斷。恢復就緒的語句是 xTaskResumeFromISR(xHandleTaskLED1(該函數用於在中斷中恢復一個被掛起的任務)。 兩個按鍵的中斷優先順序程式如下: /*------------------------------------------------------------------------*/ HAL_NVIC_SetPriority(EXTI3_IRQn, 2, 0); //KEY3按鍵中斷優先順序配置 HAL_NVIC_EnableIRQ(EXTI3_IRQn); HAL_NVIC_SetPriority(EXTI4_IRQn, 3, 0); //KEY4按鍵中斷優先順序配置 HAL_NVIC_EnableIRQ(EXTI4_IRQn); /*------------------------------------------------------------------------*/ 按鍵3的中斷優先順序配置為2,按鍵4配置為3。按鍵3的掛起任務是在另一個任務中實現,按下按鍵3後正常將LED任務掛起。按鍵4的恢復任務在中斷中,按下按鍵4出現整個系統卡死,沒有任何反應。 出現問題原因:
- 在使用FreeRTOS系統時,如果想在中斷中恢復一個被掛起的任務,需要使用 xTaskResumeFromISR(TaskHandle_t xTaskToResume)函數,而不是 xTaskResume(TaskHandle_t xTaskToResume) 函數。
- 當單片機晶元使用的是CM內核的MCU,官方強烈建議將NVIC的優先順序分組配置為全搶占式優先順序,沒有響應式優先順序。這樣方便系統管理。我看了以下我的設置:HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4); 全為搶占式優先順序,正常。
- 在系統的 FreeRTOSConfig.h 配置頭文件里,定義了一個巨集定義:#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 。它的意思是:用戶可以在搶占式優先順序為 5 - 15的中斷里調用FreeRTOS的API函數(搶占式式優先順序為0的中斷裡面不允許調用)。仔細看,我定義的是從5-15的優先順序中斷可以去調用系統的API,但是上面的代碼中,我把兩個按鍵的優先順序設置為2和3,已經超過了5-15的搶占式優先順序範圍,所以我按下按鍵後,調用不了恢復任務函數!
- 我將 #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 巨集定義改為 #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 1 (因為0級搶占式優先順序不允許用戶使用)。這表明 在 1 - 15級的搶占式優先順序範圍,我的按鍵3和按鍵4的中斷優先順序在範圍之內,可以調用系統的API函數了。這樣,我的問題就解決了。