uC/OS-II成功移植在STM32 上了,雖然理解還不是很深刻,但大體明白移植方法,以前曾經(jīng)將uC/OS-II移植到MSP430F1611上,但是也沒關(guān)注那么多,現(xiàn)在按照網(wǎng)友的介紹進(jìn)行移植,下載官方的V2.86版本的固件,自己建工程,修改Port部分,建立兩個任務(wù),但是調(diào)試時死在程序死在了OSStart();里。經(jīng)過單步發(fā)現(xiàn)程序的軟件中斷觸發(fā)后調(diào)用服務(wù)函數(shù)失敗,停在了OSStartHang BOSStartHang //停在這里,而且這里正常情況下不應(yīng)該在這的;
本文引用地址:http://www.ex-cimer.com/article/201611/319066.htm然后就開始查問題,最終解決。發(fā)現(xiàn)無論學(xué)什么,一定要知其然知其所以然,不然學(xué)的永遠(yuǎn)都只是皮毛?,F(xiàn)在把自己的移植過程和理解記錄下來。
下載將官方的庫,Port部分是需要修改的部分,Source部分不用修改。
(1)OS_CPU.h文件下面定義類型名稱,堆棧類型OS_ENTER_CRITICAL(),OS_EXIT_CRITICAL()選方法3是最合適的;定義棧增長方向,STM32是高地址向低地址增長的,所以#define OS_STK_GROWTH 1 ;
另外再定義幾個函數(shù)。直接參考移植程序,這里不做說明了。注意一點(diǎn)的是要屏蔽掉有關(guān)Systick的幾個函數(shù),OS_COU_C.c文件里的有關(guān)函數(shù)也要屏蔽,這是因?yàn)槲覀冊谧约旱某绦蚶镒约喝ザx我們需要的Systick函數(shù)。
(2)OS_CPU_C.c文件定義了OSTaskStkInit()函數(shù)和一些Hook函數(shù),OSTaskStkInit()是任務(wù)切換時候用到的,Hook函數(shù)書操作系統(tǒng)給用戶擴(kuò)展用的,因?yàn)椴僮飨到y(tǒng)輕易不能讓用戶修改,故留出一些接口供用戶擴(kuò)展。
如上所述,屏蔽掉涉及Systick的函數(shù)和一些宏定義;
(3)OS_CPU_A.asm是一些用匯編寫的函數(shù),直接復(fù)制粘貼,需要修改的地方后面詳細(xì)介紹。
uC/OS-II移植時有兩個重要的中斷,一個是SysTick_Handler(),還一個是PendSV_Handler()。SysTick是心跳信號,SysTick 的最大使命,就是定期地產(chǎn)生異常請求,作為系統(tǒng)的時基。OS 都需要這種“滴答”來推動任務(wù)和時間的管理。。PendSV掛起中斷操作,它的典型應(yīng)用是進(jìn)行任務(wù)切換,操作系統(tǒng)在實(shí)際運(yùn)行中具體會出現(xiàn)這樣的問題,就是在任務(wù)切換的時候發(fā)生中斷,中斷必須得到響應(yīng),保證它的實(shí)時性,否則后果是不堪想象的。那么在 ISR 執(zhí)行過程中,發(fā)生SysTick 異常,并且搶占了該ISR,OS 執(zhí)行必要的操作,然后pend 起PendSV 異常以作好任務(wù)切換的準(zhǔn)備,重新回到中斷,中斷完成后再進(jìn)行任務(wù)切換,具體參考《Cotex-M3權(quán)威指南》7.6節(jié)。如下圖:
再介紹一下另外幾個文件,在stm32f10x_it.h函數(shù)中的都是一些中斷入口函數(shù),有SysTick_Handler()、PendSV_Handler()等函數(shù),在CMSIS啟動文件中定義了這些中斷的入口地址,包括SysTick_Handler()、PendSV_Handler()等,這樣就對應(yīng)起來了,啟動文件直接可以找到入口函數(shù)。OS需要心跳時鐘,所以我們直接在程序里初始化SysTick函數(shù),在SysTick_Handler()函數(shù)中調(diào)用OSIntEnter();OSTimeTick();OSIntExit(),這很好理解了,就是把操作系統(tǒng)的時鐘和硬件時鐘對接上了。所以也就不需要OS_CPU.h和OS_CPU_C.c中的SysTick相關(guān)的定義了。
但官方為什么要在OS_CPU.h和OS_CPU_C.c中定義OS_CPU_SysTickHandler()這個名稱的函數(shù)呢?其實(shí)在stm32f10x_it.h中已經(jīng)定義了SysTick_Handler()函數(shù),這是因?yàn)楣俜接玫氖撬约旱膯游募▋蓚€文件init.s,vectors.s。init.s負(fù)責(zé)進(jìn)入main(),vectors.s 設(shè)置中斷向量。),他的啟動文件中的入口中斷地址名稱OS_CPU_SysTickHandler()。同樣在啟動文件中他也自己定義了OS_CPU_PendSVHandler()函數(shù),所以在OS_CPU_A.asm中定義的入口函數(shù)也是OS_CPU_PendSVHandler()。而我們的啟動文件是PendSV_Handler()。所以我前面遇到的卡死就是因?yàn)镻endSV中斷沒找到對應(yīng)的中斷處理函數(shù)。所以可以修改OS_CPU_A.asm,將OS_CPU_PendSVHandle全部替換成PendSV_Handler(),并且屏蔽掉stm32f10x_it.h中的PendSV_Handler()。另一種方法是只用修改啟動文件,將PendSV_Handler()替換成OS_CPU_PendSVHandle()即可。
另外介紹兩個文件,一個是OS_cfg.h和App_cfg.h,這是兩個配置文件,OS_cfg.h是對OS進(jìn)行配置,比如OS_TICKS_PER_SEC配置、OS_TIME_DLY_HMSM_EN等對用到的模塊進(jìn)行使能操作。App_cfg.h是用戶自己按需要添加的,主要是設(shè)置任務(wù)堆棧大小,任務(wù)優(yōu)先級等。
這是我移植過程中學(xué)到的,菜鳥起步,理解還不是很深,難免有誤,歡迎指正。
評論