FreeRTOS移植,國產(chǎn)stm32BASEPRI寄存器中斷優(yōu)先級屏蔽問題
FreeRTOS移植比較簡單(比LVGL簡單多了,lvgl移植總是報錯各種東西)使用Demo里的f103Keil工程中的FreeRTOSconfig.h,不再贅述。移植后創(chuàng)建任務,在打開調(diào)度器,xPortStartScheduler()中調(diào)用prvStartFirstTask()后進入HardFault。結合網(wǎng)上資料經(jīng)過排查,默認的config.h中的優(yōu)先級設置(就f103keilDemo里的那個)沒有問題,剛創(chuàng)建了一個任務也不會出現(xiàn)棧溢出(經(jīng)測試config里的全局數(shù)組大小也不會超過c8t6的ram,不是內(nèi)存溢出問題),最后看別人視頻發(fā)現(xiàn)還要在config.h中添加兩句話:
#define ????xPortPendSVHandler ????????PendSV_Handler
#define ????vPortSVCHandler ???????????? SVC_Handler
然后把stm32f10x_it.c中的void SVC_Handler(void)和void PendSV_Handler(void)去掉,即可正常使用。原因是FreeROTS實現(xiàn)了這兩個Handler,但是名字是xPortPendSVHandler和vPortSVCHandler,和startup.s中的DCD?PendSV_Handler、DCD?SVC_Handler名字對不上,所以用宏定義對它們改名,使其和start.s中的名字一致,才能對接。下圖為沒有對接PendSV中斷和SVC中斷導致進入HardFault的函數(shù)。

第二個問題,F(xiàn)reeRTOS為了實現(xiàn)對數(shù)據(jù)的獨立訪問,會關閉調(diào)度器和中斷(或者只關閉調(diào)度器),關中斷使用portDISABLE_INTERRUPTS()宏,即vPortRaiseBASEPRI()函數(shù)。原理是向BASEPRI寄存器寫入一個數(shù),大于等于這個數(shù)的優(yōu)先級(更低優(yōu)先級)都會被屏蔽??梢詤⒖颊c原子講解FreeRTOS中斷的視頻。正點原子f103例程中有一個實驗:設定屏蔽優(yōu)先級為5,將兩個定時器的中斷優(yōu)先級設置為4和5,調(diào)用函數(shù)寫B(tài)asePri寄存器關中斷后,定時器5的中斷被關閉了,定時器4的中斷不受影響,驗證了這個機制。

然而在使用國產(chǎn)32驗證時遇到了極其逆天的問題,調(diào)用函數(shù)屏蔽優(yōu)先級為5和以上的中斷后,優(yōu)先級為4的中斷居然也被屏蔽了,效果和屏蔽等級為4相同。經(jīng)過驗證,發(fā)現(xiàn)國產(chǎn)32對于寫入BASEPRI寄存器的高四位,會將最后一位按照0處理。比如優(yōu)先級為5,寫入0X50,即01010000,等同于01000000,0X40!優(yōu)先級為9,寫入0x90,即10010000,等同于10000000,0X80!非常奇怪!
我是直接改了一下正點原子的定時器初始化里的幾句話(因為c8t6沒有TIM5,用TIM4代替),如果正點原子代碼沒問題,那這個現(xiàn)象就和預料中不一樣,只能是國產(chǎn)32的問題了。國產(chǎn)32之前還遇到過個別定時器個別引腳無法輸出PWM波的問題。


幫大伙踩踩坑,又是國產(chǎn)32的坑