嵌入式设备的容器化App
Posted 姚家湾
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了嵌入式设备的容器化App相关的知识,希望对你有一定的参考价值。
“尽量简单,但是不能太简单” -爱因斯坦
2007年Apple全球开发者大会,当史蒂夫·乔布斯第一次将我们介绍给iPhone时,他们永久性地改变了移动应用设计师和开发者的游戏规则。 Apple 公司在Iphone 中引入了App 和App store的机制,使智能手机突破了Nokia 封闭式的手机开发模式。全球首款商用android设备HTC Dream于2008年推出。Google 公司开源android OS 采取了类似的方式,从而建立了移动智能手机的应用生态系统。在这之前,手机上的应用软件几乎是手机厂商自行开发的。
今天,手机中App的概念将延伸到云端和边缘设备应用程序。可以设想未来你编写的应用程序可以部署在云端,也可以部署在任意一个边缘设备上运行。配合5G时代的高速网络。这样的App 将完全实现“一次编程,任何地方部署”的理想。我们将这种App 称为“云端/边缘App”。,
云端/边缘APP正处于了早期智能手机建立App应用生态相似的发展阶段。未来的云端应用和边缘化应用程序也将会采纳类似智能手机App和App 市场的模式。形成云端/边缘APP 的生态系统。
随着技术的飞速发展,云端/边缘 App的生态系统会有更多的选择。人们会更多地使用开源技术。目前看来下面几个特点是已经是非常明显的了。
容器化(Dockerizing)
所谓容器,网络上已经有许多的描述,我们就不在这里重复了。本质上,所谓容器化就是将应用程序,以及应用程序的运行环境,依赖项打成一个包。他们一起被安装和移动,删除。这就是好比你将在自己熟悉的家具,生活用品装入一个集装箱,随着你一同搬家。为你提供一个适合的小环境。使你不再需要过多地去适应房东的大环境。到哪里都有“家的味道”。边缘设备的App 不像移动终端那样仅使用单一的程序设计语言(例如android 的Dalvik)和单一的API。我们可以使用javascript,python,C++ ,GO 多种程序设计语言和各种软件平台(例如数据库,nodeJS,node-RED等等)。目前看到的GE predix,Harting MICA ,mbed LinuxOS等产品都普遍采用容器技术。
松耦合
所谓松耦合,就是应用程序和系统,以及它们相互之间的依赖将是松散的。它意味着:
程序调用更多的不再是函数调用,而是基于web socket,消息的通信。大家了解,传统的应用程序通过API 来调用操作系统和其它程序的功能,编写应用程序需要使用大量的库。静态或者动态链接这些库。各种语言都需要提供一套库函数。socket,和消息接口提供了各种语言的统一接口。消息通信机制实现了所谓异步通信的方式,App 在不知道接收应用程序的状况下就能够发送消息。这給App 的开发带来了便捷。
web化人机界面
一个应用程序由三部分组成:主控程序,人机界面(HMI),配置。传统的工业电脑的HMI 和配置是在监视器的主界面上实现的。例如可以采用Qt 编程环境来开发工业控制界面。大多数云端和边缘设备不会像移动终端设备那样带有LCD触控屏,云端和边缘设备App采纳基于web 的HMI的人机界面将更加合适。具体实现时,在云端和边缘App 程序中将会嵌入一个web 服务器,提供App运维和人机界面的web 网页。
概念模型-edge device
嵌入式设备App 的容器化看起来挺复杂。具体实现考虑的问题千头万绪。从《设计心理学2》的一书给我们一些启发。世界本来就是复杂的,概念模型是用来组织和理解那些本来很复杂的事物的非常重要的工具。它让我们了解事物是如何运作的,设计师的首要工作是为人们提供适当的概念模型。我们计划通过一个原型机的研发,形成边缘设备容器化App 生态系统的概念平台。
为此,我们开始了一个边缘设备软件的开发原型项目(Edge Device),目标是在一个小型cortex-A SoC 嵌入式平台上开发一个容器化APP 环境。构建边缘设备容器化APP 的概念平台。它具有如下特点
-采用 linux OS 。
-使用docker 作为容器管理工具。
-使用MQTT 作为异步消息平台
-使用json rpc 作为web RestFull api 接口,制定了web RestFull api 接口规范
-使用web socket 推送的大容量数据。
-使用cortex-M/mbed OS 模块作为IO扩展模块,使用USB serial 实现主 SoC和IO模块之间的硬件通信接口。
-基于NodeJS 的控制面板(dashboard)
-基于web api 的基础服务
-规范的App 开发框架
-规范的MQTT 主题命名空间规范
该设计原型将会展示如何在一个小型嵌入式设备上实现容器化App ,并且测试其运行效率,开发,部署的便捷性,安全性和可靠性。
容器化App 模板
一个容器化的APP 由下面及部分组成
1 Web Restfull Server/Client
Web Server 向其它App 提供web restfull服务,Web Client 用于访问其它App 的web Rest full服务
2 MQTT Client
用于和外界的消息通信
3 web socket server/client
通过web socket 和外界交换大容量数据。
4 主程序
程序的功能实现
5 库
支持库
对于C++,NodeJS javascript,Node-RED 程序可以添加一个符合APP 模板的 web server。但是对于MQTT ,Influx DB 这样的应用程序,如需要 添加一个嵌入式web server,可以额外增加一个C++ 嵌入式web 服务器,或者lighttpd 服务器。实现对MQTT brocker和influxDB 的配置。
App 与外部接口方式
容器化的App 通过Web API 和类似MQTT 的消息两种方式向外部提供服务。Web RESTFull API 是request/response方式的同步服务 ,而MQTT 是松耦合的异步消息。比个不太恰当的比喻,web API 类似于函数调用,比如读取ADC 值,读取MODBUS 的数据等等,而MQTT 相当于事件中断,比如按下了按键,外部信号的电平变化都会发布一个消息给订阅的App。
例如 最简单的例子:求和,两种方式为
web API
request: GET /sum? 3&4
response :result:7
MQTT
publish topic:“sum”,parameter:[3,4]
subscribe topic:”result”
一个云端/边缘 App 平台要提供一套良好定义的App 规范和MQTT 命名系统。
Web socket 实时推送大量数据
web socket 是在http 协议下发起的TCP/IP 数据交换,实现连续实时数据推送。比如,在振动数据采集系统中,一旦ADC 转换器启动之后,IO 子系统会连续发送采集数据到App。这种场合如果使用web Restfull API 只能由App 不断地 request Data,效率非常低。这时使用web socket 方式更合适。
APP 的 web service API
Web API 是云端/边缘设备App 提供同步服务的接口。一个APP 包括了三个部分web API接口:
1 web 远程过程调用API(web socket API)
2 配置 API (configuration API)
3 用户人机界面API(HMI API)
在我们的试验系统中,web API 采用了http RPC协议。RPC 的全称是远程过程调用(Remote procedure call),它是一个比较古老的协议。伴随着TCP/IP 协议的出现就出现了。现在RPC 协议可以在许多协议上实现。信息格式更加倾向于XML和json格式。例如在json rpc 协议中:
--> "jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": 1
<-- "jsonrpc": "2.0", "result": 19, "id": 1
App配置页面和用户人机交互界面
大多数App 在具体使用中需要做一些配置,例如,在一个简单的MODBUS控制应用中,要根据连接的传感器的不同,配置MODBUS 的传感器地址,功能码,数据地址,类型,topic 等参数。这些参数通过App 的配置窗口配置。
同样地,App 在运行过程中,需要人机交互界面。 App 提供html 页面的人机交互界面。
每个App 的配置页面和HMI 都是不同的。所以这些UI 网页其实都是APP 开发人员开发的。一旦App 安装好之后,通过主界面可以访问该App的 配置网页。完成App 的参数配置。 下面是一个实例:
基本服务(Base Service) 的API
Base Service是一个基本的容器化服务。它为APP 提供基本的底层服务,比如硬件访问(Hardware access layer)。它具有App 模板相同的结构。
基本API(v1.0)
-注册App(App register)
每一个微服务启动后 都会通过restful api的形式将自己的配置注册到Base Service。
硬件访问(HAL web API)
云端App 并不要与硬件打交道,但是边缘设备中的App 就可能要与底层硬件打交道。对于程序员来讲,硬件访问和控制总是比较麻烦的东西。在我们的实验项目中,将硬件访问封装在一个基础服务中,通过web API 提供服务。我们称为 “HAL web API“。事实上,我们使用一个基于Arm 公司Mbed OS 的Cortex-M4 处理器作为边缘设备的IO 子系统。cortex-M 通过USB 与主处理器模块连接。为了与mbed OS 保持一致,我们的HAL web API 设计成类似Mbed IO 驱动类的格式。这些 API 包括:
-DigitalOut
-PWMout
-DigitalIn
-CANBUS
-AnalogIn
-AnalogOut
-SPI
-serial
-I2C
-Timer
这里我们以DigitalOut 为例,说明 HAL webAPI 的方式。
->/hal/DigitalOut method:“write”,parameter:”true”
->/hal/DigitalOut method:“fipflop”
->/hal/DigitalOut method:“read
<- value:true
这样安排的方法的优点在于 HAL webAPI 可以被各种语言实现的应用程序调用,例如 python ,nodeJS javascript,C++ 等各种语言实现的APP 都可以以统一的接口地访问本地硬件。
云端/边缘系统主界面
就像windows 的桌面系统和手机,IPAD 的主界面一样,云端/边缘应用系统也将会有一个统一的主界面(我们称为dashboard)。用户可以通过这个统一的主界面实现应用APP 的安装,运行,卸载。也可以现在应用程序的用户人机界面。主界面也可以是一个容器中运行的程序。
下面是我们的实验系统中为边缘设备设计的一个边缘设备主界面。
看上去是否和IPAD 的界面很相似呀? 事实上,云端/边缘服务的主界面是HTML5 设计的。我们的实验系统是基于NodeJS 实现的 。它完全可以在任何浏览器上访问这样的主页,也可以简单地实现一个APP,在ipad 上访问。
用户通过主界面可以访问不同App 提供的配置界面和人机交换界面页面,它们也是采用HTML5/css/jvascript 设计的。为了统一的用户体验,主页面的app页面应该遵循统一的设计风格。
可惜,我们的实验系统并没有对UX 做更多的探索。
dashboard 提供了系统管理和App 管理。App管理是docker 容器管理进程daemon 的远程API 的实现,它包括了
- 系统管理
用户账号管理
用户名注册,登入
网络管理
WiFi 网口令,密码,
Ethernet IP 地址
系统状态
-网络状态显示
-容器管理
容器的导入
容器启动
容器停止
容器删除
-镜像管理
导入镜像
删除镜像
应用APP管理
应用程序初始化
应用程序暂停
应用程序运行
实现细节
硬件访问服务HAL service
HAL service 为App 提供了一个统一的硬件底层访问服务。 这是采用C++编写的服务。
该程序实现了:
1 HAL Web API到USB serial RPC之间的协议转换。
2 MQTT 客户端
3 web socket 服务器端。
一个HAL 库实现USB serial 下与cortex-M 处理器之间的通信协议(RPC Over USB serial)。
主界面(App dashboard)
App dashboard 是在NodeJS 上实现的一个容器程序。实现设备的主界面。它完成的主要功能包括:
App管理
通过调用Docker 的daemon API 实现对容器(container),App镜像(images)的管理。
系统设置
用户名,密码
wifi 设置
以太网 IP 地址设置
其它系统参数的设置
系统状态
App 运行状态
网络状态
如 wifi 信号,ethernet 流量。
应用App 配置,HMI 页面导航
以上是关于嵌入式设备的容器化App的主要内容,如果未能解决你的问题,请参考以下文章
容器化 Spring Boot 应用程序时出现 Docker 错误