江達(dá)飛
【摘 要】針對(duì)TI公司新推出的基于Cortex-M4內(nèi)核的TM4C123G高性能低功耗芯片,詳細(xì)介紹了嵌入式開(kāi)源實(shí)時(shí)操作系統(tǒng)μCOS-Ⅱ在芯片上的移植方法。根據(jù)移植的需求,首先介紹了芯片的一些基本功能以及相關(guān)的軟件開(kāi)發(fā)環(huán)境,然后結(jié)合芯片的固有特性以及μCOS-Ⅱ移植的需求,使用C語(yǔ)言和匯編語(yǔ)言修改了相關(guān)的源文件,并詳細(xì)闡述了修改的原因。
【關(guān)鍵詞】Cortex-M4;μCOS-Ⅱ;TM4C123G;移植
0 引言
目前,嵌入式芯片已經(jīng)被廣泛應(yīng)用到我們的生活工作中,各種智能電子設(shè)備中都有他們的身影,例如智能冰箱、云電視、智能窗簾、掃地機(jī)器人等等。嵌入式處理器在所有的處理器市場(chǎng)中已經(jīng)占據(jù)了94%以上份額。在諸多的嵌入式芯片中,基于Cortex-M系列芯片以它高能效的兼容性以及易于使用性獲得了廣大開(kāi)發(fā)者的青睞。
隨著芯片性能的提高,芯片所承擔(dān)的任務(wù)將變得更為復(fù)雜,與之前的MCU相比,嵌入式芯片可能需要同時(shí)運(yùn)行幾十個(gè)不同的任務(wù),因此如何更有效的編寫應(yīng)用層軟件,管理眾多的硬件模塊以及滿足每一個(gè)任務(wù)對(duì)實(shí)時(shí)性的要求已成了亟待解決的問(wèn)題。使用傳統(tǒng)的方式進(jìn)行嵌入式開(kāi)發(fā)時(shí),開(kāi)發(fā)人員需要在充分了解硬件的基礎(chǔ)上設(shè)計(jì)出驅(qū)動(dòng)程序,并直接在主程序中調(diào)用不同的驅(qū)動(dòng)函數(shù)完成相關(guān)功能。然而,當(dāng)系統(tǒng)需要完成的任務(wù)數(shù)量變多時(shí),設(shè)計(jì)人員將很難保證每一個(gè)任務(wù)所需要的CPU資源。使用嵌入式實(shí)時(shí)操作系統(tǒng)的優(yōu)點(diǎn)是:它可以統(tǒng)一管理系統(tǒng)資源,讓開(kāi)發(fā)人員從復(fù)雜的CPU資源分配中解脫出來(lái),自動(dòng)調(diào)度多個(gè)不同任務(wù)程序,提高程序開(kāi)發(fā)效率;將硬件與軟件剝離開(kāi)來(lái),減少軟件與硬件的直接相關(guān)度,提高系統(tǒng)的可靠性。
μC/OS-II由美國(guó)嵌入式系統(tǒng)專家Jean J.Labrosse設(shè)計(jì)開(kāi)發(fā),可被移植到多種微處理器中,它是一個(gè)可以裁剪的操作系統(tǒng),通過(guò)設(shè)置os_cfg.h頭文件中的相關(guān)宏定義,可啟用或者禁用相關(guān)的功能。它擁占256個(gè)優(yōu)先級(jí),是一個(gè)多任務(wù)搶占式的實(shí)時(shí)內(nèi)核,優(yōu)先級(jí)序號(hào)越低,其任務(wù)的優(yōu)先級(jí)就越高,當(dāng)高優(yōu)先級(jí)任務(wù)就緒,就會(huì)中斷低優(yōu)先級(jí)任務(wù),保證高優(yōu)先級(jí)任務(wù)的實(shí)時(shí)性。μC/OS-II已經(jīng)通過(guò)聯(lián)邦航空局(FAA)商用航行器認(rèn)證,符合航空無(wú)線電技術(shù)委員會(huì)(RTCA)DO-178B標(biāo)準(zhǔn)。
Cortex-M4處理器是ARM公司開(kāi)發(fā)的新一代嵌入式處理器,在M3的基礎(chǔ)上,它新增了FPU、DSP和并行計(jì)算等功能,極大提高了運(yùn)算能力。本次移植使用了TI公司生產(chǎn)的TM4C123G芯片,其基于ARM Cortex M4F的內(nèi)核設(shè)計(jì)實(shí)現(xiàn),浮點(diǎn)運(yùn)算符合IEEE754標(biāo)準(zhǔn),CPU位數(shù)32位,主頻最高可達(dá)80MHz,擁有低功耗模式, systick時(shí)鐘和嵌套向量中斷控制器NVIC,適用于μC/OS-II的移植。軟件使用了TI公司提供的CCS集成開(kāi)發(fā)環(huán)境。
1 μC/OS-II的移植
μC/OS-II v2.91的源代碼分為三個(gè)部分,其中第一部分文件放置在Configure文件夾中,用于配置/裁剪系統(tǒng);另外一部分文件放在Source文件夾中,此部分程序是操作系統(tǒng)的核心文件,無(wú)需修改;最后一部分文件在Ports文件夾中,內(nèi)部包含OS_CPU.h、OS_CPU.c、OS_CPU_A.asm三個(gè)文件。在不同的芯片上使用μC/OS-II時(shí),需要結(jié)合芯片的特性,對(duì)這三個(gè)文件進(jìn)行修改。
1.1 OS_CPU.h文件的移植
該頭文件定義了數(shù)據(jù)類型、處理器堆棧數(shù)據(jù)字長(zhǎng)度、堆棧的增長(zhǎng)方向、任務(wù)切換的宏定義和臨界區(qū)訪問(wèn)的處理方法。
由于不同的處理器其內(nèi)部一次所能處理的字長(zhǎng)不一致,因此對(duì)于不同的CPU來(lái)說(shuō),int,unsigned int等數(shù)據(jù)類型它的字長(zhǎng)可能是不同的,μC/OS-II為了保證可移植性,程序中自己定義了一套數(shù)據(jù)類型,例如使用INT32U表示無(wú)符號(hào)32位整形,TM4C123G是32位處理器,其unsigned int表示32位無(wú)符號(hào)整形,因此可以使用typedef將unsigned int定義為INT32U。然而,對(duì)于其它一些16位的處理器來(lái)說(shuō),unsigned int可能表示的是16位無(wú)符號(hào)整形,因此INT32U必須被定義為unsigned long型。
臨界段又被稱為關(guān)鍵代碼區(qū),是指一小段代碼,同一時(shí)刻只能夠允許一個(gè)線程存取資源。在它能夠執(zhí)行前,必須獨(dú)占某些共享資源的訪問(wèn)權(quán),一旦線程進(jìn)入了臨界段,就意味著在這期間,其它想要獲得該共享資源訪問(wèn)權(quán)的線程必須等待該線程處理完成,并釋放資源。這是讓若干行代碼能夠以原子操作方式來(lái)使用資源的一種方法。μC/OS-II是一個(gè)搶占式的實(shí)時(shí)內(nèi)核,在進(jìn)入和退出臨界段時(shí)需要關(guān)閉和打開(kāi)中斷,它使用OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()這兩個(gè)宏來(lái)控制中斷打開(kāi)或者關(guān)閉,并提供了三種方式:①直接通過(guò)使用指令_disable_interrupt()和_enable_interrupts()開(kāi)關(guān)中斷;②將當(dāng)前的中斷狀態(tài)字壓至堆棧,然后再關(guān)閉中斷,當(dāng)中斷結(jié)束后,再將堆棧中的狀態(tài)字彈出;③保存當(dāng)前CPU狀態(tài)字至局部變量,然后關(guān)中斷,當(dāng)需要開(kāi)中斷時(shí),再將局部變量恢復(fù)至CPU寄存器中。使用前兩種方式會(huì)造成CPU在中斷前后狀態(tài)不一致,但第三種方式需要匯編指令支持。TM4C123G芯片使用Thumb-2指令集,支持MRS指令,可以將CPU狀態(tài)寄存器的值返回至通用寄存器中,因此可以使用第三種方式控制中斷。OS_CPU_SR_Save和OS_CPU_SR_Restore在.asm文件中定義,由于ARM編譯器默認(rèn)會(huì)將函數(shù)的第一個(gè)參數(shù)傳送至R0通用寄存器,因此它們可以定義為:
OS_CPU_SR_Save
MRS R0, PRIMASK //保存CPU狀態(tài)寄存器
CPSID I //關(guān)中斷
BX LR
OS_CPU_SR_Restore
MSR PRIMASK, R0 //恢復(fù)CPU狀態(tài)寄存器
BX LR
堆棧增長(zhǎng)方向是指數(shù)據(jù)入棧時(shí)字節(jié)變量在內(nèi)存中的存儲(chǔ)順序,Cortex-M4內(nèi)核支持的是“向下生長(zhǎng)的滿?!狈绞?,即堆棧SP指針在壓入一個(gè)新的數(shù)據(jù)時(shí),其值需要先被減去4,然后再存入新的數(shù)值。因此宏OS_STK_GROWT的值被設(shè)置為1。
1.2 OS_CPU.c文件的移植
OS_CPU.c文件中包含移植中可以在C語(yǔ)言環(huán)境下實(shí)現(xiàn)的代碼。在該文件中,包含了多個(gè)hook鉤子函數(shù)、OSTaskStkInit()任務(wù)堆棧初始化函數(shù)和Tmr_TickISR_Handler()時(shí)鐘中斷服務(wù)函數(shù),其中 OSTaskStkInit()和Tmr_TickISR_Handler()函數(shù)是移植能否成功的關(guān)鍵。
OSTaskStkInit()在任務(wù)創(chuàng)建函數(shù)OSTaskCreate()函數(shù)中被調(diào)用,用于創(chuàng)建一個(gè)新的線程,因此,在剛開(kāi)始,需要在堆棧中模擬一個(gè)線程剛被中斷的假象。在cortex-M4內(nèi)核中,當(dāng)系統(tǒng)被中斷時(shí),xPSR,PC,LR,R12,R3~R0寄存器將被自動(dòng)保存至堆棧之中,R11~R4則在需要時(shí),通過(guò)人工的方式進(jìn)行保存。另外由于cortex-M4包含浮點(diǎn)運(yùn)算單元FPU,如果該單元被啟用,則內(nèi)部的FPSCR,S0~S15寄存器也會(huì)自動(dòng)保存至堆棧中,S16~S31寄存器通過(guò)人工方式保存。為了模擬任務(wù)線程被中斷的場(chǎng)景,OSTaskStkInit()的定義如下:
OS_STK *OSTaskStkInit()
{
保存FPSCR及S15~S0寄存器;//保存FPU自動(dòng)保存的寄存器
保存xPSR,xPSR,PC,LR,R12,R3~R0等寄存器;//保存CPU自動(dòng)保存的寄存器
保存S16~S31寄存器;//保存FPU中需要人工保存的寄存器
保存R4~R11寄存器;//保存CPU中需要人工保存的通用寄存器
}
Tmr_TickISR_Handler()是時(shí)鐘中斷函數(shù),其內(nèi)部調(diào)用了μC/OS-II的節(jié)拍服務(wù)函數(shù)OSTimeTick(),在實(shí)時(shí)操作系統(tǒng)中起著”心臟“的作用。Tmr_TickISR_Handler()可以使用通用時(shí)間定時(shí)器或者看門狗定時(shí)器,但在cortex-M4內(nèi)核中,單獨(dú)為RTOS提供了一個(gè)24位周期性定時(shí)器systick,使用它作為系統(tǒng)時(shí)鐘的優(yōu)勢(shì)是:所有基于ARM架構(gòu)的M3或是M4內(nèi)核,其內(nèi)部都會(huì)有一個(gè)systick定時(shí)器,這樣做方便了程序在不同的器件之間的移植。
1.3 OS_CPU_A.asm文件的移植
該文件中包含多個(gè)用于任務(wù)切換的關(guān)鍵函數(shù),由于要涉及寄存器的保存與恢復(fù),因此只能使用匯編語(yǔ)言實(shí)現(xiàn)。另外,由于使用CCS作為編譯環(huán)境,因此在文件的起始處,使用.global引入外部C文件聲明的函數(shù),使用.def引出本文件中聲明的函數(shù)。
OSStartHighRdy()函數(shù)的作用是啟動(dòng)第一個(gè)最高優(yōu)先級(jí)任務(wù),它的工作過(guò)程分為以下五個(gè)步驟:①設(shè)置PendSV異常中斷的優(yōu)先級(jí)為最低。這樣能夠保證上下文切換是在沒(méi)有任何中斷需要被響應(yīng)時(shí)進(jìn)行的,保證系統(tǒng)的實(shí)時(shí)性。②設(shè)置PSP進(jìn)程棧指針為0,指定是第一次任務(wù)切換。③設(shè)置OSRunning標(biāo)志位1,表示系統(tǒng)已開(kāi)始運(yùn)行。④觸發(fā)PendSV中斷,實(shí)現(xiàn)上下文切換。⑤使能中斷。
OSCtxSw()和OSIntCtxSw()兩個(gè)函數(shù)的功能類似,都是完成任務(wù)的切換,不同的是一個(gè)是任務(wù)級(jí)的,一個(gè)是中斷級(jí)的,但由于是在cortex-M4上移植,所有的任務(wù)切換工作都在PendSV中斷函數(shù)中完成,以加快處理速度,因此這兩個(gè)函數(shù)的內(nèi)容是完全一致的,只要觸發(fā)PendSV中斷即可。
PendSV函數(shù)是完成任務(wù)切換的核心函數(shù),為了實(shí)現(xiàn)高低優(yōu)先級(jí)任務(wù)間的切換,該函數(shù)必須完成以下幾個(gè)操作:①獲取進(jìn)程堆棧指針PSP,如果是0則表示當(dāng)前是第一次任務(wù)切換,無(wú)需保存寄存器;②保存S16~S31寄存器,其它FPU寄存器系統(tǒng)將自動(dòng)保存;③保存R4~R11通用寄存器,其它CPU寄存器系統(tǒng)自動(dòng)保存;④將PSP指針保存至TCB中,令OSTCBStkPtr指針的值等于PSP;⑤調(diào)用OSTaskSwHook鉤子函數(shù),在任務(wù)切換之前完成用戶需要完成的一些特定工作;⑥獲得當(dāng)前就緒的最高優(yōu)先級(jí)任務(wù),并從相應(yīng)的TCB中獲得進(jìn)程堆棧指針;⑦根據(jù)獲取的堆棧指針,從相應(yīng)的堆棧中將S16~S31恢復(fù)至FPU中;⑧恢復(fù)R4~R11寄存器到CPU中,并執(zhí)行相應(yīng)的中斷返回指令。
2 總結(jié)
通過(guò)對(duì)基于cortex-M4內(nèi)核的TM4C123G芯片工作原理以及內(nèi)部寄存器研究,結(jié)合μC/OS-II實(shí)時(shí)操作系統(tǒng)移植的需求,正確配置了OS_CPU.h,OS_CPU.c,OS_CPU_A.asm三個(gè)文件,實(shí)現(xiàn)了實(shí)時(shí)操作系統(tǒng)在M4內(nèi)核上的移植,實(shí)驗(yàn)表明,使用操作系統(tǒng)可以很好的控制TM4C123G開(kāi)發(fā)板上LED燈的閃爍,證明移植是成功的。
【參考文獻(xiàn)】
[1]肖圣兵,肖紅菊.μC/OS-II在ARM+Cortex-M3處理器上的移植[J].電子技術(shù)設(shè)計(jì)與運(yùn)用,2014,8:54-55.
[2]關(guān)海,馮大政.μC/OS-II在基于Cortex-M3核的ARM處理器上的移植[J].電子科技,2009,22:69-73.
[3]潘麗蕊,袁保社.基于Cortex-M3核的μC/OS-II移植與應(yīng)用[J].電腦知識(shí)與技術(shù), 2010,5111-5114.
[4]盧有亮.嵌入式實(shí)時(shí)操作系統(tǒng)[M].北京:電子工業(yè)出版社,2014.
[責(zé)任編輯:湯靜]