基于D1-H应用处理器的RT-Thread驻留方法

2024-02-18 08:13李志嫒王宜怀刘长勇
计算机应用研究 2024年1期

李志嫒 王宜怀 刘长勇

摘 要:针对实时操作系统复杂性内核导致嵌入式应用程序编译速度慢、可复用性差的问题,提出基于通用嵌入式计算机架构(GEC)的RT-Thread实时操作系统驻留方法。在合理划分存储空间的基础上,通过对中断服务例程进行共享,为用户提供底层驱动与软件应用层的函数调用服务。最后以D1-H应用处理器为例进行RT-Thread驻留测试。实践结果表明,该驻留方法实现了系统内核与应用程序的物理隔离,编译时间更短,开发效率更高,为嵌入式程序开发的时效性、便捷性和简易性提供了应用基础。

关键词:实时操作系统;应用处理器;通用嵌入式计算机;驻留;函数调用

中图分类号:TP316.2   文献标志码:A   文章编号:1001-3695(2024)01-034-0222-04

doi:10.19734/j.issn.1001-3695.2023.04.0223

Resident method of RT-Thread based on D1-H multimedia application processor

Abstract:This paper proposed a method for the residency of the RT-Thread real-time operating system based on the general embedded computer (GEC) architecture to address the issues of slow compilation speed and poor reusability caused by the complexity of the real-time operating system kernel in embedded applications.On the basis of reasonable storage space allocation,the method achieved the sharing of interrupt service routines,providing users with function call services for both low-level drivers and software application layers.Finally,the residency method was tested using the D1-H application processor as an example.And the results demonstrate that it achieves physical isolation between the system kernel and application programs,resulting in shorter compilation time and higher development efficiency.This method provides a foundation for the timeliness,convenience,and simplicity of embedded program development.

Key words:real time operation system;multimedia application processor;general embedded computer;residency;function call  實时操作系统(RTOS)[1]作为面向应用处理器的重要工具和运行载体,不仅能有效管理和利用处理器资源,而且实现了应用程序的模块化管理与并发性执行,保证了嵌入式系统的安全性、可靠性和实时性。在RTOS的应用程序开发中,仍存在因RTOS源码被误改或代码量较大而影响编译效率与系统稳定性的现象。若在物理层面实现RTOS源码与应用程序的隔离,同时利用好RTOS为软件开发提供的高效服务,则能够在降低开发难度的基础上提升开发效率。借助GEC架构从功能层面将基本输入输出系统(basic input and output system,BIOS)与用户程序(user)进行有效分割的思想,将RTOS驻留在BIOS内,实现对嵌入式应用程序编程颗粒度和可复用性的提高。目前,已有部分学者对操作系统的驻留应用进行了相关研究,如:杨静远等人[2]提出了一种基于ARINC653标准的分区操作系统固化映像启动配置策略;Chen等人[3]以Quark分区操作系统作为研究对象,基于微内核架构配置分区来实现系统实时性能的提升;白曦等人[4]参考分区操作系统时空隔离机制,设计了机电软件开发平台,将复杂业务应用分解为功能单一的多个业务应用,将其独立驻留在不同分区,保证了应用的健壮性。

RT-Thread[5]是一个集RTOS内核与中间层组件于一体的开源物联网操作系统(IoT OS)[6],支持可靠性、实时性、高可伸缩性,被广泛应用于智能家居、工业自动化、国防军工、消费电子等众多领域。本文依据通用嵌入式计算机思想构建D1-H[7]芯片软件框架,将RT-Thread与底层驱动驻留于BIOS程序,通过函数映射的方式为用户在USER程序开发提供构件级应用,降低了编程门槛、提高了开发效率、保障了系统稳定,从而提高嵌入式应用程序的易用性、稳定性和可复用性。

1 RTOS驻留方法共性技术研究

RTOS作为嵌入式系统的核心组件,在系统启动后处于持续存在和运行的状态,负责高效地管理有限的资源以满足任务调度的实时性能需求。其驻留实现方式因系统和应用需求而异,但其目的都是确保嵌入式系统的实时性和可靠性。

1.1 通用嵌入式计算机架构

为了解决在嵌入式软件开发中存在的编程颗粒度低、可移植性弱等问题,通用嵌入式计算机GEC基于模块共性知识要素对底层驱动进行构件化,并采用类PC机开发模式将嵌入式软件分为BIOS程序与user程序两部分[8],如图1所示。其中,BIOS程序固化于MCU的非易失性存储器中,MCU上电启动时,先运行BIOS程序,再跳转至user程序,随后在user程序中启动操作系统RT-Thread。在GEC架构下,BIOS程序为user程序提供工作时钟与函数原型级调用接口,用户在基于标准软件工程框架的user程序中进行应用开发,通过调用BIOS程序提供的构件进行快速编程。GEC架构从存储空间和功能定义两个方面实现了BIOS程序与user程序的合理划分,为RT-Thread的驻留提供了应用基础。以BIOS程序作为先导程序,实现RT-Thread在MCU硬件层的固化,用户则专注于软件层,在user程序中进行应用开发。下面从共性角度对RT-Thread驻留在BIOS的关键点进行分析。a)MCU的存储资源是RTOS在实际应用中的首要考虑因素,尤其是在使用大多低成本终端设备时,其flash和RAM资源更为有限。因此,为了避免出现BIOS程序与user程序在物理地址上冲突而导致代码重叠、变量越界等问题,需要对存储资源进行合理有效的划分与利用。b)RTOS的核心功能是通过调度器对线程进行管理,当RTOS驻留在BIOS程序后,为了实现调度器在user程序中的运转,对系统中断服务例程进行共享是实现BIOS程序与user程序在空间上保持联动的必要项。c)RTOS具有丰富的函数调用接口,例如线程创建启动、线程状态转换以及线程上下文切换等,RTOS驻留后,在user程序中不包含函数接口,用户无法直接在user程序中调用函数。因此,如何定位并调用函数是RTOS驻留后正常使用系统服务的关键。

1.2 RTOS驻留方法研究与对比

RTOS作为运行在CPU内部的程序,通常与用户程序一同编译,导致存储空间与CPU算力的开销增长,文献[9]利用现场可编程逻辑门阵列(FPGA)将μC/OS-Ⅲ内核硬件化,通过定制硬件调度器进行任务调度,使得CPU专注于用户任务的运算,从而实现系统内核与用户任务的隔离。这种方法具有直接在硬件层面运行的优势,可以利用FPGA的并行计算能力与低功耗特性,提供高度可定制化的解决方案,但同时也面临着复杂的硬件设计与开发流程,不具备通用性、可移植性与扩展性,技术实现难度较大。文献[10]针对人造器官软件更新的应用场景,提出部分动态软件更新机制,通过将轻量级实时操作系统Cyborgan OS的内核驻留在固定代码区域,实现应用程序的增量更新与功能升级,该方法在确保系统稳定性和可靠性的前提下,提供了更加灵活和高效的软件更新方案。文献[11]基于汽车嵌入式实时操作系统的顺序内核展开形式建模和验证研究,通过扩展C-IL / CC- IL配置状态模型,为操作系统和可信任应用程序的内存隔离提供基础机制,保障嵌入式系统的设计和开发,提高了系统的可维护性和可扩展性。以上两种方案通过固定代码驻留RTOS的思想,为本文研究提供了重要的参考价值。不同的RTOS驻留方法在实时性能、资源利用率、开发复杂度以及可移植性等方面存在着差异。选择合适的驻留方法需要综合考虑具体的应用需求和系统要求。通过对上述方法的介绍和对比,可以进一步验证本文方法的科学性和创新之处,并为读者提供更全面的研究视角。

2 基于D1-H的GEC软件框架设计与实现

嵌入式软件工程由若干不同类型的文件组成,其中包括程序文件、头文件、与编译调试相关的文件、工程说明文件、开发环境生成文件等,基于GEC架构的层次化原则,将BIOS程序和user程序按照功能定义进行逻辑划分,通过清晰的层次结构为长期的软件维护和功能拓展提供保障。

1)BIOS程序工程框架 BIOS工程框架如表1所示,依据“分门别类,各有归处”的原则将RT-Thread源码驻留在BIOS程序的05_UserBoard文件夹,并在该文件下通过自定义的OsFunc.c程序对RT-Thread的启动流程进行统一收拢,由OS_start函数调用RT-Thread实际的启动函数。

2)user程序工程框架 user程序工程框架的组织架构与BIOS基本一致,不同之处在于05_UserBoard文件中的RT-Thread源码被替换为了Os_Self_API.h文件,在07_AppPrg中增加了threadauto_appinit.c文件。其中,Os_Self_API.h头文件是按照RT-Thread中的原函数进行重映射的接口文件,threadauto_appinit.c则用于存放RT-Thread操作系统中的自启动线程函数app_init,即BIOS程序中函数OS_start的入口参数,对于用户而言,app_init则是进行应用程序开发的快速入口。

3 基于D1-H实现RT-Thread驻留的关键要素

在GEC架构下,BIOS与user在物理空间中是相互独立的软件工程,但两者的代码和变量都是在MCU的同一存储空间下运行和定义的,若要成功实现RT-Thread的驻留,首先要对D1-H的flash与双倍速率同步动态随机存储器(double data rate,DDR)进行合理分区,从而保障RT-Thread正常调度运行。

3.1 片外flash与DDR的空间划分

flash区主要用于保存工程编译后的机器码,包含了程序代码、中断向量和常数等。为确保用户层的可扩展性,在满足BIOS程序基本存储空间需求后,将flash存储空间的剩余量一并划分到user程序下。为进一步提高BIOS程序和user程序对flash资源的利用率,依据紧凑划分原则,从片外flash的零地址開始为BIOS程序分配空间,并将BIOS程序的结束地址作为user程序的起始地址。同时,为了保持各自的独立性,防止user程序在开始写入时出现意外擦除BIOS程序的情况,需要将BIOS程序与user程序各自的代码分别存放在不同扇区。片外flash划分样例如图2所示,1~n扇区为BIOS程序,n+1扇区及后续空间均为user程序。

DDR区主要由以下数据段组成:存放初始化不为0的全局变量或静态变量的data段、存放未初始化或初始化为0的全局变量或静态变量的bss段、存放临时局部变量的heap段以及保存函数变量和参数的stack段。基于片外flash的划分要点,将DDR中的BIOS程序和user程序进行独立分区,如图3所示。该划分方式的弊端表现为:BIOS程序运行结束后,释放stack段的存储空间且不再使用,在一定程度上造成了DDR资源的浪费。因此,在独立分区的基础上,保留BIOS程序和user程序的data段、bss段和heap段,将各自的stack段合并后设置为共享区,如图4所示,实现user程序对stack段的二次使用,从而有效提高DDR存储资源的利用率。

3.2 BIOS程序与user程序的衔接

BIOS程序与user程序之间的衔接由以下两个方面组成:为确保user程序的正常运行,需要由BIOS程序提供正确引导;当user程序运行异常时,需要由BIOS提供有效方法使得user程序顺利回退至BIOS程序。

1)BIOS程序对user程序的正确引导 当BIOS程序烧录至MCU内部后,通过特定标识信息对片外flash中的user程序进行检测,若user程序存在,则由BIOS程序提供引导,将user程序拷贝到DDR,通过链接文件获取user程序的运行地址和代码量,并将PC指针指向user程序的复位函数,在该函数内利用内嵌汇编加载并跳转至user程序的运行地址,即可完成BIOS程序到user程序的跳转,执行过程如图5所示。为了避免标识信息在热复位后被清除,本文将该标识信息存放于user程序bss段与data段之间的独立范围内,保证了BIOS程序对user程序引导的可靠性与通用性。

2)由user程序返回BIOS程序 通过在短时间内对MCU进行6次热复位,且每次触发间隔控制在1 s左右,即可实现user程序主动返回至BIOS程序;若触发次数不足6次,则清空已触发次数并继续运行user程序,具体执行流程如图6所示。

由于D1-H内部不包含识别冷复位与热复位的控制状态寄存器,本文利用热复位不会导致存储器内容丢失的特性,取消启动文件中的bss段清零操作,对未初始化的全局变量进行判断,若初值改变,则返回冷复位标志,反之则返回热复位标志。

3.3 底层驱动的驻留与调用

底层驱动的驻留是指在BIOS程序中将底层驱动封装为构件,通过应用程序编程接口(application programming interface,API)为用户在user程序中提供函数调用服务。本文将底层驱动函数地址按照顺序依次存放在全局指针数组ComponentFun,利用“attribute”关键字将该数组固定存储在BIOS程序的“.component_list”数据段,并使用缺省函数reserved_func为接口函数的更新与扩充预留空间。在user程序中,按照全局指针数组ComponentFun中的存放顺序,对接口函数的函数名、返回值类型和参数类型等进行重定义,通过全局指针数组的固定索引调用相应函数。具体实现方法如下:

__attribute__((section (".component_list"))) void *

ComponentFun[MAP_SECTORSIZE/2] = {

(void*) gpio_init,

(void*) gpio_set,

(void*) reserved_func,

}

#define 函数名((接口函数声明指针表达形式)(全局数组[序号]))

4 RT-Thread驻留测试

RT-Thread的驻留测试工程在AHL-GEC-IDE开发环境和基于玄铁C906内核的D1-H应用处理器上进行,首先运行BIOS程序,将RT-Thread驻留在D1-H的外接flash中,随后运行user程序,并分别对线程间的事件、互斥量、信号量以及消息队列四种同步与通信方式进行测试。

4.1 flash和DDR的实际空间划分情况

D1-H外接NAND Flash[12]大小为256 MB,分为131 072个扇区,用于存放程序、常数以及中断向量;外接RAM为双倍速率同步动态随机存储器第三代DDR3[13],大小为512 MB,用于存放全局变量、静态变量以及堆栈空间。测试工程中NAND Flash采用图2所示划分方式,DDR3采用图4所示划分方式,RT-Thread驻留在BIOS后,NAND Flash与DDR3的空间划分如表2所示。

4.2 RT-Thread驻留后程序启动流程分析

当RT-Thread驻留到BIOS后,从D1-H上电复位到RT-Thread对用户线程进行调度主要包含以下五个阶段:启动内部固化引导程序BROM、启动第二阶段程序SPL、启动BIOS、由BIOS跳转至user、启动user以及启动RT-Thread,其启动流程如图7所示。首先,D1-H上电复位后,按照内部机制从固化在片内ROM处的引导程序BROM开始执行,接着启动SPL,通过自定义程序完成对时钟、串口以及DDR3的初始化,在将BIOS程序复制到DDR3的空间地址0x4000_0000后,开始BIOS的启动,由硬件从NAND Flash的起始地址取出中断向量表的第一个表项,赋值给堆栈指针寄存器SP进行初始化,程序计数器PC加载中断向量表第二个表项,启动BIOS复位向量,接着对DDR3中的各个数据段完成初始化,然后在主程序中調用user_jump跳转至user程序。user程序的启动过程与BIOS程序的启动过程基本一致,唯一不同的是,user在主程序中调用函数rtthread_startup启动RT-Thread,包括对板级硬件初始化、延时阻塞列表初始化、调度器初始化、创建自启动线程和空闲线程、启动调度器,然后由RT-Thread完成对用户线程的调度运行。

4.3 驻留运行测试

在user程序中分别对事件、互斥量、信号量和消息队列四种线程同步与通信方式进行功能测试。RT-Thread驻留测试工程的运行结果如表3所示。测试结果表明,RT-Thread成功驻留于BIOS程序,并在user程序中按照启动流程顺利实现了创建线程、启动线程、延时调度以及四种同步与通信等功能,验证了RT-Thread驻留方法的可行性。

a)事件测试工程。在串口中断中设置红灯事件,改变红灯亮暗。b)互斥量测试工程。红、绿、蓝三种颜色的小灯按照红灯5 s、绿灯10 s、蓝灯20 s的顺序单独实现亮暗,每种颜色的小灯线程之间通过锁定单色灯互斥量独立占有资源。c)信号量测试工程。通过串口输出线程申请、等待和释放信号量的响应过程。d)消息队列测试工程。通过消息队列实现线程间的消息传递。触发串口接收中断后,通过串口发送的数据帧被存放到消息队列,消息队列接收线程每隔1 s从消息队列中获取消息并通过串口打印出消息内容和当前消息队列中的消息量。

5 结束语

为了更好地发挥RT-Thread对嵌入式软件开发的应用支撑,本文在GEC架构的设计基础上,实现了国产RISC-V应用处理器D1-H的GEC软件框架,深入剖析了实现RT-Thread驻留的关键要素,提出了BIOS程序正向引导与user程序顺利回退两种机制来有效实现BIOS程序与user程序之间的衔接,给出了具体的存储空间划分、底层驱动驻留与调用的实现方法。后续将进一步对RT-Thread架构中的协议栈、图形库以及虚拟文件系统等组件进行研究,实现用户程序功能的扩展。

参考文献:

[1]Wang K C.Embedded real-time operating systems[M].Berlin:Springer,2017:401-475.

[2]杨静远,黄保垒,杨弋.一种分区操作系统两态下错误号处理策略[J].信息技术与信息化,2021(4):169-170.(Yang Jingyuan,Huang Baolei,Yang Yi.A partition operating system error number processing strategy under two states[J].Information Technology and Informatization,2021(4):169-170.)

[3]Chen Tanhong,Li Huiyong,Niu Jianwei,et al.Embedded partitioning real-time operating system based on microkernel[C]//Proc of IEEE International Conference on Computational Science and Engineering and IEEE International Conference on Embedded and Ubiquitous Computing.Piscataway,NJ:IEEE Press,2019:205-210.

[4]白曦,王俊.基于分區操作系统的机电软件架构研究与应用[J].信息通信,2019,33(10):95-96.(Bai Xi,Wang Jun.Research and application of electromechanical software architecture based on partitioned operating system[J].Information Communication,2019,33(10):95-96.)

[5]邱祎,熊谱翔,朱天龙.嵌入式实时操作系统:RT-Thread设计与实现[M].北京:机械工业出版社,2019:36-47.(Qiu Wei,Xiong Puxiang,Zhu Tianlong.Embedded real-time operating system:design and implementation of RT-Thread[M].Beijing:China Machine Press,2019:36-47.)

[6]Bansal S,Kumar D.IoT ecosystem:a survey on devices,gateways,ope-rating systems,middleware and communication[J].International Journal of Wireless Information Networks,2020,27:340-364.

[7]全志开发者社区.D1-H芯片介绍[EB/OL].(2021-04-27).https://d1.docs.aw-ol.com.(Allwinner Online Developer Community.Introduction of D1-H chip[EB/OL].(2021-04-27).https://d1.docs.aw-ol.com.)

[8]王宜怀,李跃华,徐文彬,等.嵌入式技术基础与实践 [M].6版.北京:清华大学出版社,2021:51-57.(Wang Yihuai,Li Yuehua,Xu Wenbin,et al.Embedded technology foundation and practice[M].6th ed.Beijing:Tsinghua University Press,2021:51-57.)

[9]张晓宇.实时操作系统内核硬件化的研究与实现[D].沈阳:沈阳工业大学,2019.(Zhang Xiaoyu.Research and implementation of hardware for real-time operating system kernel[D].Shenyang:Shen-yang University of Technology,2019.)

[10]Lyu Pan,Li Hong,Qiu Jinsong,et al.Cyborgan OS:a lightweight real-time operating system for artificial organ[J].Security and Communication Networks,2020,2020:article ID 8871626.

[11]Zhang Haitao,Chen Lirong,Luo Lei.Formal modeling and verification of the sequential kernel of an embedded operating system[C]//Proc of the 18th International Computer Conference on Wavelet Active Media Technology and Information Processing.Piscataway,NJ:IEEE Press,2021:553-569.

[12]李中,周加谊,曹睿.基于NAND Flash固态硬盘的坏块管理方法 [J].电子设计工程,2022,30(23):24-27,32.(Li Zhong,Zhou Jiayi,Cao Rui.Bad block management method based on NAND Flash solid state drive[J].Electronic Design Engineering,2022,30(23):24-27,32.)

[13]黄姣英,赵如豪,王琪,等.基于FPGA的DDR3 SDRAM控制器设计[J].现代电子技术,2022,45(22):68-74.(Huang Jiaoying,Zhao Ruhao,Wang Qi,et al.Design of DDR3 SDRAM controller based on FPGA[J].Modern Electronic Technology,2022,45(22):68-74.)