APP下载

MQX操作系统启动流程剖析

2016-05-27蒋建武王宜怀

蒋建武, 王宜怀

(1. 苏州大学计算机科学与技术学院, 江苏 苏州 215006;2. 泰州职业技术学院信息工程学院, 江苏 泰州 225300)



MQX操作系统启动流程剖析

蒋建武1, 2, 王宜怀1

(1. 苏州大学计算机科学与技术学院, 江苏 苏州215006;2. 泰州职业技术学院信息工程学院, 江苏 泰州225300)

摘要:针对嵌入式操作系统启动流程中的内核数据区的结构及其初始化, MQX运行所需系统中断和时钟滴答的初始设置, 系统初始化任务及其空闲任务的创建与启动等问题. 提出了实际应用中冷热复位区别启动、 系统滴答时钟调整等问题的操作系统内核级解决方法. 结果表明该方法提升了带MQX操作系统的应用项目的实时性、 稳定性、 鲁棒性等性能.

关键词:MQX嵌入式操作系统; 启动流程; 内核数据区; 时钟滴答

0引言

MQX(message queue eXecutive)操作系统是一款免费、 开源、 有技术支持的嵌入式实时操作系统(RTOS), 主要面向工业控制、 医疗电子、 家用电器等应用开发领域, 目前基于MQX的产品已达数百万. 从1989年至今, MQX已经走过了二十多年的发展历程, 飞思卡尔于2009年收购MQX, 组织专门团队升级维护, 并提供免费技术支持, 至2014年2月推出最新版本4.1.0[1].

与通用PC操作系统下的工程项目开发相比, 嵌入式操作系统环境下的开发对系统的实时性、 稳定性、 启动时间等方面要求更加严格, 由于资源的有限性, 对于资源消耗, 代码执行效率等方面要求也更高. 嵌入式操作系统中对于内存、 外设、 任务调度策略等内容均在启动过程中配置, 清晰理解嵌入式操作系统的启动执行流程可帮助开发人员设计出更加稳定高效的嵌入式应用系统. 陈鹏[2]在Linux操作系统下提出了基于状态保持恢复的快速启动方法, 温圣军[3]立足于系统安全性提出了重构嵌入式系统安全启动流程设计, 邓国荣[4]在分析传统基于AIS和串口引导启动的基础上, 提出了基于NORFlash实现OMAPL138双核系统二次引导自举启动的方法. 罗蕾[5]研究发现, 通过对操作系统启动流程的分析改进, 可以切实地提升系统的启动时间、 执行效率、 安全特性等各方面性能.

目前, 在文献中多为针对Linux、 Android等嵌入式操作系统的启动研究[6], 并无剖析MQX的启动流程的相关资料. 对此将在CodeWarrior v10.5嵌入式软件集成开发平台下, 以SD-FSL-K60-C评估板作为硬件平台, 利用苏州大学飞思卡尔嵌入式系统实验中心(http://sumcu.suda.edu.cn/)发布的有无操作系统相统一的AMQXFW工程框架对MQX操作系统启动流程进行研究. 剖析其从芯片上电, 经主程序Main, 最终进入操作调度的启动全过程. 分析了实现机理, 给出了执行流程并对关键代码进行了分析.

1AMQXFW工程框架启动流程

AMQXFW工程框架启动过程分为芯片启动和MQX系统启动两部分[7], 如图1. 芯片启动过程包括存储映射区域解析、 中断向量表解析、 引导启动boot、 程序启动startup和主程序启动main, 这部分内容与操作系统无关, 进入main主函数中后调用_mqx()函数将系统控制权交给MQX操作系统.

在ARM Cortex-M4处理器架构中, 芯片上电后自动执行物理地址0x00000000h处指令, 查询位于芯片内部的存储映射区域. 从中断向量表中获取其中第一个表项作为系统栈的栈首指针赋给MSP(main stack pointer, 主栈指针), 获取其中的第二个表项作为系统启动函数的地址赋给PC(program counter, 程序计数器)[8-9]. 在AMQXFW工程框架中, 由_boot函数执行启动, 执行关中断、 切换堆栈等过程. 然后转入执行_thumb_startup函数, 进入C语言函数部分, 完成禁用看门狗(wdog_disable)、 初始化内存数据(_copy_rom_sections_to_ram)、 初始化系统时钟(system clock setup)等操作[10]. 最后进入main函数执行, 调用MQX操作系统的入口函数_mqx()开始启动MQX.

MQX进入main函数之后, 调用MQX的入口函数开始启动, 初始化后由任务调度机制控制系统执行. MQX启动过程完成操作系统运行所需的内核数据区变量初始化、 中断初始化、 外设初始化, 以及各种任务队列的创建等工作.

2MQX操作系统内核数据区

内核数据区是用来表明MQX的状态和动态变量的结构体, 它的成员数不是固定的, 其中有些变量是根据配置决定是否编译, 所以内核数据区的大小不是固定的.

2.1内核数据区的存储位置

AMQX工程框架的链接文件intflash.ld对RAM进行分配和部署. K60微控制器RAM共有128 KB, 地址范围0x1FFF0000到0x2000FFFF, 如图2所示. _KERNEL_DATA_END定义为0x2000FFF0, 预留了15个字节, 防止内存块地址对齐时出现地址越界的发生. 从0x1FFF0000开始的一段区域用于存放从FLASH复制来的数据, 系统启动时startup.c文件会初始化这段数据区, 该区包括中断向量表、 .DATA和.BSS等数据. 在采用段式内存管理的架构中, .BSS段通常是指用来存放程序中未初始化的全局变量的一块内存区域, .BSS段属于静态内存分配; 而另一个.DATA段, 用来存放程序已初始化的全局变量; 而函数内的局部变量都在栈上分配空间[11]. 在项目开发中加入冷热复位处理时要注意跳过对.BSS段初始化为零的操作, 否则系统将因为全局变量的重新赋值而恢复不到复位前的状态.

2.2内核数据区数据结构kernel_data_struct

MQX初始化函数_mqx()的结构体参数MQX_INITIALIZATION_STRUCT包含了初始化MQX的基本信息, 如处理器个数、 中断堆栈大小等成员变量. BSP_DEFAULT_START_ OF_KERNEL_MEMORY代表了内核所在内存的起始地址, 具体数值在intflash.ld文件中定义, 这个起始地址就是内核数据区kernel_data_struct的起始地址. 执行_mqx()函数的过程中, 程序会对这块内存区域kernel_data_struct成员变量进行赋值, 其主要成员变量如表1所示[12].

表1 kernel_data_struct结构表

MQX_INITIALIZATION_STRUCT类型常量MQX_init_struct包含了启动MQX所需的所有参数的预设值, 各成员的数值及含义如表2所示.

表2 MQX_init_struct结构表

3MQX操作系统启动流程源码剖析

在main函数中, 将MQX初始化参数传入_mqx函数, 执行_mqx函数启动MQX系统. MQX启动过程如下: 初始化内核数据区, 初始化MQX运行所需系统模块, 创建系统初始化任务, 创建空闲任务, 启动任务调度器.

3.1初始化内核数据区

内核数据区是负责记录MQX系统运行状态及资源使用情况的存储区, 在开始正常工作之前, 要确保为内核数据区指定合适的初始值.

1)创建内核数据区访问指针kernel_data.

//获得内核数据区的首地址, 执行地址对齐后, 作为内核数据区的访问地址

kernel_data = (KERNEL_DATA_STRUCT_PTR)

_ALIGN_ADDR_TO_HIGHER_MEM(mqx_init->START_OF_KERNEL_MEMORY);

_SET_KERNEL_DATA(kernel_data);// 设置将内核数据区的首地址指向全局变量区

内核数据区空间在链接命令文件中的定义, 属于BSP的内容. 为了提高相对于BSP的独立性, 此处创建了一个内核数据区访问指针, 并定义了访问接口. 以后的程序中, 只要将kernel_data定义为“volatile KERNEL_DATA_STRUCT_PTR”类型, 再使用“_GET_KERNEL_DATA(kernel_data)”宏函数, 即可访问内核数据区.

2)填充内核数据区. 在MQX启动过程中要将系统设定的初始信息填充到内核数据区. 操作流程包括操作系统版本号与厂商名称赋值、 内核数据区字段置0、 内核数据区读写功能验证、 MQX内核数据区初始化数据赋值等, 详细流程如图3所示.

3)系统中断栈初始化. 若使用中断, 则需要为系统中断栈分配存储空间并在内核数据区中登记. 当产生嵌套中断时, 系统将把嵌套中断的上下文保存在中断栈中. 高优先级中断服务例程执行返回后, 从中断栈中恢复低优先级中断上下文继续执行.

4)创建系统任务栈. 系统栈用于自动维护系统空闲任务, 非用户创建. 当系统空闲任务被中断阻塞时, 使用系统栈保存空闲任务的上下文. 系统栈指针链接在kernel_data->SYSTEM_TD上, 可由全局变量_mqx_system_stack操作控制.

5)创建就绪任务队列数组与操作信号量. 就绪任务队列数组是任务调度系统操纵的主要对象, 在系统初始化过程中, 根据任务模板列表中用户定义的任务最低优先级创建就绪队列数目并根据优先级排序. 在就绪任务队列刚被创建时, 每个就绪任务队列中仅包含一个队列头结构, 当有任务进入就绪态后, 该任务的描述符就挂载到相应优先级的就绪任务队列上. 在内核数据区中为创建和删除任务创建一个轻量级信号量, 用以保证同步访问能够正确进行.

3.2MQX运行所需系统模块初始化

在系统启动时通过_bsp_pre_init函数对硬件平台进行初始化, 主要内容有:

1) 初始化MQX的中断系统. 为中断系统分配动态中断向量链接表头节点, 初始化动态中断向量表.

//初始化MQX的中断管理系统

result = _psp_int_init(BSP_FIRST_INTERRUPT_VECTOR_USED, BSP_LAST_INTERRUPT_VECTOR_USED);

//设置硬件中断向量表的存储位置

(void)_int_set_vector_table(BSP_INTERRUPT_VECTOR_TABLE);

//将Systick设置为系统滴答定时器中断向量

_time_set_timer_vector(BSP_TIMER_INTERRUPT_VECTOR);

//为定时器中断安装ISR服务例程

if (_int_install_isr(BSP_TIMER_INTERRUPT_VECTOR, (void (_CODE_PTR_)(pointer))_bsp_systick, NULL) == NULL) return MQX_TIMER_ISR_INSTALL_FAIL}

MQX对动态中断向量表进行分组管理, 每组的节点数由配置文件small_ram_config.h中的宏MQX_SPARSE_ISR_SHIFT的定义值决定, 缺省值一般为3, 每组的节点数为23=8. 初始化的动态中断向量链接表头节点为一个中断服务的数组指针, 数组的大小由给定的中断向量数除以8得到, 每组数组元素指针指向一组链表. 当中断事件产生后, MQX的中断处理系统将在中断向量链表中查询相应的服务函数并调用执行. 动态中断向量表机制中中断服务例程可在系统运行过程中安装更新, 根据不同需要可以为同一中断源动态配置中断服务例程, 这样使得中断处理更加灵活.

2) 初始化系统时间滴答. MQX操作系统运行时, 需要一个滴答(tick)时钟信号, 驱动操作系统的时间管理系统工作. ARM Cortex-M4处理器内部提供了一个Systick定时器, 是一个可编程的硬件模块, 以固定的频率产生中断. 该中断就是Systick中断, 它所处理的中断处理程序负责更新系统时间, 也负责执行需要周期性运行的任务. 系统滴答包括滴答计数TICKS与硬件滴答计数HW_TICKS, 初始化过程如下:

//初始化系统ticks变量

kernel_data->TIMER_HW_REFERENCE = (BSP_SYSTEM_CLOCK / BSP_ALARM_FREQUENCY);

_time_set_ticks_per_sec(BSP_ALARM_FREQUENCY);

_time_set_hwticks_per_tick(kernel_data->TIMER_HW_REFERENCE);

_time_set_hwtick_function(_bsp_get_hwticks, (pointer)NULL);

在AMWXFW工程框架中BSP_SYSTEM_CLOCK为96M, BSP_ALARM_FREQUENCY为200, 由以上初始化代码可知滴答时间为1/200=5 ms, 硬滴答时间为200/96M=1/480 ms, 当滴答计数器TICKS=10与硬滴答计数器HW_TICKS=48时, 则系统运行了(10×5+48/480)=50.1 ms, Systick中断执行了10次.

3.3任务初始化与调度

1) 启动系统初始化任务. 系统初始化任务是MQX系统创建的初始化任务, 完成BSP设备初始化和自动运行任务加入就绪任务队列两项工作. 通过_mqx_init_task()函数完成, 在其中利用_bsp_init()函数完成dma设备列表初始化、 内核IO子系统初始化、 默认UART调试串口初始化、 内核串行IO端口初始化. 为了提高启动速度, 应将所有非系统必要的硬件设备初始化操作均可以调整到用户设计的初始化硬件设备任务中进行.

2) 启动空闲任务初始化. 为便于维护系统中的任务队列, MQX会创建一个空闲任务. 当所有应用任务均不再执行, 系统仍然运行此空闲任务, 以保证MQX的调度系统保持工作状态.

3) 启动任务调度器. 在做好所有启动MQX的准备后, 启动调度程序_sched_start_internal(), 系统的控制权就转移给调度系统. 在调度系统的管理下, 根据系统使用的调度策略依次调度各个任务执行, 实现系统功能.

4结语

操作系统的启动过程包含对操作系统运行时所需资源的初始化, 明晰其执行流程可快速把握操作系统的整体架构. 本文通过对AMQXFW工程框架执行流程的分析, 将MQX操作系统的启动流程界定为芯片启动和操作系统启动两个独立的过程, 简要给出了前期的引导启动过程, 着重分析了进入操作系统后的内核数据区、 初始化中断和系统滴答的初始化, 以及任务调度启动过程. 对MQX的启动流程分析可以为优化启动过程、 简化执行流程、 提升启动速度等进一步研究工作奠定基础.

参考文献:

[1] Freescale. Freescale MQX RTOS 4.1.0[EB/OL]. (2014-02-16)[2014-03-02]. http://www.freescale.com/mqx.

[2] 陈鹏, 王树志, 张全胜, 等. 基于状态保持恢复的嵌入式Linux快速启动方法的研究[J]. 微计算机信息, 2012(9): 48-50.

[3] 温圣军, 张鲁国. 可重构嵌入式系统安全启动流程设计与实现[J]. 计算机工程, 2009, 35(20): 134-136.

[4] 邓国荣, 刘厚钦. 基于NOR Flash的OMAPL138双核系统自举引导启动实现[J]. 电子技术应用, 2014, 40(2): 19-22.

[5] 罗蕾. 嵌入式实时操作系统及应用开发[M]. 北京: 北京航空航天大学出版社, 2011.

[6] 汤书森, 刘栋. 基于ARM处理器PXA270&Linux的嵌入式系统的启动过程分析[J]. 甘肃科技, 2011, 27(6): 14-16.

[7] 苏勇. 嵌入式实时操作系统MQX应用框架研究[D]. 苏州: 苏州大学, 2013.

[8] ARM. Cortex-M4 devices generic user guide[EB/OL]. (2010-12-26)[2011-06-08]. http://www.arm.com.

[9] Freescale. K60 sub-family reference manual rev.6[EB/OL]. (2011-11-12) [2012-03-18]. http://www.freescale.com.

[10] 王宜怀, 吴瑾, 蒋银珍. 嵌入式系统原理与实践-ARM Cortex-M4 Kinetis微控制器[M]. 北京: 电子工业出版社, 2012.

[11] 石晶, 王宜怀, 苏勇, 等. 基于ARM Cortex-M4的MQX中断机制分析与中断程序框架设计[J]. 计算机科学, 2013, 40(6): 41-44.

[12] Freescale. Freescale MQX RTOS user’s guide rev.6[EB/OL]. (2014-02-12)[2014-05-13].http://www.freescale.com/mqx.

(责任编辑: 林晓)

Analysis of the boot process of MQX RTOS

JIANG Jianwu1, 2, WANG Yihuai1

(1. School of Computer Science and Technology, Soochow University, Suzhou, Jiangsu 215006, China;2. Department of Electronic and Information Engineering, Taizhou Polytechnic College, Taizhou, Jiangsu 225300, China)

Abstract:The boot process of embedded operating system is the leading process of its running. This paper deeply analyzes a series of problems existing in the boot process of embedded operating system startup process, including initial set kernel data structure and its initialization, the setting method of system interruption and clock required to Run the MQX operating system, the creating and starting process of the system initialization task and the idle task.It presents some of the operating system kernel level solutions, to solve differences start on the practical application in hot and cold reset, system clock tick by adjustment problems, so as to enhance the performance of various kinds of application projects with the MQX operating system, including real-time, stability, robustness.

Keywords:MQX RTOS; boot process; kernal data; ticks

中图分类号:TP316.2

文献标识码:A

基金项目:国家自然科学基金资助项目(60871086); 泰州职业技术学院硕博基金资助项目(TZYBS-14-5)

通讯作者:王宜怀(1962-), 教授, 主要从事嵌入式系统与物联网、 智能控制等方面研究, Yihuaiw@suda.edu.cn

收稿日期:2014-07-07

文章编号:1000-2243(2016)02-0202-05

DOI:10.7631/issn.1000-2243.2016.02.0202