技术天地

Android双应用进程Demo程序设计作者:陈昌龙    发布时间:2017-12-18 9:42:14    被阅览数:

  Android是移动设备的主流操作系统,近年来越来越多的工业领域的客户开始关注基于Android操作系统的设备在工控领域的应用。鉴于Android是基于Linux内核的事实,我们发展了一种以双应用进程为特色的Android工控应用方案,并在ESM6802工控主板上加以实现。具体说来,就是在Linux平台上运行一个直接操作硬件接口的控制通讯管理进程,为保证运行效率,该进程采用C/C++语言编写(以下简称C进程或控制进程);另一方面在Android平台采用标准Java语言编写一个人机界面进程(以下简称Java进程)。底层的控制进程并不依赖与上层的Java进程而独立运行,两个进程之间通过本地IP进行通讯,控制进程处于服务器侦听模式,Java进程则为客户端模式。本方案的主要优点是客户可以直接继承已有的现成应用程序作为底层控制进程的基础,仅仅增加标准的Socket侦听功能,即可快速完成新的底层应用程序的设计。而界面的Java程序,由于不再涉及具体的工控硬件接口,属于单纯的Android程序,编程难度也大大降低。


  设计Android双应用进程Demo程序的目的就是验证“双应用进程”Android工控应用方案的可行性,同时起到一个抛砖引玉的作用。本设计文档将具体讲解设计思路,约束通信协议和接口。


  本文PDF下载:Android双应用进程工控方案(二)——Android双应用进程Demo程序设计


1、总体描述


  总体要求如下:

  ● 采用C/S(客户端/服务端)模式,通过socket连接,通信需要自定义通信协议

  ● 客户端使用Java语言开发,主要是人机交互,查询以及简单的设置功能

  ● 服务端使用C/C++语言开发,主要是各个功能模块的业务逻辑正常运行,以及接收处理客户端的人机交互请求

  ● 服务端各个功能模块的业务逻辑部分始终正常运行,客户端连接与否,不影响各个模块的工作

  ● 客户端接入后,固定周期向服务端发出刷新数据请求,服务端响应后,客户端仅刷新有改变的UI部件


Android双应用进程Demo程序设计.gif

图1 C/S工作模式示意图


  如图1所示,Android开机后,服务端C/C++程序自动运行,此时整个控制系统已经运转起来,各个功能模块下的设备都已进入正常工作模式。这里以GPIO和串口设备作为示例,其中GPIO模拟开关状态变量,串口模拟通信设备。server模块监听client的连接,当有client接入后,响应client的请求,将GPIO状态、串口的数据统计信息,按照自定义的通信协议封装成协议包,通过socket发送给client。如果没有client接入,或者client接入断开,各个功能模块依然正常工作。也就是说,服务端C/C++程序完全可以在没有客户端的情况下,自动运转各个功能模块;客户端的接入,主要是为了方便人为监控。


2、模拟业务描述


  在上一节的描述下,我们模拟某个控制系统(控制进程)的实际控制设备如下:

  ● 设备1:两个GPIO,其中GPIO0作为警报输入,GPIO1作为消防输出。控制进程启动后一直监听GPIO0,当GPIO0输入高电平时,控制进程设置GPIO1输出低电平;当GPIO0输入低电平时,GPIO1输出高电平

  ● 设备2:1个串口设备,控制进程开启后,串口设备周期性自动发送固定字符串,接收线程一直开启


  在Android的人机界面进程(Java进程)中,需要做的有:

  ● 查询并显示GPIO0和GPIO1的状态

  ● 查询并显示串口设备的发送/接收计数值、底层串口的自动发送周期值

  ● 设置底层串口的自动发送周期

  ● 清零底层串口的发送/接收计数值


3、自定义通信协议


  客户端与服务端之间通过socket连接通信,由于socket流传输是没有边界概念的,可能存在“分包”或“黏包”的情况,这就要求用户自定义通信协议,用以从socket字节流中提取出完整的通信包,解析此通信包,完成通信。


  根据模拟业务描述,在此Demo程序中,采用下图所示的通信包结构:


Android双应用进程Demo程序设计.gif

图2 自定义通信协议包


  Head:包头,2字节,固定0xFF0x02

  Len:包剩余(ID+Type+Data+Csum)长度,4字节,范围0~1018(1024-2-4)

  ID:设备标号,1字节,表明此包来自于客户端还是服务端(可以不用)

    ‘S’-- 服务端

    ‘C’-- 客户端

  Type:数据类型,1字节,表明此包的具体指令目的

    ‘q’--  来自客户端,查询所有参数(gpio状态、串口发送/接收字节数、自动发送周期)

    ‘r’--  来自服务端,应答客户端‘q’查询

    ‘s’--  来自客户端,设置底层串口自动发送的周期

    ‘c’--  来自客户端,底层串口发送接收计数清零

  Data:数据内容,长度不定字节,长度范围0~1015字节

    Type=‘q’时,data没有意义,长度可以为0

    Type=‘r’时,data长度14字节,gpio0状态(1字节)+gpio1状态(1字节)+串口rx计数(4字节)+ 串口tx计数(4字节)+串口自动发送周期(4字节)

    Type=‘s’时,data长度4字节,表示设置底层串口自动发送的周期

    Type=‘c’时,data没有意义,长度可以为0

  Csum:校验和,1字节,从ID到Data结束的校验和(反码),接收端ID+Type+data+Csum=0即为正确接收


4、服务端C/C++程序


  服务端C/C++程序是“双应用进程”模式中的控制进程,其主要功能有两个方面:一是能够自动运转各个功能模块,控制完成主要的业务逻辑;二是监听客户端连接,解析响应客户端请求。


  4.1 自动运转各个功能模块

  在此demo程序中,功能模块主要是gpio和串口,gpio模拟开关量,串口模拟通信设备。因此,创建MyGPIO和MySerial两个类。下面简单介绍下这两个类的public接口。


Android双应用进程Demo程序设计.gif

图3 MyGPIO类


  MyGPIO的init接口主要是打开/dev/esm6800_gpio这个设备节点。run接口主要是新建线程开启GPIO相关的业务工作,这里假设GPIO0作为输入,GPIO1作为输出,当检测到GPIO0为低电平状态时,GPIO1输出高电平;反之,当GPIO0位高电平时,GPIO1输出低电平。stop接口为停止GPIO业务,退出GPIO业务线程。getGPIOStateByIndex接口可以读取gpio-index的输入/输出电平状态。


  同样,对于MySerial类,也提供init、run、stop接口,另外提供了getCountInfo接口,读取传送计数信息,clearCount接口对计数清零。run接口开启串口业务线程,这里模拟业务为周期性的向串口发送数据(接收线程一直接收串口数据),因此还提供了一个设置周期的公共接口setPeriod和查询接口getPeriod。


Android双应用进程Demo程序设计.gif

图4 MySerial类部分公共接口


  4.2 监听客户端连接,解析响应客户端请求

  此部分主要对应图1中的Server模块,为此创建一个MyServer类,其头文件如图5所示。其中,registerDev接口用于向MyServer类注册设备,主要是将设备类(MyGPIO、MySerial)的指针传递给MyServer类,当MyServer类解析通信包后,可以通过设备类的指针调用其公共接口,查询/设置相关参数。run函数开启服务器,监听本地网络(127.0.0.1)的默认端口9733,进入accept等待连接状态。


Android双应用进程Demo程序设计.gif

图5 MyServer类


  4.3 main函数工作流程

  在main函数中,首先将GPIO设备和串口设备注册到Server模块中;然后初始化并运行GPIO和串口的具体工作任务;最后运行Server模块,开始监听本地端口9733,如果有连接到来,就建立新连接,解析来自客户端的协议帧,根据协议栈中的信息,调用GPIO、串口设备的公共接口得到响应信息,响应客户端请求。main函数的流程如下图所示:


Android双应用进程Demo程序设计.gif

图6 main函数


5、客户端Android Java程序


Android双应用进程Demo程序设计.gif

图7 客户端初始化


Android双应用进程Demo程序设计.gif

图8 客户端连接本地端口


  客户端启动后,新建socket连接本地IP地址的默认端口(127.0.0.1:9733),如图7和图8所示。建立连接后,以固定周期向服务器发送查询请求,然后刷新界面。


Android双应用进程Demo程序设计.gif

图9 客户端界面(正常状态)


Android双应用进程Demo程序设计.gif

图10 客户端界面(报警状态)


  如图9和图10所示,“警报输入状态”和“消防栓输出状态”分别读取的GPIO0和GPIO1的状态,当GPIO0输入高电平时(报警输入状态OFF),服务端自动控制GPIO1输出低电平(消防栓输出状态OFF);反之,当GPIO0输入低电平时(报警输入状态ON),服务端控制GPIO1输出高电平(消防栓输出状态ON)。


  “串口设备”模拟通信设备,这里仅获取了发送和接收计数值。为了模拟通信设备的自动独立运行,我们让串口周期自动发送字符串,而这个周期值可以在点击“串口设备”弹出的对话框中的设置。如图11所示,在弹出的对话框中,还可以选择清零底层串口的发送/接收计数值。这样就加入了人为的控制。


  最后,“设置”项主要设置UI进程相关的属性,比如访问服务器获取信息的“刷新周期”等。


Android双应用进程Demo程序设计.gif

图11 串口设置对话框


6、总结


  “双应用进程”方案设计的应用程序,在原来的C/C++程序基础上,添加一个server模块,将工作设备(GPIO、串口)的运转信息通过本地网络(127.0.0.1)的socket传送给了Android UI端显示;同时,server模块又能接收UI端的人机交互命令,并设置到对应工作设备。这其中,主要工作是抽象出server与各工作设备间的通信方式,以及server与UI端的自定义通信协议及解析。此方案充分利用了原有的C/C++程序,加快了底层业务逻辑的开发进度;同时,也降低了Java端界面开发的难度。


  本文在server与各工作设备间的通信方式,以及server与UI端的自定义通信协议及解析方面只是针对第二节中简单模拟业务而设定的,其目的在于验证方案的可行性,起到抛砖引玉的作用。如果用户对此方案感兴趣,英创会提供此demo程序的源码,供客户参考。


  本文PDF下载:Android双应用进程工控方案(二)——Android双应用进程Demo程序设计

Go Top