关于GD32构建软硬件自主可控的嵌入式实时控制系统的介绍和应用

描述

本文基于GD32微控制器和RT-Thread实时操作系统,构建了一种软硬件自主可控的嵌入式实时控制系统。研究了RT-Thread操作系统在GD32芯片开发板上的移植方法和驱动程序改写,并编写多任务应用程序测试了系统的运行稳定可靠。为嵌入式控制系统的发展提供了一种技术实现途径。

引  言

由微控制器和实时操作系统共同构成的嵌入式实时控制系统在工业生产、交通运输、能源供给、国防装备等众多领域被广泛使用,是实现自动化技术的核心中枢。目前,国内所采用的嵌入式实时控制系统大多基于国外的微控制器芯片和软件产品,在“棱镜门”和“Stuxnet病毒”事件后关键领域所采用的嵌入式系统安全问题已被国内用户所重视,发展自主可控、安全可靠的嵌入式实时控制系统已成为必然趋势。

伴随微控制器芯片和实时操作系统软件的不断发展和日趋成熟,基于国产软、硬件产品构建自主可控的嵌入式实时控制系统已经具备实现条件。本文采用具有ARM Cortex-M3内核的微控制器GD32F207芯片和RT-Thread实时操作系统建立了一套完全国产化的嵌入式实时控制系统,为国产自主可控嵌入式实时控制系统的建立及应用进行了技术经验总结和有益探索。

01

嵌入式实时控制系统的构成

嵌入式系统与通用计算机系统在体系结构上具有相似性,都是由主控制器芯片和外围功能芯片构成硬件电路基础,再由可提供底层硬件操作功能的软件作为操作系统,用户最终通过操作系统对硬件进行访问和控制;嵌入式系统通常针对某个特定控制任务设计,因而具有实时处理能力、可靠性的要求,通用计算机的处理适用范围广,因此更注重兼容性而实时处理能力较弱。

1.1 GD32F207微控制器与开发板

GD32F2系列微控制器芯片为基于ARM Cortex-M3内核架构设计的产品,本文中采用的GD32F207ZET6芯片主频最高可达120MHz,具有128KB的SRAM和512KB的Flash存储容量,并且提供UART、ADC、以太网和LCD控制器等众多外设功能接口,可以很大程度减少所需的外围功能电路配置。Colibri-F207ZE开发板是基于该芯片设计的一款“口袋实验室”类型产品,如图1所示,在板子上有与Arduino平台引脚布局兼容的引出IO接口之外,还包括TFT显示屏接口、2个用户按键、3个LED指示灯、1个USB串口和板载GDLINK调试器功能。本文中将以此开发板作为硬件平台构建嵌入式控制系统。

计算机

图1 Colibri-F207ZE开发板

计算机

图2 RT-Thread操作系统层次结构

1.2 RT-Thread实时操作系统

RT-Thread嵌入式实时操作系统的开发始于2006年,并且遵循GPLv2+的版权许可协议。在经过多年的能源、仪表、车辆等行业广泛使用后,RT-Thread已经被验证是一款稳定、可靠的嵌入式实时操作系统。从文献[6]中对RT-Thread与国际主流嵌入式实时操作系统进行的比较中,也可看出其具有优越的性能。RT-Thread系统的结构层次框图如图2所示,其中内核层(Kernel)是RT-Thread的关键部分涉及时钟管理、实时调度、任务切换等核心操作;组件层(Components)主要提供Shell交互、文件系统、协议栈等附加操作功能;在内核层与硬件之间是用于系统移植的软件接口部分(Porting),其实现了操作系统对于硬件的各种具体操作功能。在本文中以最新发布的 RT-Thread 2.1.0版作为移植对象进行分析、代码修改并最终实现与Colibri-F207ZE开发板共同构成嵌入式实时控制系统。

02

RT-Thread在GD32微控制器上的移植

RT-Thread操作系统已经在GitHub上做了代码托管,因此可直接从GitHub上下载获取到RT-Thread 2.1.0版的源代码压缩文件包[7]。本文中采用MDK 5.16a版本的ARM开发工具进行移植工作,并需要在MDK的Pack Installer中安装GD32F2系列芯片的DFP支持包。在移植工作中完成了RT-Thread操作系统的串口通信和LED灯驱动功能,可实现RT-Thread与主机之间的Shell交互操作和对测试程序中运行任务的直接观察。

2.1 RT-Thread目录结构的转换

打开下载得到的RT-Thread源代码文件包可看到按代码功能分类的目录结构,各文件夹所包含的内容和用途分别为:

bsp文件夹:板级支持包,包含针对特定型号微控制器板卡和外部设备的驱动程序。

components:对应RT-Thread操作系统的组件层,包含RT-Thread核心功能之外的大部分附加操作功能以及硬件设备驱动模型。

documentation:RT-Thread编程风格说明,对开发人员和用户掌握RT-Thread提供指引。

examples:针对RT-Thread操作系统的应用和测试程序示例。

include:RT-Thread操作系统使用的头文件,可供外部应用程序调用。

libcpu:CPU支持包,包含对各种常见CPU的底层驱动程序,大部分为汇编语言开发。

src:对应RT-Thread操作系统的内核层,包含RT-Thread实时调度、时钟管理、内存分配、线程管理等全部核心功能。

tools:Scons构建脚本文件,包含用于不同开发工具的各种脚本执行文件。

根据RT-Thread源代码文件包中各个文件夹的用途,结合GD32芯片所提供的外设固件库、CMSIS配置文件和Colibri-F207ZE开发板的板级支持包构建基于GD32F207芯片和RT-Thread操作系统的目录结构,如图3所示。其中App文件夹中包括RT-Thread的启动文件startup.c和用户开发的应用程序;GD32F207ZET6文件夹中包括硬件相关的两个子文件夹,Colibri_BSP中是开发板的外设驱动程序,GD32F20x_StdPeriph_Driver中是GD32芯片所提供的外设固件库,芯片驱动、配置和中断处理文件;Obj文件夹中为MDK所建立的工程文件和存放编译后得到的axf文件;RT-Thread210文件夹中包含RT-Thread操作系统的各软件模块,其为直接从源代码文件包中相关内容复制而来。

计算机

图3 基于GD32芯片构建的RT-Thread系统目录结构

2.2 项目工程的建立与驱动程序改写

在完成上述目录结构的构建后,需要使用MDK开发工具将RT-Thread源代码和GD32芯片的相关文件有机结合起来,实现RT-Thread操作系统在Colibri-F207ZE开发板上的移植工作。在MDK工具内部各个文件按照逻辑关系进行分组管理,这里以GD32开头的组和嵌入式系统硬件相关,以RT开头的组和操作系统软件相关,如图4所示。这种分组结构可有效实现软硬件隔离,便于日后硬件部分或软件部分代码的升级替换工作。

2.2.1 软硬件配置与代码修改

在RT-Thread和GD32的配置中采用宏定义方式实现对所需软件功能模块的条件编译和芯片性能参数设置,以达到对嵌入式系统软、硬件裁剪和配置的目的。因此,在移植过程中需要对这些宏定义进行有选择的设置。

修改system_GD32f20x.c文件,该文件中主要实现GD32的系统时钟和AHB、APB总线上挂接各部件的时钟树配置,本文中将系统时钟设置为72MHz。

修改colibri_board.h文件,该文件主要用于设置GD32芯片内、外部RAM的容量,根据本文中所使用的GD32F207ZET6芯片,将内部RAM容量设置为128KB;开发板未扩展外部RAM,将对应的宏定义GD32_EXT_SRAM设置为0。

修改rtconfig.h文件,该文件主要用于RT-Thread操作系统的参数配置以及软件功能模块的裁剪。用户可根据需要设置,保留的软件功能模块越多,则编译后的HEX文件尺寸越大且需要的运行RAM越多。本文中将RT-Thread最大优先级RT_THREAD_PRIORITY_MAX设置为16;每秒节拍数RT_TICK_PER_SECOND设置为100;启用了控制台和Shell交互功能RT_USING_CONSOLE和RT_USING_FINSH以方便应用程序调试。

计算机

图4 对GD32芯片和RT-Thread系统文件的分组管理

2.2.2 设备驱动程序的改写

编写驱动程序是操作系统移植过程中的重要一步,其用于实现软件对硬件的最终操作。在RT-Thread中驱动程序属于Porting层采用了统一的设备驱动模型框架,可以被应用程序通过标准接口函数访问和调用,在文献[6,8,9]中对RT-Thread设备驱动框架的构成进行了说明。由于GD32F2系列微控制器与STM32微控制器在系统结构上具有相似性,因此在本文中通过对RT-Thread源代码文件包中/bsp/stm32f10x/drivers子文件夹内驱动程序进行改写的方法实现Colibri-F207ZE开发板上串口通信和LED灯的驱动程序。对于GD32芯片上其它功能接口的驱动程序,都可根据需求而参考此种方法进行改写。

以实现串口通信功能的驱动程序改写为例,应用程序通过I/O设备模块中的标准接口函数和设备驱动程序中的函数二者之间映射关系实现对底层I/O设备控制,如图5所示。其中标准接口函数不需修改,由RT_DeviceDrivers分组中的serial.c文件实现;而串口驱动程序则由GD32_BSP分组中的colibri_board_usart.c文件实现,需要对相应的功能函数和配置进行修改。改写的内容主要包括替换片上外设访问层头文件、实现串口通信功能的芯片管脚定义、rt_hw_usart_init()函数中的串口参数设置和通过rt_hw_serial_register()函数将串口设备注册到RT-Thread设备驱动框架中,即实现标准接口函数与串口设备之间的关联。需要注意的是GD32与STM32两种芯片在各自外设固件库中提供的结构体定义和函数功能是类似的但是名称不一致,需要在移植过程中进行修改,表1列出了串口驱动程序colibri_board_usart.c文件中需要修改的结构体和函数名称。得益于Cortex内核遵循的CMSIS接口标准和RT-Thread所采用的设备驱动框架机制,对设备驱动程序只需做上述少量改写即可完成不同芯片间的移植工作。

计算机

图5 应用程序操作底层设备的接口函数映射

芯片 STM32 GD32 定义位置
结构体 USART_TypeDef USART_InitPara gd32f20x_usart.h
GPIO_InitTypeDef GPIO_InitPara gd32f20x_gpio.h
NVIC_InitTypeDef NVIC_InitPara gd32f20x_misc.h
函数 USART_Cmd USART_Enable gd32f20x_usart.h
USART_ITConfig USART_INT_Set
USART_GetITStatus USART_GetIntBitState
USART_ClearITPendingBit USART_ClearIntBitState
USART_GetFlagStatus USART_GetBitState
RCC_APB2PeriphClockCmd RCC_APB2PeriphClock_Enable gd32f20x_rcc.h

表1 串口驱动程序中需要修改的结构体和函数名称

2.3 RT-Thread测试应用程序编写

开发板在上电后GD32芯片复位,通过文件startup_gd32f20x_cl.s中复位地址处的加载指令调用RT-Thread系统main()函数(位于startup.c文件中),在完成开发板、RT-Thread系统内核、定时器、用户任务和空闲任务等的初始化后,通过rt_system_scheduler_start()函数启动RT-Thread调度器实现对各个用户任务的实时调度。为验证RT-Thread在Colibri-F207ZE开发板上的移植是否成功,使用rt_thread_init()函数建立两个用户任务分别控制两个LED灯按照0.5秒和1秒的周期闪烁。

03

嵌入式实时控制系统的测试

在完成RT-Thread在Colibri-F207ZE开发板上的移植和测试程序编写后,将经过MDK编译得到的axf文件下载到开发板上运行。通过上位机的串口通信工具可以和RT-Thread提供的Shell进行交互操作,并使用相应指令观察RT-Thread系统运行和RAM的使用情况,如图6所示。可以看到共有4个任务在运行,其中LED_GREE和LED_RED是控制LED灯闪烁的用户任务,tshell和tidle分别是系统的shell交互任务和空闲任务;在RT-Thread中注册有一个设备,就是提供Shell功能的uart1串口。通过该测试程序,表明RT-Thread已经在Colibri-F207ZE开发板上稳定运行,实现了预期的移植效果。

计算机

图6 RT-Thread系统Shell交互界面

结  语

本文基于GD32微控制器和RT-Thread实时操作系统构建了一种嵌入式实时控制系统,其具有软硬件自主可控、安全可靠的特点为工业生产、国防装备等军民应用的关键领域提供了有效解决方案。通过本文的研究和探索,在自主可控嵌入式实时控制系统的构建方面积累了技术检验,为后期配套应用开发奠定了坚实基础。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分