赵 炯,杨天豪,肖 杰,熊肖磊
(同济大学机械与能源工程学院,上海 201804)
随着工业4.0、智能系统、物联网[1]的发展,对于各类传感器的采集、应用需求愈发增大。工业数据采集器的采集对象大多是RS-232/RS-485、CAN总线接口或以太网接口的传感器。在目前的工程应用中,常用的智能采集系统架构有“传感器-可编程逻辑控制器(programmable logic controller,PLC)-计算机监控系统”和“传感器-串口服务器-计算机解析”模式。前者价格高昂且依赖PLC开发;后者则只能适用于RS-232/RS-485接口,不易进行网络扩展,且在软件开发时需要进行Modbus等底层协议的解析。
在嵌入式系统成本大大降低,应用范围日渐广泛的背景下,针对目前数据采集系统搭建、开发过程复杂的问题,本文设计了一种适用于工业通用采集接口、便于个性化配置、面向多传感器并发读写的嵌入式远程数据采集器。
结合工业数据采集应用场合,数据采集应用系统框架如图1所示。整个系统主要由数据采集器、多个传感器以及远程监控中心构成。数据采集器与数个传感器直接相连,同时通过自身的3G/4G功能或以太网与远程监控中心间接相连。数据采集器负责根据用户配置分别采集各个传感器数据,经处理后直接转发至远程监控中心。
图1 数据采集应用系统框架
根据嵌入式系统的硬件设计原理及本数据采集器的需求,本数据采集器包括以下主要模块:核心模块、电源模块、采集接口模块、网络功能模块及基本外围电路。数据采集器硬件框架如图2所示。
图2 数据采集器硬件框架图
核心模块采用Freescale公司生产的i.MX6Q核心平台,其集成了Cortex-A9四核处理器,工作频率可达1 GHz,搭载了2 GB的DDR3内存以及8 GB的eMMC Flash;同时支持以太网、CAN总线、UART等接口驱动;支持Linux操作系统,满足本数据采集器硬、软件的开发需求。
在电源模块的设计上,数据采集器需要为自身处理器、各控制芯片供电。根据工业设备常用电源,最终选定采用24 VDC电源输入,稳压输出5 V、3.3 V电源。RS-232及CAN总线接口电路如图3所示。
本文的数据采集器面向工业通用接口,因此图2中与各类传感器连接的RS-232接口及CNA总线接口电路模块主要包含RS-232模块、CAN总线、以太网模块。
图3 RS-232及CAN总线接口电路
RS-232模块主要依靠MAX232芯片进行晶体管-晶体管逻辑电平信号(transistor-transistor logic,TTL)电平与RS-232电平之间的转换,TTL电平与核心模块串口输入/输出接口直接相连。对于CAN总线模块,由于核心模块具备了CAN总线控制器的功能,因此只需要增加CAN收发器即可。此处选用的是MCP2551芯片。
根据功能定义,数据采集器需要完成实时数据采集以及Web实时配置访问两大功能。数据采集器软件功能构架如图4所示。
图4 数据采集器软件功能构架图
Web实时配置访问功能是指将采集器作为服务器为用户开放一个Web界面,用户不需要修改采集器内部软件,通过此界面便可增加、删除传感器,配置各传感器的解析协议、地址等参数。同时可以观察数据采集器内部数据库的摘要内容,了解数据采集器的运行状态。
实时数据采集功能(data acquisition,DAQ)是数据采集器的核心功能,主要包含本地自检功能,面向多个通信的传感器采集、处理功能以及远程传输功能。
Linux运行环境搭建是指在i.MX6Q核心板上移植Linux系统,主要步骤如下。
①配置编译环境。在计算机端的虚拟机中安装ubuntu 16.04系统,安装gcc-5.3.1 版本交叉编译器,并配置相关环境变量。
②获取系统源码。本系统使用的是由天嵌公司提供的TQIMX6_linux_v3.0源码包(4.1内核)以及相应的u-boot源码。
③进行内核配置。在编译源码前,运行make menuconfig配置系统功能,主要打开串口设备、CAN总线设备的相关配置。
④编译源码。分别进入Linux源码和u-boot源码根目录,运行编译脚本,进行内核编译和u-boot编译。
⑤烧录系统。将编译完成的zImage文件和dtb文件存入mfgtools工具中,通过USB连接线进行系统烧录。
实时配置访问功能是指数据采集器为用户开放Web页面,用户可以通过网络灵活配置数据采集器的参数,同时获知其中数据库的存储情况。以下将从XML配置文件设计、数据库设计以及Web服务器的开发三方面介绍具体实现方法。
由于该数据采集器主要面向通用的工作环境,因此有必要设计合适的配置文件以描述系统的各项参数。配置文件的载体并不统一,常用的主要有INI配置文件、XML配置文件或系统注册表等。本数据采集器选用带有树形层次结构、且方便扩展的XML文件[2]。
XML配置文件树型结构如图5所示。
图5 XML配置文件树型结构图
SYS为根节点,第一层分为LOCAL、REMOTE、DAQ三部分,分别代表本地参数、远程服务器参数及传感器参数。第二层是第一层的子节点元素,描述了详细的参数设定。其中DAQ下属二级节点中,包含的是属性值num唯一且互不相同的多个Sensor节点,Sensor节点下的三级节点描述了详细的传感器参数设置。
随着嵌入式设备硬件的升级,目前嵌入式系统中可以支持加入轻量级或中低量级的数据库。通过加入数据库,可以有序地储存采集到的数据,同时记录系统的运行状态。
嵌入式Linux系统中常用的数据库为SQlite或Mysql。SQlite的优点是功能简约、小型化、上层应用可以直接访问数据文件,缺点是没有用户管理并且不支持并行读写。Mysql数据库优点是功能全面,有线程池机制,追求最大并发效率[3],缺点是占用空间较大。考虑到本系统中储存空间充足,且Mysql需要并发操作,因此选用Mysql数据库,且选用MyIASM传统数据库引擎[4]。
根据功能需求,为数据采集器设计了两个主要表,即daq_status_tb表和data_store_tb表,分别用于储存DAQ软件的运行状态以及各传感器的数据。data_store_tb表和设计如表1和表2所示。
表1 data_store_tb表设计
表2 daq_status_tb表设计
数据采集器中的Web服务器主要提供了操作XML配置文件和读取数据库的接口。本数据采集器选用Apache服务器并配合LAMP(Linux、apache、Mysql、PHP)架构进行开发,同时使用javascript、Ajax等技术以增强页面交互性。
Web服务器的主要操作对象是数据采集器内的XML配置文件以及Mysql数据库。LAMP架构访问原理如图6所示。
图6 LAMP架构访问原理图
用户通过浏览器向服务器发送http请求,Apache服务器接受请求后,调用php处理模块进行php脚本的处理,进行XML文件的读写或Mysql的读写。Apache服务器接收php脚本的返回信息,并将结果发送给浏览器。浏览器解析后将数据呈现至整个网页。用户可通过Web浏览器实现对数据采集器的配置和监控。
实时数据采集功能主要在Linux平台上使用C/C++语言进行开发,结合多进程、多线程、驱动开发等技术以保证整体软件的稳定运行[5]。下面将介绍整体软件流程以及基本功能的设计与实现。
实时数据采集功能中包含的三个并发运行的功能(本地自检、传感器采集、远程转发),但又互相关联的。本设计中提出使用Linux系统中的多进程技术来实现三个功能的同时协调运作[6]。多进程技术与多线程技术相比,优势在于不同进程享有独立的资源,相互影响较少。
针对其中传感器采集功能,有三个重要指标:高速性、连续性和并发性。采集过程中可能会对多种传感器同时进行高频率采集。本设计提出使用Linux系统中的多线程技术来实现多路传感器的并发采集、转发功能。
整体系统程序流程如图7所示。软件系统通过三次fork()函数向Linux内核申请资源,获得MONITOR、DAQ、REMOTE三个进程。
图7 整体系统程序流程图
MONITOR即监控进程,负责实时读取XML配置文件内容、监控REMOTE、DAQ进程的状况并向Mysql数据库写入数据采集器状态。
REMOTE即远程连接进程,负责建立、维持与远程服务器的连接,同时定时获取并转发共享数据缓冲区的内容。
DAQ即数据采集进程,负责多路传感器的数据采集和处理。DAQ进程会根据配置文件中的传感器数量生成相同数量的采集线程,每个采集线程在初始化后,依序循环实现数据采集、预处理及转发功能。多个采集线程会将采集结果转发至系统的共享内存中,由REMOTE进程进行统一转发。
三个进程间互有关联,都需要访问配置属性、数据缓冲区等参数。此部分主要通过共享内存与信号量以实现进程间的互斥通信。
本地自检功能主要由MONITOR进程实现。该进程会定时对比XML配置文件内容。当检测到XML配置文件被改变时,会向REMOTE和DAQ进程发出kill信号,然后创建新的REMOTE进程和DAQ进程。如此便可在不重启整个软件的情况下改变系统的参数配置。
MONITOR进程会定时检测REMOTE、DAQ进程的存活情况,并在Mysql数据库中写入数据采集器的状态。
单个传感器的数据采集是由DAQ进程生成的采集线程来实现的。每个线程根据传感器的不同种类调用不同的初始化函数,然后循环实现数据采集、处理及转发功能,如图7中DAQ多线程部分所示。
5.3.1 采集接口初始化
本数据采集器所面向的是工业中常用的RS-232/RS-485总线(如Modbus RTU协议)、以太网总线(如Modbus TCP协议)以及CAN总线。接口初始化与驱动层间关系如图8所示。在进行传感器初始化时,程序需要调用与硬件底层驱动相关的文件或函数,例如启动RS-232/RS-485总线需要调用uart.c中的串口初始化函数,启动以太网总线需要调用socket.c中的socket套接字函数。初始化后,通过对虚拟文件系统(virtual file system,VFS)的读写访问,即可实现对硬件设备的读写[7]。
图8 接口初始化与驱动层间关系图
5.3.2 数据预处理
数据预处理过程是对原始数据进行简单解包、数据类型转化并储存的过程。定义每条数据的格式主要包含数据类型、传感器序号、数据包序号、实际数量及采集时间。传感器序号用一字节表示,数据包序号用两字节(16进制)表示,格式之间用“,”逗号分隔。单个数据包格式如图9所示。
图9 单个数据包格式
经预处理后的数据将会被储存至Mysql数据库作为备份,同时被转存至转发缓冲区中,等待REMOTE进程进行统一转发。
5.3.3 数据同步转发及转发缓冲区设计
整个系统中,REMOTE进程和多个采集线程会频繁地并发操作转发缓冲区,因此需要避免对内存的误读写操作,否则容易造成内存越界而导致软件崩溃。针对并发读写的缓冲区,一种有效的方案是采用环形缓冲区结构[8]。
环形缓冲区是一种先进先出模型,可为频繁读写缓冲区的过程减少操作步骤。数据采集系统中的读写操作及环形缓冲区结构如图10所示。
系统中的环形缓冲区主要储存字符数组的地址,本系统中定义每个字符数组空间为64字节,环形缓冲区总大小为64个元素(即k=64)。环形缓冲区内定义了head和tail两个指针,分别用于读、写操作,tail和head之间的灰色区域表示缓冲区内已有数据。
图10 读写操作及环形缓冲区结构图
缓冲区的读写采用操作系统中经典的“生产者-消费者”模型[9]。REMOTE进程负责从缓冲区中取数据,主要操作head指针,各个采集线程负责往缓冲区内写数据,操作tail指针。此处的操作是面向共享内存的操作,因此添加了信号量来实现多进程间的互斥访问:semop(wait)代表取信号的函数。若缓冲区正在被其他函数操作,即会阻塞挂起,直至获取信号;semop(release)代表释放当前占用的信号[10]。
该环形缓冲区有两个特殊的设定:一是总是保持一个存储单元为空,用于区分缓冲区内“满”和“空”的情况;二是允许覆盖缓冲区数据,即在进行写操作过程中,若缓冲区已满,则以新数据覆盖旧数据。
远程转发功能由REMOTE进程实现,主要实现建立远程服务器TCP连接、定时发送心跳包以及打包发送数据。其中,心跳包功能中会实时判断网络连通状况。
数据打包协议如图11所示。
图11 数据打包协议图
在实际应用中,每个传感器的采集频率fn不尽相同,REMOTE进程向服务器发送数据的频率也不易确定。本系统中,由用户自行设置统一发送频率F,REMOTE进程会根据统一频率F定时获取环形缓冲区内数据,进行统一打包、发送数据。这样做的好处是可以灵活处理发送频率:当数据实时性要求较高时,设置统一转发频率F高于传感器的频率fn,即可实时发送每个数据;当数据实时性要求不高时,可以设置统一转发频率F最低,同时打包多项数据,节约网络资源。
协议首部CMD代表操作请求号;daqSerial代表当前数据采集器的序列号,用于区分不同数据采集器;SensorNum代表当前在线的传感器数量;dataNum代表正文中数据包数量;headLen代表首部长度。正文部分是各个数据包的内容,以换行符区分。
本文主要介绍了基于i.MX6Q核心芯片及嵌入式Linux的工业通用数据采集器设计,完成了采集器硬件系统的设计、基于LAMP架构的Web服务器搭建,以及C/C++数据采集软件的编写与测试;实现了数据采集器实时配置、多路并发采集储存数据、远程转发数据等功能。与传统的数据采集器相比,本文设计不仅通用性更强,而且配置操作更加人性化、网络化。
系统着重关注多路数据采集的并发性设计以及实际应用的通用性,主要通过多进程、多线程的设计以保证系统各功能的稳定运行,同时通过环形缓冲区数据结构和信号量的操作以实现多路数据的并发读写。测试过程中,上位服务器可以稳定、准确地接收多个Modbus协议传感器的数据。