劉長勇,王宜懷,彭 濤,孫亞軍,程宏玉
1(武夷學(xué)院 數(shù)學(xué)與計算機學(xué)院,武夷山 354300)
2(蘇州大學(xué) 計算機科學(xué)與技術(shù)學(xué)院,蘇州 215006)
3(認知計算與智能信息處理福建省高校重點實驗室,武夷山 354300)
實時操作系統(tǒng)(Real-Time Operating System,RTOS)的運用不僅能夠更有效、更合理的利用現(xiàn)有的CPU 資源,而且能夠簡化應(yīng)用軟件的設(shè)計,縮短應(yīng)用的開發(fā)時間、降低開發(fā)費用[1],保證系統(tǒng)的可靠性和實時性,那么如何實現(xiàn)RTOS 在不同的內(nèi)核、微控制器(Micro Controller Unit,MCU)、開發(fā)環(huán)境等方面的移植,一直是工程技術(shù)界研究的共性技術(shù).
目前在RTOS 的移植上已經(jīng)有了一些研究,也提出相應(yīng)的移植解決方法.如常華利等[2]提出了一種基于MicroBlaze 軟核處理器的μC/OS-II 的移植方案;唐小平[3]在深入分析μC/CPU 移植文件編寫與修改的細節(jié)的基礎(chǔ)上,給出了基于STM32F103RC 產(chǎn)品平臺下的μC/OS-Ⅲ成功移植案例;候海霞[4]對Free RTOS 操作系統(tǒng)和LwIP 協(xié)議棧進行了深入的研究,在STM32F407芯片上實現(xiàn)了Free RTOS 與LwIP 協(xié)議棧的移植;羅名駒[5]研究了如何移植引入設(shè)備樹的U-boot 和Linux內(nèi)核到Samsung Exynos4412 芯片上的關(guān)鍵技術(shù).但是,這些移植解決方案僅停留在解決如何將RTOS 移植到某一特定的MCU 上,而對不同的內(nèi)核、MCU、開發(fā)環(huán)境等的移植情況鮮有研究.同時,有關(guān)mbedOS 的研究主要集中在通信技術(shù)和安全訪問服務(wù)機制[6]、協(xié)議棧和IP 網(wǎng)絡(luò)組件[7]、物聯(lián)網(wǎng)設(shè)備平臺[8,9]等方面.
2014年ARM 公司推出了mbedOS,它是一種專為物聯(lián)網(wǎng) (IoT)中的“物體”設(shè)計的開源嵌入式實時操作系統(tǒng)[10],具有任務(wù)管理與調(diào)度、時間管理、中斷處理、內(nèi)存管理、同步與通信等基本功能,對外提供統(tǒng)一的底層驅(qū)動接口,能滿足多任務(wù)的運行,具有較高的實時性.本文在深入剖析mbedOS 的基本功能和實時性要求上,根據(jù)嵌入式軟件工程的基本思想,以可擴充、可移植的mbedOS 工程框架為基礎(chǔ),分析了移植的共性問題和注意事項,給出了具體的移植方法,解決了mbedOS 在不同的內(nèi)核、MCU、開發(fā)環(huán)境等上的移植關(guān)鍵技術(shù)問題,為mbedOS 的應(yīng)用研究提供了基礎(chǔ),為mbedOS 的移植提供了一條簡捷、有效的路徑.
這里對基于MKL36Z64VLH4(簡稱KL36)微控制器的無操作系統(tǒng)工程框架SD-NOS 和可移植的SDmbedOS 工程框架的構(gòu)建方法做個簡要的概述.
首先,根據(jù)無操作系統(tǒng)軟件最小系統(tǒng)的含義,建立包括說明文檔、內(nèi)核相關(guān)文件、微控制器相關(guān)文件、用戶板構(gòu)件、軟件構(gòu)件、中斷服務(wù)程序和無操作系統(tǒng)主程序等嵌入式系統(tǒng)工程最基本要素的無操作系統(tǒng)工程框架SD-NOS.該工程框架能夠滿足點亮一盞發(fā)光二極管的最基本要求,甚至帶有串口調(diào)試構(gòu)件.
其次,提出了RTOS 軟件最小系統(tǒng)的含義,它是將任務(wù)管理、調(diào)度管理、內(nèi)存管理、中斷管理、時間管理以及同步與通信等RTOS 最基本功能要素,以構(gòu)件的形式添加到無操作系統(tǒng)軟件最小系統(tǒng)上,構(gòu)成能至少實現(xiàn)對兩個任務(wù)進行調(diào)度的工程框架.
最后,按照“分門別類、各有歸處”原則,對工程框架的文件夾和共性文件進行歸納分類,以編號的形式建立相應(yīng)的文件夾存放源程序和頭文件,基于KL36微控制器,構(gòu)建了可移植的SD-mbedOS 工程框架.表1給出了利用SD-mbedOS 工程框架在采用ARM Cortex-M 處理器的MCU 上進行移植時,需要替換、修改或添加的內(nèi)容,對不需要改動的內(nèi)容直接進行復(fù)制,其中底層構(gòu)件僅包含最基本的通用輸入輸出gpio 構(gòu)件和串口通信uart 構(gòu)件.
表1 基于SD-mbedOS 工程框架的移植說明
移植必然涉及文件覆蓋與改動,也涉及到開發(fā)環(huán)境、編譯器、內(nèi)核等共性問題,下面給出簡要分析.
SD-mbedOS 工程框架是基于ARM Cortex-M0+內(nèi)核的KL36 微控制器進行構(gòu)建的,當(dāng)采用該框架在ARM 內(nèi)核的MCU 上進行mbedOS 移植時,會涉及到不同內(nèi)核、不同MCU、不同開發(fā)環(huán)境等因素,其共性問題分析如下:
(1)mbedOS 文件的添加
由于要將mbedOS 移植到特定MCU 的嵌入式系統(tǒng)工程中,因此需將SD-mbedOS 工程框架下的02_Core 和07_mbedOS 文件夾內(nèi)容添加到指定的工程中.
(2)MCU 相關(guān)文件的替換
不同的MCU,其內(nèi)核、異常處理程序、鏈接文件、MCU 頭文件、MCU 啟動文件、底層硬件驅(qū)動構(gòu)件、應(yīng)用構(gòu)件都有所不同.因此,需要根據(jù)實際采用的MCU 和應(yīng)用需求,替換這些文件.若采用的MCU 為KL36,則不需進行替換.
(3)內(nèi)核與MCU 相關(guān)文件的修改
不同MCU,其RAM 的起始地址和大小是不一樣的,中斷向量的個數(shù)也不相同,堆棧指針的棧底地址也不同.因此,需要對這些內(nèi)容進行重新設(shè)置,以符合特定MCU 的要求.若采用的MCU 為KL36,則不需進行修改.
(4)頭文件的設(shè)置
由于MCU 發(fā)生了改變,需要將CMSIS 編譯器、內(nèi)核頭文件以及MCU 頭文件加入到相關(guān)的文件中,這樣在編譯時才能找到指定的文件.
本文涉及到的MCU 雖然內(nèi)核不相同、所采用的開發(fā)環(huán)境也不一樣,但都屬于ARM Cortex-M 處理器范疇,都遵循微控制器軟件接口標準(Cortex Microcontroller Software Interface Standard,CMSIS).mbedOS 是由ARM 公司開發(fā),其內(nèi)核程序也遵循CMSIS,且采用C++語言和匯編語言混合編程,這就要求開發(fā)環(huán)境集成的編譯器不僅能處理C++語句,而且還能編譯匯編語言指令,故一般都采用GCC(GNU Compiler Collection,GNU 編譯器套件)編譯器.因此,當(dāng)在不同MCU 上進行mbedOS 移植時,必須分析開發(fā)環(huán)境、編譯器和內(nèi)核等方面的設(shè)置和使用問題.
(1)與開發(fā)環(huán)境相關(guān)問題分析.由于開發(fā)環(huán)境不相同,會出現(xiàn)有些宏、數(shù)據(jù)類型、函數(shù)調(diào)用、靜態(tài)內(nèi)聯(lián)函數(shù)等未定義情況,一方面是要在工程屬性中設(shè)置各文件夾及其子文件夾的路徑,另一方面則需要在相關(guān)文件中添加宏定義或頭文件.例如,在MSP432 開發(fā)環(huán)境中,需要在cmsis.h 中添加“__WEAK”宏定義解決弱定義錯誤、在cmsis_gcc.h 中添加“sys/_stdint.h”解決數(shù)據(jù)類型未定義問題、在鏈接文件中修改heap 段的結(jié)束標志“__end”為“__end__”;在S32K 開發(fā)環(huán)境中,需要在mbed_critical.c 中添加“cmsis_gcc.h”解決__disable_irq 等函數(shù)調(diào)用問題、在os_systick.c 中添加“core_cm4.h”和“system_S32k144.h”解決OS_Tick_Setup 等函數(shù)調(diào)用問題、在rtx_core_cm.h 中添加“core_cm4.h”解決靜態(tài)內(nèi)聯(lián)函數(shù)未定義問題.
(2)與編譯器相關(guān)問題分析.mbedOS 是采用C++和匯編語言混合編程,不僅開發(fā)環(huán)境的編譯器要設(shè)置成能同時處理C++語句和匯編指令,而且有的開發(fā)環(huán)境還要求對.c 的源文件要進行特殊處理,才能滿足其要求.例如,在MSP432 開發(fā)環(huán)境CCS 中,默認編譯器采用“TI V5.2.5”版本,對編譯匯編文件和C++文件支持不足,故建議改為“GNU V7.2.1”,運行支持的類文件選擇“l(fā)ibsupc++.a”,同時添加名為“c”的libc.a 庫文件,這樣才能更好地實現(xiàn)對匯編指令和C++的編譯;在S32K 和MSP432 開發(fā)環(huán)境中,對.c 程序的編譯時會出錯,要進行特殊處理:一方面可以采用直接將其擴展名改為.cpp 的方式,另一方面若該.c 文件同時存在同名的.h 文件時,則可以通過“ifdef __cplusplus”預(yù)處理告之編譯器要以c 的形式處理這些文件.
(3)與內(nèi)核相關(guān)問題分析.mbedOS 的SVC、PendSV、SysTick 等中斷服務(wù)程序是按照CMSIS 標準采用C++和匯編語言混合編程,對寄存器的使用遵循AAPCS 規(guī)范(ARM Archtecture Procedure Call Standard,ARM 架構(gòu)過程調(diào)用標準).當(dāng)MCU 的內(nèi)核為Cortex-M0+時,采用R7 寄存器保存實際調(diào)用函數(shù)的入口地址;當(dāng)采用Cortex-M4 或M4F 內(nèi)核的MCU 時,則實際調(diào)用函數(shù)的入口地址保存在R12 寄存器中.因此,在編寫匯編程序時,要注意避開這兩個寄存器,改用其他寄存器,以避免程序執(zhí)行時出現(xiàn)無法預(yù)計的情況.
在已有的無操作系統(tǒng)工程的基礎(chǔ)上,要將mbedOS移植到特定的嵌入式系統(tǒng)應(yīng)用開發(fā)中,可以采用以下3 種方法進行移植:第1 種方法是自行分析mbedOS 代碼結(jié)構(gòu),根據(jù)應(yīng)用開發(fā)的實際從中抽取相關(guān)文件加入到工程中,然后在工程進行編譯,修改相關(guān)的錯誤,對mbedOS 的移植有較大難度;第2 種方法是根據(jù)SDmbedOS 工程框架內(nèi)的02_Core 和07_mbedOS 文件夾的內(nèi)容,從mbedOS 代碼中直接抽取這些源文件,加入到工程中,然后進行編譯修改,對mbedOS 的移植有一定難度;第3 種方法是直接利用SD-mbedOS 工程框架,將其中的02_Core 和07_mbedOS 文件夾加入到工程中,根據(jù)工程具體情況只需少量的修改就可以使用,這樣可以少走彎路,更容易一些.下面介紹mbedOS 移植的第3 種方法.
本文分析的是基于KL36[11]的SD-mbedOS 工程框架在S32K144[12]和MSP432[13]等MCU 上的移植方法,這幾款MCU 均為ARM Cortex 處理器,但采用的內(nèi)核、開發(fā)環(huán)境、Flash、RAM、中斷向量數(shù)以及生產(chǎn)廠家等都有所不同,具體對比如表2所示.
表2 不同MCU 的基本情況對比表
當(dāng)采用的MCU 為KL36 時,可以直接使用SDmbedOS 工程框架,只需根據(jù)實際應(yīng)用的功能需求,修改08_mbedOsPrg 文件夾內(nèi)的相關(guān)內(nèi)容即可.當(dāng)采用不同的MCU 時,mbedOS 的移植步驟分析如下:
(1)構(gòu)建無操作系統(tǒng)工程框架.按照SD-NOS 工程框架的結(jié)構(gòu),根據(jù)所采用的MCU(其內(nèi)核文件、鏈接文件和啟動文件等在購買該MCU 時廠家會提供或可從網(wǎng)絡(luò)上下載獲取),使用相應(yīng)的開發(fā)環(huán)境搭建無操作系統(tǒng)工程框架.
(2)復(fù)制mbedOS 文件.由于02_Core 文件夾包含的內(nèi)核頭文件、內(nèi)核函數(shù)訪問頭文件、內(nèi)核指令訪問頭文件以及編譯器頭文件等在mbedOS 中已有且略有不同.因此,先刪除這些文件,然后將SD-mbedOS框架中的02_Core 和07_mbedOS 文件夾的內(nèi)容復(fù)制到無操作系統(tǒng)工程框架中,形成帶操作系統(tǒng)的工程框架.
(3)設(shè)置內(nèi)核與MCU 相關(guān)文件.由于MCU 不同,其中斷向量個數(shù)、中斷向量表在RAM 的起始地址、RAM 的起始地址與大小、堆棧指針等也不一樣,要根據(jù)特定的MCU 進行重新設(shè)置;需要將MCU 的頭文件包含在微控制器軟件接口標準頭文件cmsis.h 和公共頭文件common.h 中;由于中斷向量表要從Flash 復(fù)制到RAM 中,需要在RAM 中預(yù)留出中斷向量數(shù)×4 的字節(jié)數(shù)來,故在鏈接文件中RAM 的起始地址要在原起始地址的基礎(chǔ)上加中斷向量數(shù)×4.具體需要設(shè)置的文件和內(nèi)容如表3所示.
表3 mbedOS 在不同MCU 上移植主要內(nèi)容修改對比表
(4)設(shè)置工程屬性.為了便于在函數(shù)調(diào)用中能找到相關(guān)的文件聲明位置,可以在工程配置文件中添加各個文件夾及子文件夾的路徑,同時添加相關(guān)宏定義,以便在函數(shù)調(diào)用時能找到這些頭文件和宏.
(5)與應(yīng)用開發(fā)相關(guān)的內(nèi)容設(shè)置.在實際的應(yīng)用開發(fā)中,若有新增底層硬件構(gòu)件、應(yīng)用構(gòu)件、軟件構(gòu)件、用戶任務(wù)程序、中斷服務(wù)程序等,需要在總包含頭文件includes.h 中要包含各類構(gòu)件頭文件、用戶函數(shù)聲明和中斷聲明.這一步根據(jù)需要進行設(shè)置,若無增加則不需要進行設(shè)置.
(6)編譯工程.在開發(fā)環(huán)境中對工程進行編譯,檢查并修改錯誤,編譯成功之后下載到開發(fā)板上運行,觀察運行結(jié)果.
通過以上移植步驟,按照表3的修改內(nèi)容以及共性技術(shù)分析的要點,就可以利用KL36 的SD-mbedOS工程框架將mbedOS 移植到以S32K 和MSP432 為MCU 的工程上.由于是針對mbedOS 進行移植測試,因此,在三款MCU 的工程中實現(xiàn)相同的任務(wù)功能,可以將KL36 工程中的藍燈任務(wù)、綠燈任務(wù)和紅燈任務(wù)這3 個任務(wù)程序代碼直接復(fù)制到S32K 和MSP432 工程中進行移植測試.移植測試工程實現(xiàn)藍燈任務(wù)、綠燈任務(wù)和紅燈任務(wù)分別每2 s、每1 s 和每3 s 閃爍1 次,由于篇幅有限,僅給出藍燈任務(wù)的程序代碼,綠燈任務(wù)和紅燈任務(wù)的程序代碼與藍燈任務(wù)的程序代碼基本一樣,只是延時時間不同而已,更加詳細的工程代碼與移植說明可到蘇州大學(xué)嵌入式學(xué)習(xí)社區(qū)網(wǎng)站(網(wǎng)址:http://sumcu.suda.edu.cn)的“教學(xué)培訓(xùn)-教學(xué)資料-mbedOS”位置,下載“The Protability of mbedOS in MCUs_190928”查看.
藍燈任務(wù)代碼:
void run_bluelight(void)
{
while (true){
printf(" ***2-1.藍燈任務(wù)開始.*** ");
light_change(LIGHT_BLUE);//切換藍燈的亮暗
Thread::wait(2000);//延時2 秒
printf(" ***2-2.延時2 秒到切換藍燈亮暗.*** ");
printf(" ***2-3.藍燈任務(wù)結(jié)束.*** ");
}
}
圖1給出了mbedOS 在KL36 上的運行結(jié)果,以及在S32K 和MSP432 上的移植測試結(jié)果,從中可以看出在mbedOS 的調(diào)度下任務(wù)運行正常、程序執(zhí)行邏輯準確,本測試工程涉及到RTOS 的任務(wù)調(diào)度、時間嘀嗒、延時函數(shù)、事件、消息隊列等基本要素,這些要素具有普適意義,程序的正常運行,表明移植成功.
圖1 mbedOS 在多個MCU 的移植測試結(jié)果
實時操作系統(tǒng)mbedOS 具有任務(wù)管理與調(diào)度、時間管理、中斷處理、內(nèi)存管理、同步與通信等基本功能,能提供調(diào)度的實時性、響應(yīng)時間的可確定性、系統(tǒng)高度的可靠性,在物聯(lián)網(wǎng)終端、工業(yè)控制設(shè)備、軍事設(shè)備、航空航天等領(lǐng)域得到廣泛應(yīng)用.本文通過對mbedOS 的基本功能和實時性等方面進行深入剖析,根據(jù)嵌入式軟件工程的基本思想和嵌入式軟件構(gòu)件設(shè)計的基本原則,以可移植、易擴充的SD-mbedOS 工程框架為基礎(chǔ),分析了移植的共性技術(shù)和注意事項,給出了mbedOS 在ARM Cortex-M 系列的不同內(nèi)核、MCU、開發(fā)環(huán)境等的移植解決方案,并完成了移植測試,為廣大嵌入式系統(tǒng)開發(fā)者在mbedOS 移植上少走彎路,提供了簡潔、方便的路徑,也可為其他RTOS 的移植提供參考.后續(xù)將針對mbedOS 的啟動、系統(tǒng)服務(wù)調(diào)用、任務(wù)調(diào)度等做進一下的研究探討.