張建 王宜懷
?
基于ARM CortexTM-M4的MQX-RTOS啟動流程剖析*
張建1,2王宜懷1,2
(1.蘇州大學計算機科學與技術學院 2.軟件新技術與產業化協同創新中心)
結合ARM Cortex-M4的地址映射、工程鏈接文件intflash.ld分析Kinetis MK60DN512ZVLQ10芯片的地址空間的分配情況,剖析芯片從加電復位跳轉到駐留在ROM開始地址的中斷向量表處執行,依次完成系統堆棧指針、進程堆棧指針、切換堆棧指針等設置,最后調用MQX初始化函數完成MQX-RTOS的啟動,在對啟動過程的代碼進行合理裁剪的基礎上,給出較詳細的注釋,為研究其他RTOS的啟動提供一定的借鑒。
MQX系統;RTOS;ARM Cortex-M4芯片;啟動流程
MQX(message queue executive)是一種廣泛應用于工業控制、醫療電子、家用電器等領域的嵌入式實時操作系統(embedded real time operation system,RTOS),相對其他的嵌入式實時操作系統,其內核精簡、實時性較高,具有技術支持、開發工具成熟、外設驅動豐富等特點而備受開發人員歡迎。RTOS的啟動過程具有復雜性高和啟動時間短的特點,深入剖析MQX-RTOS的啟動流程,對提高軟件開發、編寫高效的軟件代碼有很大的幫助[1]。
以蘇州大學飛思卡爾嵌入式實驗中心發布的AMQXFW工程框架,結合ARM Cortex-M4的地址映射、工程鏈接文件intflash.ld分析Kinetis MK60DN512ZVLQ10芯片地址空間的分配情況[2]。剖析芯片從加電復位跳轉到駐留在ROM開始地址(地址為0x0000_0000)的中斷向量表處執行,依次設置系統堆棧指針、進程堆棧指針、切換堆棧指針、關看門狗、端口時鐘門控、系統時鐘、初始化全局變量,調用MQX初始化函數完成MQX-RTOS啟動的復雜過程,對啟動過程的代碼進行合理的裁剪并給出剖析的注釋,可深入理解MQX-RTOS的啟動過程[3]。
存儲器空間地址映像是芯片的“地圖”,規定了芯片上所有設備的地址范圍,不同芯片組的存儲器空間地址映像也不相同。ARM Cortex-M4的K60系列的存儲器空間地址映像對照如表1所示,MK60DN512ZVLQ10芯片沒有FlexNVM和FlexRAM,其存儲器空間地址映像對照如表2所示。

表1 K60系列芯片的存儲器空間地址映像

表2 MK60DN512ZVLQ10芯片的存儲器空間地址映像
ARM Cortex-M4的K60系列ROM地址范圍為0x0000_0000~0x0FFF_FFFF,共計256MB的ROM區域,該區域主要存放中斷向量表、操作系統代碼和常量等內容。Kinetis MK60DN512ZVLQ10芯片只配置512 kB的Flash,其地址只使用了起始的512 kB地址空間,即0x0000_0000~0x0008_0000,該區域主要存放中斷向量表、Flash模塊配置信息、MQX-RTOS操作系統代碼和常量等內容。K60系列的RAM地址范圍為0x1800_0000~0x200F_FFFF,共計129 MB的RAM區域,主要存放運行時的中斷向量表、支持操作系統運行的代碼、常變量、靜態變量、全局變量和堆棧等內容。Kinetis MK60DN512ZVLQ10芯片只配置了128 kB的SRAM,其地址只使用了SRAM_L末尾的64 kB和SRAM_U起始的64 kB空間,地址范圍為0x1FFF_0000~0x0x2000_FFFF[4]。
Flash和SRAM存儲空間的分配,在AMQXFW工程的鏈接文件intflash.ld中定義如下:
MEMORY
{
/* 異常中斷向量表 */
vectorrom (RX): ORIGIN = 0x00000000, LENGTH = 0x00000400
/* Flash模塊配置 */
cfmprotrom (R): ORIGIN = 0x00000400, LENGTH = 0x00000020
/* 代碼和常量 */
rom (RX): ORIGIN = 0x00000420, LENGTH = 0x0007FBE0
/* SRAM */
ram (RW): ORIGIN = 0x1FFF0000, LENGTH = 0x00020000
/* 內核數據區結束處 */
end_of_kd (RW): ORIGIN = 0x2000FFF0, LENGTH = 0x00000000
/* 啟動堆棧 */
bstack (RW): ORIGIN = 0x2000FA00, LENGTH = 0x00000200
/* 啟動堆棧結束處 */
end_bstack (RW): ORIGIN = 0x2000FC00, LENGTH = 0x00000000
}
由intflash.ld文件的定義,MK60DN512ZVLQ10的ROM、RAM的地址映射分別如圖1和圖2所示;512 kB的ROM主要分為1 kB的中斷向量表+32 B的Flash配置+(511 kB-32 B)的代碼和常量區,其中1 kB的中斷向量共包含256個中斷項,每個中斷占4個字節[5]。

圖1 MK60DN512ZVLQ10 ROM地址空間映射

圖2 MK60DN512ZVLQ10 RAM地址空間映射
128 kB的RAM由編譯器根據MQX系統預定義的常量進行有條件地編譯使用。一般來說,RAM主要有中斷向量表、數據段、BSS段和內核數據等,其中內核數據區約從0x1FFF_0330開始,到0x2000_ FFFF結束,約為127 kB,不同的工程編譯出來的內核數據區大小也不盡相同。
MK60DN512ZVLQ10芯片的啟動可分為芯片啟動和MQX-RTOS系統啟動2個階段,啟動流程如圖3所示。
MK60DN512ZVLQ10芯片加電復位跳轉到駐留在ROM開始地址的中斷向量表處執行,依次設置系統堆棧指針、進程堆棧指針、切換堆棧指針、關看門狗、端口時鐘門控、系統時鐘、初始化全局變量[6]。

圖3 MQX-RTOS啟動流程
2.1引導
芯片上電,ARM Cortex-M4處理器架構的芯片將寄存器清0,同時自動執行0x0000_0000地址處的指令。對存儲映射區域進行解析,位于0x0000_0000為ROM區域的中斷向量表內容。引導程序從中斷向量表中取第一個表項(地址為:0x0000_0000)的內容作為系統棧指針,即主堆棧指針(main stack pointer,MSP);從中斷向量表中取第二個表項(地址為:0x0000_0004)的內容作為系統啟動函數的地址,并放入程序計數器(Program Counter,PC)中,接著進入執行PC指向處的指令,進入__boot函數的執行。ROM起始的1 kB放置的256個中斷,每個中斷占4個字節,以下代碼為前2個中斷[7]。
/* 第1個中斷項
* 中斷系統棧指針,值在intflash.ld文件中定義,其值和end_bstack相同
* end_bstack=0x2000_FC00*/
(vector_entry)__BOOT_STACK_ADDRESS,
/* 第2個中斷項
* 啟動函數指針宏定義為__boot
* __boot為boot.s中的標號 */
BOOT_START,
...
2.2__boot啟動
__boot啟動代碼在boot.s文件中,采用匯編語言編寫加快啟動速度。__boot主要設置了啟動過程中禁中斷、切換堆棧,并跳轉到startup.c的__thumb_startup處運行。__boot代碼如下。
__boot:
// 禁中斷清除掛起標志
ldr r0, =NVIC_ICER0
ldr r1, =NVIC_ICPR0
ldr r2, =0xFFFFFFFF
mov r3, #8
// 循環設置8個禁中斷清除掛起標志寄存器
_boot_loop:
cbz r3, _boot_loop_end
str r2, [r0], #4 /* NVIC_ICERx - 清除IRQ使能 */
str r2, [r1], #4 /* NVIC_ICPRx - 清除掛起IRQ標志 */
sub r3, r3, #1
b _boot_loop
_boot_loop_end:
// 用主堆棧指針值設置進程堆棧指針的值
mrs r0, MSP
msr PSP, r0
// 切換到PSP CONTROL[1]為1使用PSP 為0使用MSP
mrs r0, CONTROL
orr r0, r0, #2
msr CONTROL, r0
isb #15
// 跳轉到startup.c的__thumb_startup處執行
.extern __thumb_startup
b __thumb_startup
2.3__thumb_startup函數
__thumb_startup函數在startup.c文件中,主要完成看門狗、端口時鐘門控、系統時鐘等設置,初始化全局變量,調用main函數,進入main函數運行。__thumb_startup函數代碼如下:
//設置看門狗
wdog_disable1();
//設置端口時鐘門控
gpio_io_init();
//初始化全局變量
zero_fill_bss();
//拷貝ROM至RAM,本文件中SUPPORT_ROM_TO_RAM定義為1
#if SUPPORT_ROM_TO_RAM
if (__S_romp != 0L)/* __S_romp 在intflash.ld中定義 */
__copy_rom_sections_to_ram();
#endif
//設置系統時鐘
SystemClockSetup(ClockSource_EX50M,CoreClock_96M);
//進入主程序Main
exit(main(0, argv));
MQX-RTOS系統啟動階段主要是通過main函數調用_mqx函數完成MQX-RTOS系統的啟動。
3.1 main函數
main函數在main.c文件中,主要根據定義的MQX初始化常量調用_mqx函數完成MQX-RTOS系統的啟動。main函數代碼如下:
//MQX初始化結構體常量MQX_init_struct,在mqx_init.c文件中賦值
extern const MQX_INITIALIZATION_STRUCT MQX_init_struct;
//調用_mqx,啟動MQX-RTOS系統
_mqx( (MQX_INITIALIZATION_STRUCT_PTR) &MQX_init_struct );[8]
3.2_mqx函數
_mqx函數主要完成MQX-RTOS系統的啟動,具體步驟如下:
1) 初始化內核數據區
內核數據區是負責記錄MQX系統運行狀態及資源使用情況的存儲區,在開始正常工作之前,要為內核數據區指定合適的初始值。
初始化內核數據區依次執行:創建內核數據區訪問指針→填充內核數據區→啟動對中斷的支持→創建系統空閑任務棧→創建就緒任務隊列數組→創建任務操作信號量。
2) 初始化外設
MQX操作系統的運行需要硬件平臺的支持,因此在系統啟動過程中,需對硬件平臺進行初始化設定。
初始化外設依次執行:初始化MQX中斷系統→初始化系統時間滴答→初始化IO子系統。
3) 調度系統初始化與啟動
啟動調度系統是MQX啟動過程的最后一個環節,成功啟動調度系統后,整個系統中包含的應用任務將在調度系統的管理下有序地運行。
調度系統初始化與啟動依次執行:設置缺省使用的時間片→創建并啟動空閑任務→創建自啟動應用任務→啟動調度系統。
啟動調度系統成功后,標志著RTOS系統成功啟動,用戶開發的程序可通過調度系統來運行。
MQX-RTOS系統啟動過程包括芯片啟動和MQX系統啟動2個階段。MQX-RTOS系統成功啟動調度系統后,由調度系統合理有序地調度各個任務、中斷運行。本文主要結合蘇州大學飛思卡爾嵌入式實驗中心發布的AMQXFW工程框架進行深入剖析,對主要的啟動代碼進行分析,為從事RTOS系統的啟動研究提供了研究基礎,同時為基于MQX系統應用程序開發提供一定的借鑒。
[1] 王宜懷,朱仕浪,姚望舒.嵌入式實時操作系統MQX應用開發技術—ARM Cortex-M微處理器[M].北京:電子工業出版社,2014.
[2] 朱仕浪,王宜懷,馮德旺.MQX實時操作系統構件化工程框架研究[J].武漢理工大學學報,2013,35(10):135-140.
[3] 蔣建武,王宜懷.基于ARM Cortex-M4的MQX中斷機制深度剖析[J].電子技術與軟件工程,2014(22):214-217,233.
[4] Freescale. MQX User Guide Rev.12[M]. 2014.
[5] 王宜懷,吳瑾,蔣銀珍.嵌入式系統原理與實踐——ARM Cortex-M4 Kinetis微控制器[M].北京:電子工業出版社, 2012.3.
[6] Freescale.K60 Sub-Family Reference Manual Rev.6[M]. 2011.
[7] Freescale. Freescale MQX RTOS Reference Manual Rev.16 [M]. 2014.
[8] Freescale. Cortex-MTM System Design Kit Technical Reference Manual Revision r0p0[M]. 2011.
[9] Giovani Gracioli, Sebastian Fischmeister. Tracing and recording interrupts in embedded software[J]. Journal of Systems Architecture,2012,58(9): 372-385.
[10] 董榮勝,古天龍.計算機科學與技術方法論[M].北京:人民郵電出版社,2002.
[11] Enkhbaatar Tumenjargal, Luubaatar Badarch, Hyeokjae Kwon, et al. Embedded software and hardware implementation system for a human machine interface based on ISOAgLib[J]. Journal of Zhejiang University-Science C (Computers & Electronics), 2013,14(3):155-166.
The Analysis of Starting Process of MQX-RTOS Based on ARM CortexTM-M4
Zhang Jian1,2Wang Yihuai1,2
(1.School of Computer Science & Technology, Soochow University, Suzhou 2.Collaborative Innovation Center of Novel Software Technology and Industrialization)
Based on ARM Cortex-M4’s address mapping and the project link file “intflash.ld”, this paper analyzes the address space distribution statement of Kinetis MK60DN512ZVLQ10 chip, and the starting process of the chip, which first jumps to the interrupt vector table at the beginning of the ROM address after power on reset, and then sets the system stack pointer, process stack pointer, switches stack pointer, and finally calls the MQX initialization function to complete the MQX-RTOS starting process. In the basis of reasonable tailoring the start-up code, this paper gives more detailed annotations, which provide certain reference for the further study of other RTOS.
MQX System; RTOS; ARM Cortex-M4 Chip; Booting Process
張建,男,1980年生,講師/碩士,主要研究方向:MIS系統開發、嵌入式系統應用。E-mail: zhangjian2012@suda.edu.cn
王宜懷(通信作者),男,1962年生,教授/博士、博導,主要研究方向:嵌入式系統、傳感網與智能控制技術。E-mail: Yihuaiw@suda.edu.cn
國家自然科學基金資助項目(61070169:無線網傳感器網絡中緊急事件信息發布的可靠性研究)