刘长勇,王宜怀,彭 涛,孙亚军,程宏玉
1(武夷学院 数学与计算机学院,武夷山 354300)
2(苏州大学 计算机科学与技术学院,苏州 215006)
3(认知计算与智能信息处理福建省高校重点实验室,武夷山 354300)
实时操作系统(Real-Time Operating System,RTOS)的运用不仅能够更有效、更合理的利用现有的CPU 资源,而且能够简化应用软件的设计,缩短应用的开发时间、降低开发费用[1],保证系统的可靠性和实时性,那么如何实现RTOS 在不同的内核、微控制器(Micro Controller Unit,MCU)、开发环境等方面的移植,一直是工程技术界研究的共性技术.
目前在RTOS 的移植上已经有了一些研究,也提出相应的移植解决方法.如常华利等[2]提出了一种基于MicroBlaze 软核处理器的μC/OS-II 的移植方案;唐小平[3]在深入分析μC/CPU 移植文件编写与修改的细节的基础上,给出了基于STM32F103RC 产品平台下的μC/OS-Ⅲ成功移植案例;候海霞[4]对Free RTOS 操作系统和LwIP 协议栈进行了深入的研究,在STM32F407芯片上实现了Free RTOS 与LwIP 协议栈的移植;罗名驹[5]研究了如何移植引入设备树的U-boot 和Linux内核到Samsung Exynos4412 芯片上的关键技术.但是,这些移植解决方案仅停留在解决如何将RTOS 移植到某一特定的MCU 上,而对不同的内核、MCU、开发环境等的移植情况鲜有研究.同时,有关mbedOS 的研究主要集中在通信技术和安全访问服务机制[6]、协议栈和IP 网络组件[7]、物联网设备平台[8,9]等方面.
2014年ARM 公司推出了mbedOS,它是一种专为物联网 (IoT)中的“物体”设计的开源嵌入式实时操作系统[10],具有任务管理与调度、时间管理、中断处理、内存管理、同步与通信等基本功能,对外提供统一的底层驱动接口,能满足多任务的运行,具有较高的实时性.本文在深入剖析mbedOS 的基本功能和实时性要求上,根据嵌入式软件工程的基本思想,以可扩充、可移植的mbedOS 工程框架为基础,分析了移植的共性问题和注意事项,给出了具体的移植方法,解决了mbedOS 在不同的内核、MCU、开发环境等上的移植关键技术问题,为mbedOS 的应用研究提供了基础,为mbedOS 的移植提供了一条简捷、有效的路径.
这里对基于MKL36Z64VLH4(简称KL36)微控制器的无操作系统工程框架SD-NOS 和可移植的SDmbedOS 工程框架的构建方法做个简要的概述.
首先,根据无操作系统软件最小系统的含义,建立包括说明文档、内核相关文件、微控制器相关文件、用户板构件、软件构件、中断服务程序和无操作系统主程序等嵌入式系统工程最基本要素的无操作系统工程框架SD-NOS.该工程框架能够满足点亮一盏发光二极管的最基本要求,甚至带有串口调试构件.
其次,提出了RTOS 软件最小系统的含义,它是将任务管理、调度管理、内存管理、中断管理、时间管理以及同步与通信等RTOS 最基本功能要素,以构件的形式添加到无操作系统软件最小系统上,构成能至少实现对两个任务进行调度的工程框架.
最后,按照“分门别类、各有归处”原则,对工程框架的文件夹和共性文件进行归纳分类,以编号的形式建立相应的文件夹存放源程序和头文件,基于KL36微控制器,构建了可移植的SD-mbedOS 工程框架.表1给出了利用SD-mbedOS 工程框架在采用ARM Cortex-M 处理器的MCU 上进行移植时,需要替换、修改或添加的内容,对不需要改动的内容直接进行复制,其中底层构件仅包含最基本的通用输入输出gpio 构件和串口通信uart 构件.
表1 基于SD-mbedOS 工程框架的移植说明
移植必然涉及文件覆盖与改动,也涉及到开发环境、编译器、内核等共性问题,下面给出简要分析.
SD-mbedOS 工程框架是基于ARM Cortex-M0+内核的KL36 微控制器进行构建的,当采用该框架在ARM 内核的MCU 上进行mbedOS 移植时,会涉及到不同内核、不同MCU、不同开发环境等因素,其共性问题分析如下:
(1)mbedOS 文件的添加
由于要将mbedOS 移植到特定MCU 的嵌入式系统工程中,因此需将SD-mbedOS 工程框架下的02_Core 和07_mbedOS 文件夹内容添加到指定的工程中.
(2)MCU 相关文件的替换
不同的MCU,其内核、异常处理程序、链接文件、MCU 头文件、MCU 启动文件、底层硬件驱动构件、应用构件都有所不同.因此,需要根据实际采用的MCU 和应用需求,替换这些文件.若采用的MCU 为KL36,则不需进行替换.
(3)内核与MCU 相关文件的修改
不同MCU,其RAM 的起始地址和大小是不一样的,中断向量的个数也不相同,堆栈指针的栈底地址也不同.因此,需要对这些内容进行重新设置,以符合特定MCU 的要求.若采用的MCU 为KL36,则不需进行修改.
(4)头文件的设置
由于MCU 发生了改变,需要将CMSIS 编译器、内核头文件以及MCU 头文件加入到相关的文件中,这样在编译时才能找到指定的文件.
本文涉及到的MCU 虽然内核不相同、所采用的开发环境也不一样,但都属于ARM Cortex-M 处理器范畴,都遵循微控制器软件接口标准(Cortex Microcontroller Software Interface Standard,CMSIS).mbedOS 是由ARM 公司开发,其内核程序也遵循CMSIS,且采用C++语言和汇编语言混合编程,这就要求开发环境集成的编译器不仅能处理C++语句,而且还能编译汇编语言指令,故一般都采用GCC(GNU Compiler Collection,GNU 编译器套件)编译器.因此,当在不同MCU 上进行mbedOS 移植时,必须分析开发环境、编译器和内核等方面的设置和使用问题.
(1)与开发环境相关问题分析.由于开发环境不相同,会出现有些宏、数据类型、函数调用、静态内联函数等未定义情况,一方面是要在工程属性中设置各文件夹及其子文件夹的路径,另一方面则需要在相关文件中添加宏定义或头文件.例如,在MSP432 开发环境中,需要在cmsis.h 中添加“__WEAK”宏定义解决弱定义错误、在cmsis_gcc.h 中添加“sys/_stdint.h”解决数据类型未定义问题、在链接文件中修改heap 段的结束标志“__end”为“__end__”;在S32K 开发环境中,需要在mbed_critical.c 中添加“cmsis_gcc.h”解决__disable_irq 等函数调用问题、在os_systick.c 中添加“core_cm4.h”和“system_S32k144.h”解决OS_Tick_Setup 等函数调用问题、在rtx_core_cm.h 中添加“core_cm4.h”解决静态内联函数未定义问题.
(2)与编译器相关问题分析.mbedOS 是采用C++和汇编语言混合编程,不仅开发环境的编译器要设置成能同时处理C++语句和汇编指令,而且有的开发环境还要求对.c 的源文件要进行特殊处理,才能满足其要求.例如,在MSP432 开发环境CCS 中,默认编译器采用“TI V5.2.5”版本,对编译汇编文件和C++文件支持不足,故建议改为“GNU V7.2.1”,运行支持的类文件选择“libsupc++.a”,同时添加名为“c”的libc.a 库文件,这样才能更好地实现对汇编指令和C++的编译;在S32K 和MSP432 开发环境中,对.c 程序的编译时会出错,要进行特殊处理:一方面可以采用直接将其扩展名改为.cpp 的方式,另一方面若该.c 文件同时存在同名的.h 文件时,则可以通过“ifdef __cplusplus”预处理告之编译器要以c 的形式处理这些文件.
(3)与内核相关问题分析.mbedOS 的SVC、PendSV、SysTick 等中断服务程序是按照CMSIS 标准采用C++和汇编语言混合编程,对寄存器的使用遵循AAPCS 规范(ARM Archtecture Procedure Call Standard,ARM 架构过程调用标准).当MCU 的内核为Cortex-M0+时,采用R7 寄存器保存实际调用函数的入口地址;当采用Cortex-M4 或M4F 内核的MCU 时,则实际调用函数的入口地址保存在R12 寄存器中.因此,在编写汇编程序时,要注意避开这两个寄存器,改用其他寄存器,以避免程序执行时出现无法预计的情况.
在已有的无操作系统工程的基础上,要将mbedOS移植到特定的嵌入式系统应用开发中,可以采用以下3 种方法进行移植:第1 种方法是自行分析mbedOS 代码结构,根据应用开发的实际从中抽取相关文件加入到工程中,然后在工程进行编译,修改相关的错误,对mbedOS 的移植有较大难度;第2 种方法是根据SDmbedOS 工程框架内的02_Core 和07_mbedOS 文件夹的内容,从mbedOS 代码中直接抽取这些源文件,加入到工程中,然后进行编译修改,对mbedOS 的移植有一定难度;第3 种方法是直接利用SD-mbedOS 工程框架,将其中的02_Core 和07_mbedOS 文件夹加入到工程中,根据工程具体情况只需少量的修改就可以使用,这样可以少走弯路,更容易一些.下面介绍mbedOS 移植的第3 种方法.
本文分析的是基于KL36[11]的SD-mbedOS 工程框架在S32K144[12]和MSP432[13]等MCU 上的移植方法,这几款MCU 均为ARM Cortex 处理器,但采用的内核、开发环境、Flash、RAM、中断向量数以及生产厂家等都有所不同,具体对比如表2所示.
表2 不同MCU 的基本情况对比表
当采用的MCU 为KL36 时,可以直接使用SDmbedOS 工程框架,只需根据实际应用的功能需求,修改08_mbedOsPrg 文件夹内的相关内容即可.当采用不同的MCU 时,mbedOS 的移植步骤分析如下:
(1)构建无操作系统工程框架.按照SD-NOS 工程框架的结构,根据所采用的MCU(其内核文件、链接文件和启动文件等在购买该MCU 时厂家会提供或可从网络上下载获取),使用相应的开发环境搭建无操作系统工程框架.
(2)复制mbedOS 文件.由于02_Core 文件夹包含的内核头文件、内核函数访问头文件、内核指令访问头文件以及编译器头文件等在mbedOS 中已有且略有不同.因此,先删除这些文件,然后将SD-mbedOS框架中的02_Core 和07_mbedOS 文件夹的内容复制到无操作系统工程框架中,形成带操作系统的工程框架.
(3)设置内核与MCU 相关文件.由于MCU 不同,其中断向量个数、中断向量表在RAM 的起始地址、RAM 的起始地址与大小、堆栈指针等也不一样,要根据特定的MCU 进行重新设置;需要将MCU 的头文件包含在微控制器软件接口标准头文件cmsis.h 和公共头文件common.h 中;由于中断向量表要从Flash 复制到RAM 中,需要在RAM 中预留出中断向量数×4 的字节数来,故在链接文件中RAM 的起始地址要在原起始地址的基础上加中断向量数×4.具体需要设置的文件和内容如表3所示.
表3 mbedOS 在不同MCU 上移植主要内容修改对比表
(4)设置工程属性.为了便于在函数调用中能找到相关的文件声明位置,可以在工程配置文件中添加各个文件夹及子文件夹的路径,同时添加相关宏定义,以便在函数调用时能找到这些头文件和宏.
(5)与应用开发相关的内容设置.在实际的应用开发中,若有新增底层硬件构件、应用构件、软件构件、用户任务程序、中断服务程序等,需要在总包含头文件includes.h 中要包含各类构件头文件、用户函数声明和中断声明.这一步根据需要进行设置,若无增加则不需要进行设置.
(6)编译工程.在开发环境中对工程进行编译,检查并修改错误,编译成功之后下载到开发板上运行,观察运行结果.
通过以上移植步骤,按照表3的修改内容以及共性技术分析的要点,就可以利用KL36 的SD-mbedOS工程框架将mbedOS 移植到以S32K 和MSP432 为MCU 的工程上.由于是针对mbedOS 进行移植测试,因此,在三款MCU 的工程中实现相同的任务功能,可以将KL36 工程中的蓝灯任务、绿灯任务和红灯任务这3 个任务程序代码直接复制到S32K 和MSP432 工程中进行移植测试.移植测试工程实现蓝灯任务、绿灯任务和红灯任务分别每2 s、每1 s 和每3 s 闪烁1 次,由于篇幅有限,仅给出蓝灯任务的程序代码,绿灯任务和红灯任务的程序代码与蓝灯任务的程序代码基本一样,只是延时时间不同而已,更加详细的工程代码与移植说明可到苏州大学嵌入式学习社区网站(网址:http://sumcu.suda.edu.cn)的“教学培训-教学资料-mbedOS”位置,下载“The Protability of mbedOS in MCUs_190928”查看.
蓝灯任务代码:
void run_bluelight(void)
{
while (true){
printf(" ***2-1.蓝灯任务开始.*** ");
light_change(LIGHT_BLUE);//切换蓝灯的亮暗
Thread::wait(2000);//延时2 秒
printf(" ***2-2.延时2 秒到切换蓝灯亮暗.*** ");
printf(" ***2-3.蓝灯任务结束.*** ");
}
}
图1给出了mbedOS 在KL36 上的运行结果,以及在S32K 和MSP432 上的移植测试结果,从中可以看出在mbedOS 的调度下任务运行正常、程序执行逻辑准确,本测试工程涉及到RTOS 的任务调度、时间嘀嗒、延时函数、事件、消息队列等基本要素,这些要素具有普适意义,程序的正常运行,表明移植成功.
图1 mbedOS 在多个MCU 的移植测试结果
实时操作系统mbedOS 具有任务管理与调度、时间管理、中断处理、内存管理、同步与通信等基本功能,能提供调度的实时性、响应时间的可确定性、系统高度的可靠性,在物联网终端、工业控制设备、军事设备、航空航天等领域得到广泛应用.本文通过对mbedOS 的基本功能和实时性等方面进行深入剖析,根据嵌入式软件工程的基本思想和嵌入式软件构件设计的基本原则,以可移植、易扩充的SD-mbedOS 工程框架为基础,分析了移植的共性技术和注意事项,给出了mbedOS 在ARM Cortex-M 系列的不同内核、MCU、开发环境等的移植解决方案,并完成了移植测试,为广大嵌入式系统开发者在mbedOS 移植上少走弯路,提供了简洁、方便的路径,也可为其他RTOS 的移植提供参考.后续将针对mbedOS 的启动、系统服务调用、任务调度等做进一下的研究探讨.