最近在使用FreeRTOS的時候,突然發現程序在運行了幾分鍾之后所有的任務都不再調用了,只有幾個中斷能正常使用,看來是系統掛掉了,連續測試了幾次想找出問題,可是這個真的有點不知所措。
我先看了下文檔里的常見錯誤,發現和我現在有關系的也就堆棧大小的設置和中斷嵌套優先級的設置了,不過我這幾個任務都是比較簡單的,沒有太多的變量,那么現在設置的堆棧大小是夠的,不然也不會運行一段時間才奔潰,應該一運行就會奔潰的。那么把問題就集中到了中斷嵌套優先級里,我嘗試了把 configKERNEL_INTERRUPT_PRIORITY = 15/configMAX_SYSCALL_INTERRUPT_PRIORITY = 10結果程序比之前更不如,直接進入了HardFault異常,那么只能看看相關的說明和解釋了。
看了下文檔里的介紹,configKERNEL_INTERRUPT_PRIORITY 是設置系統心跳時鍾的中斷優先級,configMAX_SYSCALL_INTERRUPT_PRIORITY是設置中斷安全版本FreeRTOS API 可以運行的最高中斷優先級。且建立一個全面的中斷嵌套模型需要設置 configMAX_SYSCALL_INTERRUPT_PRIRITY
為比configKERNEL_INTERRUPT_PRIORITY 更高的優先級。而基於Cortex-M3中斷優先級的特點,優先級是數值越低優先級越高,即0是最高優先級,255是最低優先級。貌似我設置的和這個不沖突啊,沒辦法去google去,找到了一個解釋:
configMAX_SYSCALL_INTERRUPT_PRIORITY needs to be a raw priority value as it is written to the NVIC priority registers in the Cortex-M3 device, as documented in the ARM manuals. The priorities of 0..15 are not real Cortex-M3 priorities, and are simplified priorities for use in some library calls (because the real priorities are so complex on Cortex-M devices). If you want a simplified priority of 8, then you need to set configMAX_SYSCALL_INTERRUPT_PRIORITY to 0x8n, where n can be any value, but by convention, and for future proofing in case future STM32 parts implement more priority bits, should be set to f. Therefore, the priority you want is 0x8f. “the code app-faults at "svc 0" in vPortStartFirstTask” Presumably a hard fault because you are attempting a call to effectively a synchronous interrupt while simultaneously having that interrupt masked out.
看到這里的解釋我知道了問題,原來我之前那樣的設置是相當於無效的,
出問題時肯定的了,
優先級設置原來是0xbx,才相當於11的優先級,原來/* equivalent to 0xb0, or priority 11. */這段注釋是這個意思
,不過一般看到這個注釋還真聯系不起來,還好找到原因了,下面測試下任務是不是還會掛掉。
下面這個圖是一個RTOS中斷優先級的說明,如果系統的優先級比configMAX_SYSCALL_INTERRUPT_PRIORITY高,則這些中斷可以直接觸發,不會被RTOS延時,如果優先級比其低,則有可能被RTOS延時。
