高 政,叶乐清,郑小芳,肖 柳
(1.杭州义益钛迪信息技术有限公司,浙江 杭州 310019;2.杭州腾熠科技有限公司,浙江 杭州 310051;3.浙江大华技术股份有限公司,浙江 杭州 310051)
基于MCU的硬件终端成本低且功耗小,被广泛应用于物联网领域。在传统应用场景中,MCU由于受到存储、主频以及外设等资源的限制,无法完成较复杂的操作和计算。传统终端的系统服务和应用软件集成在一套程序中,更新应用软件时整套软件都需修改,操作风险较高。随着物联网场景应用要求的不断提高,客户对MCU的软件灵活性和开发效率提出了更高的要求。当大规模定制应用时,服务商无法高效满足需求。另外,终端在实时性要求较高的场景中需承担更多的边缘计算任务。
IC行业快速发展,MCU性能不断提高,提供服务的能力越来越强,需用新的思路来设计MCU软件。文献[1]设计和研究了嵌入式Linux系统的可重用组件,提出了一个基于XML的原型数据库,减少了存储所需的时间,提高了系统的整体效率。文献[2]提出采用一种基于组件的轻量级方法来工程化嵌入式,以中间件方式实时控制软件。文献[3]提出了一种基于微控制器的软件架构,主要应用于物联网(IoT)捕获数据卡。文献[4]利用Docker容器化技术设计了在线实验系统,为用户提供了良好的实验灵活性。文献[5]提出以软件构件的形式封装系统软件,以标准的接口形式呈现给应用软件,方便了系统的集成和维护。基于以上文献基础,提出了一种基于MCU的物联网关容器化软件设计方法。该方法中,MCU利用分散加载技术分离系统服务和应用软件,以容器化方式将应用软件划分为多个应用模块,且各模块间可独立开发和升级。由于系统服务和应用软件的解耦,开发者可集中精力于各应用模块的开发而无需关注系统支持,因此可缩短应用软件开发周期,提高测试和部署效率。
基于MCU的物联网终端系统包括硬件、硬件控制层、内核层以及应用层,具体结构如图1所示[6]。其中,内核层和硬件控制层统称系统服务,应用层统称应用软件。
如图1所示,传统模式中,系统服务和应用软件共同组成了物联网终端内部MCU的整套程序。当更新MCU应用软件时,需在整套程序基础上修改应用软件,编译链接生成可执行代码并下载到MCU中。
图1 传统物联网终端软件构成图
利用所提方法分离系统服务和应用软件,应用软件以容器化方式划分为多个模块,且彼此之间可独立开发和升级,具体如图2所示。在系统服务基础上搭建资源中台,屏蔽硬件差异,为应用软件提供资源。以容器化方式将应用软件划分为多个应用模块,每个应用模块可放在容器中独立运行。每个应用模块可从资源中台获取资源和数据,如读操作、写操作以及数据等[7]。MCU启动后,以分散加载方式先启动系统服务,逐步启动容器中的应用模块。应用软件需更新时,只需在开发环境中修改应用模块,借助编译环境生成可执行文件下载到原有容器即可。
图2 系统服务和应用软件分离
MCU软件的设计分离了系统服务和应用软件。其中,系统服务负责系统框架、执行逻辑以及资源控制,应用软件在以容器化方式划分为多个模块,每个独立开发,负责边缘计算服务。
在充分理解MCU运行机制的基础上,搭建系统服务框架,定义资源中台。系统服务包括程序存储区域、资源中台、外设驱动、运行库、外设资源、启动和加载配置描述等[8]。软件设计框架和执行流程如图3所示。
图3 软件设计框架和执行流程
程序存储区为系统服务和各个应用模块分配程序存储区域,每个存储区域有固定大小和起始地址,升级时可按存储区域升级。资源中台用于定义所有的函数地址、变量以及数据索引,便于使用系统服务和应用软件。外设驱动可屏蔽硬件差异,操作MCU资源,包括IO和通信等。运行库是MCU运行时所需的驱动库、业务库以及协议库等。外设资源是MCU的固有资源,包括内存、存储、中断、定时、通信以及IO等[9]。启动和加载配置描述应用程序存储区、资源中台配置以及系统分散加载项等相关参数,保证系统服务和应用软件独立开发,统一运行。
系统服务包括轮询应用和定时应用。轮询应用在主循环中执行,定时应用在中断服务中执行。开发系统服务时,需用加载配置项描述服务在应用程序存储区的位置和资源中台配置,保证系统服务可独立更新,且可调用系统资源。应用软件开发所用的资源中台配置需与此配置相同。
以轮询应用为例,介绍MCU软件执行流程。首先,在系统服务编译时确定资源中台在内存中的位置及各种资源在中台中的位置,MCU根据加载项启动,执行初始化工作,包括定义各类应用程序存储区等。其次,MCU根据资源中台中定义的轮询应用地址和定时应用地址,在主循环中以指针方式执行多个轮询应用,在中断服务中以指针方式执行定时应用。最后,执行到某个应用模块时,MCU运行指针从资源中台跳转到应用模块存储区执行应用模块函数体,完成应用软件的业务功能[10]。
不同的应用软件类型需要不同的开发模板。以轮询应用为例,当某个应用模块需更新时,使用具备与系统服务相同资源中台配置的开发环境修改模块代码,编译生成可执行目标文件,并将其下载到指定程序存储区,MCU按已有机制执行更新后的应用模块。
为验证方法的可行性,设计了MCU作为STM32F207的最小系统,启动模式设置为BOOT0。在MCU中内置app_fuc1和app_fuc2两个应用模块,开发环境为keil,描述如何实现应用软件app_fuc与系统服务的独立开发和升级。
在MCU系统服务开发环境中,分散加载包括系统服务程序存储地址描述和资源中台配置描述,描述如下:
以上描述中,定义了系统服务在程序存储区的存储位置和运行时在内存中的位置,规定了资源中台的起始地址和长度。
在启动文件中描述资源中台的内部定义,保证系统服务和应用程序的全局使用,描述如下:
app_fuc1_adr占用4个字节,为app_fuc1函数的执行地址,即app_fuc1应用模块的存储地址;app_fuc2_adr占用4个字节,为app_fuc2函数的执行地址,即app_fuc2应用模块的存储地址。系统服务初始化时,为app_fuc1和app_fuc2分配起始地址的描述如下:
app_fuc1_adr=fuc1应用程序存储地址;
app_fuc2_adr=fuc2应用程序存储地址;
在系统服务的循环执行中,以函数指针方式执行两个应用,描述如下:
((void (*)())app_fuc1_adr)();/*执行应用程序1*/
((void (*)())app_fuc2_adr)();/*执行应用程序2*/
此处系统服务已完成对应用模块app_fuc1和应用模块app_fuc2的执行。
在应用模块开发环境中,分散加载包括应用模块程序存储地址描述和资源中台配置描述。为保证资源中台使用的标准性和统一性,其所使用资源中台描述与系统服务中的保持一致,描述如下:
在启动文件中对资源中台的内部定义与系统服务中的保持一致,描述如下:
在应用模块开发环境中,应用程序存储地址和资源中台内部定义等配置完毕后,只需开发服务应用函数app_fuc。main函数无实质性操作,开发主体描述如下:
按照上述实现方法,设计了基于MCU的物联网关并应用在动力环境监控场景中。该网关具备4个串口、8路数字量输入接口、4路模拟量输入接口以及1路网口。每个端口可升级配置为任意应用模块,从而完成每个端口的功能。选取4个端口进行验证,端口接入信息如表1所示。
表1 物联网关端口接入设备列表
开关电源为标准电总协议,应用模块为app_com1;智能电表为标准MODBUS协议,应用模块为app_com2,烟雾传感器为标准高低电平信号,应用模块为app_DI1;温度传感器为标准0~5V电压信号,应用模块为app_AI1。各个应用模块以轮询方式实现对端口数据的采集和解析,并将其封装为上行数据,产品应用场景如图4所示。
文中基于MCU的物联网关容器化软件设计方法,利用分散加载技术,分离系统服务和应用软件,将应用软件以容器化方式划分为多个应用模块,且模块间可独立开发和升级,提高了应用程序定制化开发效率。该方法在运营商通信机房的动力环境监控领域中广泛使用,设备维护效率较高,且可在其他领域进行推广应用。
图4 物联网关应用场景