中文引用格式: 王磊,王宜懷,姚望舒,等. MQXLite操作系統(tǒng)在ARM Cortex-M0+/M4上的移植研究與實現(xiàn)[J].電子技術(shù)應(yīng)用,2015,41(11):27-30.
英文引用格式: Wang Lei,Wang Yihuai,Yao Wangshu,et al. The study and implementation of porting MQXLite RTOS to ARM Cortex-M0+/M4[J].Application of Electronic Technique,2015,41(11):27-30.
0 引言
MQXLite操作系統(tǒng)是飛思卡爾公司維護的一款開源的嵌入式實時操作系統(tǒng),是已有十幾年穩(wěn)定實踐運行經(jīng)驗的標(biāo)準(zhǔn)版MQX(Message Queue eXecutive)嵌入式實時操作系統(tǒng)的輕量級版本,專門針對ARM Cortex-M系列中資源有限的MCU開發(fā),目前僅支持M0+/M4內(nèi)核的MCU,具有內(nèi)核精簡、資源占用低(低于4K RAM)、執(zhí)行效率高等特點[1]。
目前的MQXLite集成在飛思卡爾公司的圖形化快速程序設(shè)計工具——處理器專家(Processor Expert,PE)里,作為其中的一個組件提供,使用獨立的PE軟件套件或是集成了PE的開發(fā)環(huán)境(CodeWarrior或Kinetis Design Studio)可以方便地構(gòu)建一個基于MQXLite的工程,實現(xiàn)MQXLite在PE支持芯片上的移植。但此種移植方式過度依賴于PE軟件,移植的通用性與靈活性不足,不利于工程在PE不支持的芯片平臺上移植。
針對此缺陷,本文對PE中生成的MQXLite代碼進行了整理與修改,提出了一種改良版的MQXLite組織架構(gòu),使得其脫離PE可獨立配置,并利用此架構(gòu)構(gòu)建了一個通用的工程框架模板“AMQXLITEFW”。在此框架下,分別實現(xiàn)了MQXLite在M0+內(nèi)核的飛思卡爾KW01芯片及M4內(nèi)核的德州儀器CC3200芯片上的移植,拓展了MQXLite的適用平臺。
1 移植研究
1.1 MQXLite的組織架構(gòu)
通過分析MQXLite源碼包的構(gòu)成,并與PE中生成的完整MQXLite工程代碼相比較,可以得出PE下MQXLite組織架構(gòu)的各部分組成如下:
KERNEL:MQXLite的微內(nèi)核,是標(biāo)準(zhǔn)版MQX內(nèi)核的精簡。具有基于優(yōu)先級的搶占式任務(wù)調(diào)度、中斷處理及任務(wù)間的同步與通信(輕量級)等核心功能。
PSP:處理器支持包(Processor Support Package,PSP),包含了MQXLite操作系統(tǒng)的上下文切換、中斷控制等與芯片內(nèi)核密切相關(guān)的功能。
LDD:PE中提供的邏輯設(shè)備驅(qū)動(Logic Device Drivers,LDD),用來實現(xiàn)對外設(shè)I/O的訪問。
BSP:板級支持包(Board Support Package,BSP),包含與具體芯片及電路板相關(guān)的時鐘、中斷初始化等內(nèi)容,通過圖形化的參數(shù)配置后,由PE自動生成。
TASK:應(yīng)用任務(wù),用于實現(xiàn)具體的應(yīng)用功能。
在此架構(gòu)中,KERNEL及PSP的代碼都源于MQXLite的源碼包,其中KERNEL部分是通用代碼,而PSP中穿插有部分LDD及PE生成代碼;LDD及BSP部分的代碼則完全是通過配置PE自動生成,因不同的目標(biāo)芯片及實際電路板的具體情況而異;TASK中的應(yīng)用任務(wù)代碼根據(jù)實際需求編寫,部分與特定平臺相關(guān)的應(yīng)用任務(wù)也會調(diào)用PE生成的LDD代碼。
由此可見,此架構(gòu)下的MQXLite與PE被緊密地捆綁在了一起。利用此架構(gòu),雖然可以在PE的幫助下快速便捷地完成MQXLite在部分目標(biāo)芯片上的移植,但若想將MQXLite移植到PE不支持的芯片平臺上,實現(xiàn)起來較為困難。
可行的解決方案是設(shè)法將MQXLite從PE中獨立出來,使其能夠脫離PE單獨配置,并根據(jù)目標(biāo)芯片選用第三方的驅(qū)動程序來訪問外設(shè)I/O,這樣就增強了MQXLite的移植靈活性與通用性,拓展了MQXLite的適用芯片平臺?;谝陨纤枷?,本文對此架構(gòu)中的組成內(nèi)容進行了適當(dāng)?shù)男薷模岢隽艘环N改良版的MQXLite組織架構(gòu),架構(gòu)中各組成部分如下:
KERNEL:使用MQXLite源碼包中提供的KERNEL代碼。
PSP:使用MQXLite源碼包中提供的PSP代碼,用自行編寫的通用代碼替換PE生成代碼。
DRIVER:使用第三方驅(qū)動而不是PE中的LDD來實現(xiàn)對外設(shè)I/O的訪問。
BSP:自行編寫通用的時鐘、中斷初始化函數(shù),并利用宏常量的方式傳遞參數(shù),方便根據(jù)具體芯片及電路板的情況來進行配置修改。
TASK:保留應(yīng)用任務(wù)代碼不變,只在調(diào)用到外設(shè)I/O驅(qū)動時將LDD驅(qū)動替換為Driver中的第三方驅(qū)動程序。
兩種組織架構(gòu)的對比如圖1所示。相比PE下的MQXLite組織架構(gòu),此改良版的架構(gòu)有獨立、通用、靈活的特點。
1.2 通用的工程框架模板
為了供移植時參考,本文結(jié)合上文提出的改良版MQXLite組織架構(gòu)與本實驗室提出的基于標(biāo)準(zhǔn)版MQX的工程框架“AMQXFW”,提出了一個面向MQXLite的通用工程框架模板“AMQXLiteFW”,其在Kinetis Design Studio 3.0(KDS 3.0)集成開發(fā)環(huán)境下的工程組成如圖2所示[2]。
工程框架中的MQXLite文件夾存放操作系統(tǒng)的相關(guān)文件,包含6個子文件夾:app、bsp、psp、kernel、include及config。其中app對應(yīng)組織架構(gòu)中的“TASK”,bsp即架構(gòu)中的“BSP”,include、kernel及psp共同組成了“KERNEL”及“PSP”;config則存放了MQXLite的配置文件,用于MQXLite內(nèi)核功能的裁剪。
該工程框架模板組織結(jié)構(gòu)清晰,內(nèi)容簡單明了,便于工程的移植。
2 移植實現(xiàn)
利用上文提出的AMQXLiteFW通用工程框架模板及相應(yīng)的第三方驅(qū)動程序,可以方便地實現(xiàn)MQXLite在任何ARM Cortex-M0+/M4內(nèi)核芯片上的移植。下面從啟動流程、中斷系統(tǒng)、系統(tǒng)定時器及應(yīng)用任務(wù)這幾個方面介紹移植的過程。
2.1 啟動流程
使用MQXLite的工程需要一個新的復(fù)位向量函數(shù)Reset_Handler(),以便于在通用的初始化操作之前完成一些與操作系統(tǒng)相關(guān)的額外設(shè)置。此函數(shù)用匯編語言編寫,位于boot.S文件中,主要實現(xiàn)如下功能:
(1)重置外設(shè)中斷狀態(tài)。通過對NVIC相關(guān)寄存器的操作來關(guān)閉所有外設(shè)中斷并清除所有掛起中斷標(biāo)志。其中由于M0+內(nèi)核與M4內(nèi)核所支持的最大外設(shè)中斷數(shù)目不同(M0+:32,M4:240),所以在移植時可根據(jù)目標(biāo)MCU的類型宏定義來條件編譯不同的代碼。
(2)切換棧指針。芯片復(fù)位后默認(rèn)使用主棧指針(Main Stack Pointer,MSP),而操作系統(tǒng)在運行應(yīng)用任務(wù)時使用進程棧指針(Process Stack Pointer,PSP),只有在進入異?;蛑袛鄷r才使用MSP。所以在復(fù)位向量函數(shù)中需要將CONTROL寄存器的第1位置1,實現(xiàn)從MSP到PSP的切換。此部分M0+內(nèi)核與M4內(nèi)核一致,無需修改。
(3)FPU相關(guān)設(shè)置。若目標(biāo)芯片為M4內(nèi)核且具有浮點運算單元FPU并決定在MQXLite中使用,則對系統(tǒng)控制塊SCB的CPACR及FPCCR寄存器進行設(shè)置,開啟芯片的FPU協(xié)處理器,并關(guān)閉硬件在進入異常時對FPU相關(guān)寄存器的自動壓棧操作。
結(jié)束以上操作后,跳轉(zhuǎn)到無操作系統(tǒng)下的通用啟動流程,然后進入應(yīng)用主函數(shù)main(),在其中調(diào)用_mqxlite_
init()及_mqxlite()函數(shù)來初始化并啟動MQXLite操作系統(tǒng)。
2.2 中斷系統(tǒng)
MQXLite的中斷處理過程分為兩個相對獨立的部分:內(nèi)核ISR與用戶ISR。內(nèi)核ISR函數(shù)_int_kernel_isr用匯編語言編寫,以便能快速的響應(yīng)中斷,它完成PSP與MSP之間的切換與上下文的保存,實現(xiàn)硬件中斷到用戶ISR的映射;用戶ISR則通常用C語言編寫,與無操作系統(tǒng)下的中斷服務(wù)例程一致,用于處理各種中斷事件[3]。
鑒于這種情況,MQXLite在維護ROM中的硬件中斷向量表之外,還維護了一個存儲在RAM中的用戶中斷向量表。在移植時,需要將硬件中斷向量表中的系統(tǒng)定時器中斷向量及所有外設(shè)中斷向量都預(yù)設(shè)為內(nèi)核ISR函數(shù),以作為它們的通用入口,接著在應(yīng)用任務(wù)中調(diào)用_int_install_isr()函數(shù)將對應(yīng)外設(shè)的用戶ISR注冊到用戶中斷向量表中。這樣當(dāng)中斷到來時,首先會進入內(nèi)核ISR,然后再查找用戶中斷向量表,轉(zhuǎn)到相應(yīng)的用戶ISR,實現(xiàn)外設(shè)硬件中斷到用戶編寫的中斷服務(wù)例程之間的映射。整個中斷處理流程如圖3所示。
內(nèi)核ISR與處理器所用內(nèi)核有關(guān),位于dispatch.S文件中。此文件可直接從MQXLite源碼包中獲取,并已針對M0+內(nèi)核及M4內(nèi)核提供了不同版本,移植時根據(jù)需要進行替換即可。用戶ISR在移植時可保持與無操作系統(tǒng)下的外設(shè)ISR代碼基本一致。
2.3 系統(tǒng)定時器
MQXLite使用Cortex-M內(nèi)核中共有的Systick定時器作為系統(tǒng)定時器,為操作系統(tǒng)提供系統(tǒng)節(jié)拍,用于任務(wù)的調(diào)度,其初始化代碼調(diào)用了PE中的LDD驅(qū)動。為了擺脫PE,在AMQXLiteFW框架中使用了自行編寫的更為簡單通用的systick_init()函數(shù)來代替LDD驅(qū)動實現(xiàn)Systick定時器的初始化,然后調(diào)用_int_install_isr()函數(shù)將MQXLite內(nèi)核中的滴答處理例程_time_notify_kernel()注冊到Systick的中斷向量中,實現(xiàn)MQXLite操作系統(tǒng)與Systick定時器的關(guān)聯(lián)。在移植時只需根據(jù)具體應(yīng)用需求,修改bsp.h頭文件中宏定義BSP_ALARM_FREQUENCY的值(單位:Hz),即可改變系統(tǒng)定時器的節(jié)拍頻率。
2.4 應(yīng)用任務(wù)
MQXLite不支持動態(tài)任務(wù)創(chuàng)建,所以需要在編譯時靜態(tài)地為所有任務(wù)預(yù)先分配好任務(wù)棧空間,并在任務(wù)模板列表MQX_template_list中登記任務(wù)的相關(guān)屬性。
MQXLite只支持基于優(yōu)先級的搶占式先入先出任務(wù)調(diào)度方式。為了觸發(fā)任務(wù),在此框架中會固定地創(chuàng)建自啟動任務(wù)task_main,用于外設(shè)硬件模塊初始化及其他任務(wù)的創(chuàng)建。此任務(wù)執(zhí)行完后會自我阻塞,操作系統(tǒng)開始根據(jù)優(yōu)先級的高低對就緒隊列中的任務(wù)進行調(diào)度[4]。
在移植應(yīng)用任務(wù)時,為了協(xié)調(diào)任務(wù)間的執(zhí)行順序,既可以使用輕量級的事件、信號量、消息隊列等任務(wù)同步組件函數(shù),也可以在任務(wù)循環(huán)體最后調(diào)用_time_delay_
ticks()等延時函數(shù)來主動放棄CPU的占用權(quán)[5]。
3 移植測試
為了檢驗提出的AMQXLiteFW框架及移植流程的通用性與有效性,本文在KW01及CC3200這兩款不同內(nèi)核、不同廠商的MCU上進行了MQXLite的移植測試。
3.1 KW01移植測試
KW01為飛思卡爾公司推出的基于ARM Cortex-M0+內(nèi)核的Sub-GHz無線MCU,可工作在290~1 020 MHz的無線頻率范圍內(nèi),最高主頻48 MHz,擁有128 KB的ROM及16 KB的SRAM。由于在PE V3.0.0之前并不支持這款芯片,所以利用本文提出的框架及本實驗室自行編寫的KW01外設(shè)驅(qū)動程序來構(gòu)建MQXLite移植測試工程。
測試工程程序分為兩個部分:發(fā)送節(jié)點程序與接收節(jié)點程序。發(fā)送節(jié)點程序通過ADC內(nèi)部通道采集芯片溫度及電源電壓等信息,在收到問詢幀后回發(fā)相關(guān)數(shù)據(jù)。接收節(jié)點程序?qū)拇诮邮盏降腜C端命令進行無線轉(zhuǎn)發(fā),并將收到的無線數(shù)據(jù)通過串口上傳到PC端。
移植完成后在KDS 3.0開發(fā)環(huán)境里編譯工程并下載到測試節(jié)點中進行測試,PC端軟件運行結(jié)果可看出使用MQXLite的芯片運行正常,實現(xiàn)了目標(biāo)功能。
3.2 CC3200移植測試
CC3200是德州儀器公司推出的基于ARM Cortex-M4內(nèi)核的WiFi無線MCU,支持Wi-Fi 802.11 b/g/n及TCP/IP協(xié)議棧,主頻80 MHz,最高擁有256 KB的SRAM。此芯片的生產(chǎn)廠商并非飛思卡爾公司,故PE對其并不支持,測試工程利用本文提出的框架及德州儀器公司提供的外設(shè)驅(qū)動程序,嘗試將MQXLite操作系統(tǒng)移植到此芯片中。
測試程序?qū)C3200配置為AP模式,與存儲在外部Flash中的網(wǎng)頁進行交互,根據(jù)網(wǎng)頁上傳來的信息控制測試板上指示燈的亮滅,并從串口輸出網(wǎng)頁上發(fā)送過來的字符串信息。
移植完成后在IAR 7.2 IDE里編譯工程并下載到測試板,PC或手機連接到CC3200的WiFi熱點,通過瀏覽器訪問內(nèi)置網(wǎng)頁進行通信與控制測試,測試結(jié)果與預(yù)期目標(biāo)一致,說明MQXLite移植成功。
4 總結(jié)
移植測試的結(jié)果驗證了本文提出的AMQXLiteFW框架的可移植性與通用性。此框架使得MQXLite可以脫離PE移植到任何廠商的ARM Cortex-M0+/M4芯片上,為MQXLite在不同平臺上的移植提供了借鑒。此外,為了進一步提高此框架的通用性,還可以繼續(xù)研究修改MQXLite的相關(guān)代碼,使其兼容ARM Cortex微控制器軟件接口標(biāo)準(zhǔn)(CMSIS),并統(tǒng)一外設(shè)驅(qū)動的接口,使得工程更便于移植。
參考文獻
[1] Freesca1e Semiconductor.MQXLite Real-Time Operating System User Guide. Rev 1.1[EB/OL].(2014-4-2).http://cache.freescale.com/files/soft_dev_tools/doc/user_guide/MQXLITEUG.pdf.
[2] 王宜懷,朱仕浪,姚望舒.嵌入式實時操作系統(tǒng)MQX應(yīng)用開發(fā)技術(shù)-ARM Cortex-M微處理器[M].北京:電子工業(yè)出版社,2014.
[3] 石晶,王宜懷,蘇勇,等.基于ARM Cortex-M4的MQX中斷機制分析與中斷程序框架設(shè)計[J].計算機科學(xué),2013,40(6):41-44.
[4] ZHAO T,LONG D.Analysis on task scheduling operating mechanism of embedded real-time operating system MQX[C].Mechatronic Sciences, Electric Engineering and Computer(MEC),Proceedings 2013 International Conference on.IEEE,2013:1844-1847.
[5] 周航慈,吳光文.基于嵌入式實時操作系統(tǒng)的程序設(shè)計技術(shù)[M].北京:北京航空航天大學(xué)出版社,2006.