基于固件技术的mbedOS驻留方法

2021-08-23 04:00刘长勇王宜怀孙亚军
计算机工程与设计 2021年8期
关键词:重定向固件调用

刘长勇,王宜怀,孙亚军

(1.武夷学院 数学与计算机学院,福建 武夷山 354300;2.苏州大学 计算机科学与技术学院, 江苏 苏州 215006;3.武夷学院 认知计算与智能信息处理福建省高校重点实验室, 福建 武夷山 354300)

0 引 言

实时操作系统(real-time operating system,RTOS)的运用不仅能有效合理地利用现有的CPU资源,而且能简化应用软件的设计,缩短开发周期、降低开发费用[1],保证系统的可靠性和实时性。那么如何发挥RTOS作用和优势,采用何种技术实现RTOS在嵌入式系统中的驻留,实现RTOS与应用程序分开编译,是有一定难度且值得研究的问题,可以采用嵌入式固件技术,将RTOS与应用程序进行物理隔离,固化在非易失存储器(如Flash)中[2]。目前,在操作系统的应用及驻留等方面已有部分工作者做了一些基本的研究工作,如唐鹏程等[3]提出了一种基于IAP技术的STM32单片机在线固件升级方案;王运盛等[4]以VxWorks 653分区操作系统作为研究对象,采用统一建模语言来分析和说明分区的配置和启动机制,为理解分区和驻留应用提供了参考;薛芳芳等[5]参考ARINC702A的分区要求,研究了FMS软件的驻留规则,提出了分区设计和驻留方案,最后给出了测试方法;Wang H等[6]采用μC/OS-Ⅱ实时操作系统,在ARM内核的处理器上开发了蛇状机器人,并给出了步态规划算法;常华利等[7]提出了一种基于MicroBlaze 软核处理器的μC/OS-Ⅱ的移植方案;马书红[8]利用集成电路技术和密码学原理,提出了一种将数学计算机系统固化于TPM安全芯片的方法。

mbedOS是专门为使用Arm微控制器的物联网(IoT)设备而设计的开源操作系统[9],支持确定性、多线程、实时性等,广泛应用于协议栈和IP网络组件[10]、物联网设备平台[11]、通信技术和安全访问服务机制[12]等方面。依据固件技术的设计原则,本文基于通用嵌入式计算机架构,在合理划分Flash和RAM空间的基础上,研究mbedOS驻留的关键技术,通过将mbedOS与应用程序分开编译,达到快速编译的目的。同时,也为用户提供函数原型级的对外接口技术和调用方法,方便用户对任务函数的使用,降低了开发门槛、节省了编译时间、提高了写入速度,从而提高应用程序的健壮性、实时性和可移植性,为学习和使用mbedOS提供了基础,也为mbedOS的驻留提供了一种解决方案。

1 GEC架构简介

为了提升编程颗粒度、提高可移植性,借鉴通用计算机(general computer)的概念与做法,把基本输入输出系统(basic input and output system,BIOS)与用户程序分离开来,实现彻底的工作分工,形成了通用嵌入式计算机(general embedded computer,GEC)[13]。GEC架构将嵌入式软件系统分为BIOS工程程序(简称BIOS)和USER工程程序(简称USER)两部分,BIOS先于USER固化于微控制器(microcontroller unit,MCU)内的非易失存储器(如Flash)中,启动时BIOS先运行,随后转向USER,最后由USER启动mbedOS。基于GEC架构,将mbedOS驻留在BIOS中有以下优势:

(1)降低编程难度。由于工程分为了BIOS和USER,mbedOS驻留在BIOS中,成为了一个固件。因此,用户只需关心USER的编程,不改变原有的编程模式,无需了解mbedOS调度机制,就可以调用mbedOS提供的对外接口函数,从而降低了编程难度;

(2)节省编译时间。由于mbedOS驻留在BIOS中,只需要编译成功之后就可以作为一个固件提供给用户长期使用,不占用用户程序时间,而在USER中由于无mbedOS,只需编译用户程序即可,缩短了程序的编译时间;

(3)简化写入方式。在原来不分BIOS和USER时,每次要使用SWD接口通过写入器将程序烧录到Flash中,若程序有变动,还需重新写入。而在GEC架构中,只需在BIOS中通过写入器将程序烧录到Flash中,而USER则可以通过串口进行写入和更新,甚至可以通过远程的方式实现对USER的更新,简化了程序的写入方式。

2 驻留方法

基于GEC架构,程序虽然分为BIOS和USER,但最终程序代码和各种变量数据都是放在同一个MCU的Flash和RAM中,要将mbedOS驻留到BIOS中,就必须对MCU的Flash和RAM空间进行合理的划分,这样才能确保代码不重叠,变量使用不越界,从而保证mbedOS能得到正常运行,而且又不影响USER的执行。

2.1 Flash和RAM空间的划分

(1)Flash空间的划分

MCU的Flash 空间一般分为中断向量段、Flash配置段和程序代码段,分别用于存放中断向量、默认的Flash保护设定与加密属性、程序代码。在GEC架构下,Flash 空间采用分割独享方式划分为BIOS和USER两部分,每部分都包含这3个段,其划分如图1所示,需要注意的是由于Flash是以扇区为单位进行擦除,在划分空间时要以扇区为单位。BIOS负责MCU的启动、提供各类构件、实现mbedOS的驻留以及生成函数原型级的对外接口函数表供USER使用;USER由用户编写,它可以调用BIOS提供的对外接口函数,实现应用程序的功能需求。

图1 分割独享式Flash空间划分

(2)RAM空间的划分

MCU的RAM空间一般分为重定向段、data段、bss段、heap段和stack段,各段的作用见表1。栈空间的使用方向是从大地址向小地址方向进行的,栈空间的栈底位置应该设置为RAM最大地址+1处;而堆空间的使用方向是从小地址向大地址方向进行的。

表1 RAM中的各段作用

RAM空间的划分也同样分为BIOS和USER两部分,前者包含重定向段、data段、bss段、heap段和stack段,后者包含data段、bss段、heap段和stack段。由于heap段和stack段都是用于存放临时局部变量,可以重叠使用。因此,在RAM空间划分上可以采用分割独享和重叠共享两种方式。分割独享方式的优势在于BIOS和USER独享自己的RAM空间,可以避免BIOS和USER运行时彼此间的数据重叠干扰,一般适用于RAM空间较大的情况。由于本文采用的KL36的RAM空间较小,因此采用重叠共享方式。

由于芯片上电启动,运行完BIOS之后,程序会跳转到USER执行。此时,虽然BIOS完成了它的使命,但其RAM空间中的重定向段、data段、bss段和heap段仍要为USER服务,故需保留,而stack段的临时变量不再被使用,无需保留。因此,可以充分利用这一特性,只需确保USER的RAM区域从BIOS的heap段之后开始,且BIOS的stack段的栈底地址与USER的stack段的栈底地址都指向RAM最大地址+1的位置,这样可以将BIOS的stack段与USER的RAM空间共同使用同一段区域。基于此思想,针对RAM空间较小的情况,提出了采用重叠共享的方式来划分RAM空间,如图2所示,BIOS占用整个RAM空间,USER只占用BIOS的stack段这块区域。

图2 重叠共享式RAM空间划分

2.2 对外接口函数表的设计与实现

通过对Flash和RAM空间的划分,为mbedOS驻留在BIOS中提供了空间,但要发挥mbedOS的作用,还需将mbedOS的功能通过对外接口函数表的方式向USER提供服务。要达到这样的目的,首先需要在BIOS中进行对外接口函数的定义、声明、注册,形成对外接口函数表;其次要在USER中获取对外接口函数表的入口地址,并重定向对外接口函数名称;最后在USER中实现对函数的调用,如图3所示。

图3 对外接口函数表的设计与实现

(1)对外接口函数的定义

对外接口函数不仅包含mbedOS的功能函数,而且还可以包括各类构件函数,其定义与一般函数的定义并无区别,主要包括函数名、函数的返回值类型、函数的参数、函数体等。

(2)对外接口函数的声明

对外接口函数定义好之后,一般应在与之同名的.h头文件中进行声明,函数的声明要给出函数名、函数的返回值类型、函数的参数以及函数的功能说明。

(3)对外接口函数的注册

在对外接口函数定义和声明之后,还要对函数进行注册才能形成对外接口函数表。借鉴中断向量表的定义做法,可以给所有的或部分的对外接口函数编号,并将函数名(即函数的入口地址)集中在一起按编号有序地放在一个统一的区域中,这个区域就称为对外接口函数表。对外接口函数表常用数组(如BIOS_API)来存放,对外接口函数的编号与数组的下标元素一一对应,如0号对外接口函数对应BIOS_API[0],1号对外接口函数对应BIOS_API[1],依此类推。

(4)获取对外接口函数表的入口地址

当BIOS的对外接口函数表形成之后,USER要使用它必须先获得对外接口函数表的入口地址,也就是获得存放对外接口函数表的数组首地址。为了与该数组的元素一一对应,在USER中一般也定义一个重定向表数组(如USER_API),这样USER使用USER_API就相当于使用BIOS_API。也可以说,USER通过USER_API就可以访问BIOS提供的对外接口函数。

(5)对外接口函数表的重定向

USER对对外接口函数表中函数的访问是通过USER_API数组,如USER_API[1]访问的是1号对外接口函数。但采用USER_API[i]这种形式对具体访问的对外接口函数的类型、函数名、参数以及功能等不够清晰明了。因此,类似中断向量重定向的做法,也可以对对外接口函数进行重定向,即重新给USER_API[i]取另外一个用户熟悉的函数名,这个函数名可以与对外接口函数名同名,也可以是不同名的,这样就可以为用户提供函数原型级的访问方式,易于用户记住和使用。如mbedOS中延时函数的名称是wait,在重定向时可以取名为delay,表2列出了部分mbedOS对外接口函数。

表2 部分对外接口函数重定向

(6)函数调用

在对外接口函数表重定向之后,就可以利用重定向后的名字来调用对外接口函数,如USER在调用delay函数时,实际上是指向了USER_API[3],而USER_API[3]对应BIOS_API[3],BIOS_API[3]存放的就是wait函数的入口地址,也就是USER通过delay达到调用wait的目的。

2.3 驻留实现的关键点

在GEC架构下,实现将mbedOS驻留在BIOS中,有以下几个方面的关键点需要注意:

(1)合理分配Flash空间。由于Flash空间的划分是以扇区为单位的,当Flash空间较小时,只须保留最基本的各类构件和mbedOS的最基本功能函数以满足实际工程需要即可,确保BIOS的Flash空间不浪费;

(2)确保RAM空间不冲突。当RAM空间较小采用重叠共享方式划分时,若BIOS使用new或malloc等动态内存申请函数,此时申请的空间占用的是BIOS的heap段,当申请的内存过大,可能会出现heap段空间不够而越界到USER的重定向段、data段、甚至bss段,造成USER无法正常运行;

(3)及时回收系统服务调用权。在GEC架构中,从芯片上电到最终用户的任务执行是先启动BIOS,接着启动USER,最后才启动mbedOS。由于mbedOS的调度依赖于系统服务调用SVC、可挂起服务调用PendSV和系统时间嘀嗒SysTick等,而在启动BIOS和USER时都会使用到SVC中断,SysTick中断也有可能会被作为定时器使用。因此,在启动mbedOS前,必须及时将SVC、PendSV和SysTick的调用权回收,移交给mbedOS。

3 驻留测试

mbedOS的驻留测试工程在Kinetis Design Studio 3.0.0 IDE开发环境和金葫芦AHL-A系列Cortex-M0+内核的KL36微控制器[14](即AHL-AN100VL型号开发板)上进行,分为BIOS和USER两个工程,BIOS工程实现mbed-OS的驻留,先于USER固化到Flash中,USER工程实现应用功能。

3.1 Flash和RAM空间实际划分情况

KL36片内Flash大小为64 KB,分为64个扇区,一般用来存放中断向量(共有48个,占192字节)、程序代码、常数等;片内RAM为静态随机存储器SRAM,大小为8 KB,一般用来存储全局变量、静态变量、临时变量(堆栈空间)等。测试工程考虑到Flash和RAM空间较小,Flash空间采用图1划分方式,RAM采用图2划分方式。当mbedOS驻留后,Flash和RAM空间划分情况见表3。

表3 KL36中BIOS和USER空间划分

3.2 驻留后程序启动流程分析

在GEC架构中,当mbedOS驻留在BIOS后,整个程序从上电启动到最后由mbedOS实现对用户任务的调度,需要经历BIOS启动、USER启动以及mbedOS启动3个阶段,其简易启动流程如图4所示。

图4 GEC架构下mbedOS的简易启动流程

首先,MCU上电开始BIOS的启动,由硬件自动完成从Flash的0地址处取值对BIOS的堆栈指针初始化和启动复位向量,接着进行系统时钟初始化和各数据段的初始化,然后在main函数中调用projectJump跳转到USER的执行。

其次,从BIOS转到USER的启动,由用户指令完成从Flash的0地址处取值对USER的堆栈指针初始化和启动复位向量,接着进行各数据段的初始化,然后在USER的main函数调用mbedOS_start启动mbedOS。

最后,从USER转到mbedOS的启动,包括设置mbed-OS的堆栈区、重定向中断向量表、内核初始化、设置自启动任务属性、创建自启动任务、启动内核、调用自启动任务的执行函数,然后由mbedOS完成对用户任务的调度执行。

3.3 驻留的运行测试

USER工程的主要功能是创建两个任务,实现每秒红灯闪烁一次,蓝灯任务每2 s切换亮暗一次,绿灯任务当收到蓝灯任务的线程信号(34)时,切换绿灯亮暗。在USER 工程中,使用到了mbedOS提供的对外接口函数有延时、任务创建、任务启动、信号设置和信号等待等函数。驻留测试工程的运行结果如图5所示,从中可以看出mbedOS驻留成功,程序启动流程正确,能准确调用mbedOS提供的对外接口函数,任务在mbedOS调度下运行正常、程序执行逻辑准确、实时性能得到满足。

图5 驻留测试工程的运行结果

4 结束语

为充分发挥实时操作系统mbedOS的强大功能和较高实时性的性能,本文结合固件技术的设计原则,深入剖析了GEC架构下mbedOS的驻留优势和关键技术,提出了分割独享和重叠共享两种方式来合理划分Flash和RAM空间,详细给出了对外接口函数设计与实现,最后测试结果表明mbedOS驻留成功,Flash和RAM空间划分合理,程序运行逻辑正确。同时,本文提出的对外接口函数重定向方法,使得用户可以使用自己定义的函数名称而不依赖于RTOS提供的函数名称,提高了用户程序的可移植性。后续将在不同MCU的可移植性和驻留等方面展开进一步的研究,文中的程序可在苏州大学嵌入式学习社区(http://sumcu.suda.edu.cn)中下载查看。

猜你喜欢
重定向固件调用
核电项目物项调用管理的应用研究
LabWindows/CVI下基于ActiveX技术的Excel调用
解决安卓文件夹乱象
重复压裂裂缝重定向的措施研究
4G伪基站的监测定位与规避协同分析
基于系统调用的恶意软件检测技术研究
基于固件的远程身份认证
提取ROM固件中的APP
一种通过USB接口的可靠固件升级技术
多路手机固件升级工具设计