(深圳信息职业技术学院,广东 深圳 518029) 林 涛,耿 壮
 林涛(1963-)
男,硕士,现任深圳信息职业技术学院计算机应用系讲师,主要研究方向为单片机与嵌入式系统、网络技术、信息安全。
1 引言
目前,先进的嵌入式计算机以其优良的品质、高可靠性及模块化,广泛地应用于工业控制、航空航天、医疗、智能仪表、通信、数控、自动化生产设备、数据采集等领域。在实际应用中,为了提升系统的整体性能,必须实现PC机和嵌入式计算机之间的通信。由于串行通信具有连接简单、使用灵活方便、数据传递可靠等优点,可采用串行通信方式进行数据下载。但是,Windows操作系统对系统底层操作采取了屏蔽的策略,不允许用户对硬件I/O口进行直接操作,进行串行通信只能通过调用API函数来完成;同时Windows 9x通过消息队列驱动管理程序,DOS中断服务例程在其下面也很难实现,且实时性和可靠性都得不到保证;笔者考虑可以通过多线程编程解决这一问题,来提高数据传输的吞吐量和应用程序的可靠性。
高速串口数据采集软件的设计不同于普通串口通信,要求在接收数据采集设备发送大量数据的同时完成对已接受到数据的实时存储,如果处理不好二者之间的关系,会造成数据的丢失甚至程序的崩溃。这就要求应用程序能够同时处理两件以上不同的任务。Win32是基于线程的抢先式多任务操作系统,使得应用程序能够同时执行多个任务,即在一个进程中可以同时运行多个线程。一个线程是指程序的一条执行路径,系统不停的在多个线程之间切换。由于时间很短,看上去多个线程在同时运行。对于通讯这种需要花费大量时间来测试I/O操作,同时又要保持响应用户其它操作的应用程序来说,创建多线程是最佳选择。
2 基于ARM的嵌入式数据采集系统
本文以基于ARM的嵌入式数据采集系统为背景进行论述。现场的嵌入式数据采集系统采集各种传感器发来的数据,包括电流、电压、温度、压力、振动等。采集系统通过485总线实时将数据送到给PC机,PC机通过多线程方式接收嵌入式数据采集系统发来的数据,送本地数据库系统或者通过Internet发往数据处理中心,如图1所示。
文中的嵌入式数据采集系统采用了由PHILIPS公司生产的ARM7TDMI微处理器LPC2214,LPC2214是基于一个支持实时仿真和跟踪的16/32位ARM7TDMICPU的微控制器,并带有16K字节片内静态RAM和256 KB嵌入的高速Flash存储器。128位宽度的存储器接口和独特的加速结构使32位代码能够在最大时钟速率下运行。对代码规模有严格控制的应用可使用16位Thumb模式将代码规模降低超过30%,而性能的损失却很小。LPC2214较小的144脚封装、极低的功耗、多个32位定时器、8路10位ADC(64脚和144脚封装)以及多达9个外部中断使它们特别适用于工业控制、医疗系统、访问控制和POS机。可使用的GPIO(General Purpose Input/Output,通用输入输出)高达76(使用了外部存储器)~112个(单片应用)。由于内置了宽范围的串行通信接口,它们也非常适合于通信网关、协议转换器、嵌入式软Modern以及其它各种类型的应用。
 图1 基于ARM的数据采集系统
3 用多线程技术实现数据采集系统和PC机的通信
(1) 多线程程序设计思想
在32位Windows系统中,多任务是指系统可以同时运行多个进程,每个进程也可以同时执行多个线程。进程就是应用程序的运行实例。每个进程都有自己私有的虚拟地址空间,每个进程都有一个主线程,但可以建立另外的线程。进程中的线程是并行执行的,每个线程占用CPU的时间由系统来划分。
可以把线程看作是操作系统分配CPU时间的基本实体,系统不停的在各个线程之间切换,它对线程的中断是汇编语言级的。系统为每一个线程分配一个CPU时间段,某个线程只有在分配的时间段内才有对CPU的控制权。
高速串口数据采集的特点是接收数据的速度要求很高,数据量很大,根据这些特性,可以在程序中创建一个辅助工作者线程专门来监视串行口的输入。由于写串口的数据量不大,不会太费时,所以可以在主线程中完成写端口的任务,不必另外创建线程。
(2) 用API函数实现串行通信的基本流程
首先CreatFile()函数打开通信资源,之后配置通信资源属性由以下API函数完成:SetupComm()设置串行通信端口的输入和输出缓冲区的大小;通过设备控制块DCB修改和设置串口工作状态的参数,如波特率、数据位、奇偶校验位等通信参数,SetCommState()将DCB结构中的内容写入串口设置;SetCommTimeouts()设置串口读写操作的溢出时间。设置工作完成后串行通信可用ReadFile()对通信资源进行读操作,WriteFile()进行写操作。
串行通信结束时调用函数CloseHandle()来关闭CreateFile()函数返回的串口句柄。
(3) 数据采集线程
多线程的串口I/O通信编程中,将对串口的读、写操作视为同一进程的两个不同任务,创建读线程和写线程分别完成对串口的读、写操作;由于异步串行通信事件的随机性和实时性,要求通信线程优先于主线程被处理,所以设置各线程的优先级别如下:
读线程的优先级>写线程的优先级>主线程的优先级。
主线程是数据采集程序的管理者,用来初始化串口(通过调用Win32 API函数),自定义通信事件消息,创建、删除辅助线程,进行人机交互的操作及协调好各线程的运行。程序流程如图2所示。
 图2 数据采集程序框图
左边为主线程,右边为子线程。用户通过VC设计的界面上的控件打开串口,并且发送数据。当对串口的参数设置完毕,串口成功打开的同时,子线程即接收线程开始运行。用户发送数据的同时,接收线程的控制函数也同时运行,当控制函数接收到读串口事件时,调用读串口函数,读取串口接收到的数据。子线程一直运行,也不断的读取接收到的数据,并显示在用户的界面上。当用户关闭串口,主线程要终止,此时子线程也收到主线程发送的关闭串口事件,终止线程,关闭串口。
(4) 后台辅助线程
后台辅助线程是数据采集软件的核心,包括串口监视线程、读线程。串口监视线程在后台对串口进行实时监视,当监视到预定义的事件时,立即调用相应的线程进行处理并向主线程发相应的消息,如接收到数据就调用读线程自动接收数据并进行处理,同时向主线程发送。
 图3 串口监视线程的实现
接收到数据的消息,串口监视线程发送完此消息后就执行后面的程序代码,继续对串口进行监视,做到了处理消息与监视串口两不误,既保证了数据采集的实时性,又避免了资源的浪费,其处理过程如图3所示。
4 结语
本文分析了多线程技术在嵌入式数据采集系统中的应用,利用多线程,可以实现嵌入式系统与PC机的高速通信。通过两个通信线程并发执行,加以同步管理,应用程序能够在发送数据的同时接收数据,实时响应性强,高效可靠,有效地避免了数据丢失、程序锁死等问题。在数据采集的实际应用中结果令人满意。
其他作者:耿壮(1954-),现任深圳信息职业技术学院计算机应用系副教授,主要研究方向为单片机与嵌入式系统、网络管理、多媒体技术。
参考文献 [1] S3C44B0X RISC Microprocessor Data Sheet, Samsung semiconductor Ltd, 2001. [2] 蒋亚群, 张春元. ARM微处理器体系结构及其嵌入式SOC[J]. 计算机工程. [3] 王田苗. 嵌入式系统设计与实例开发―基于ARM微处理器与μC/OS-Ⅱ实时操作系统[M]. 北京:清华大学出版社, 2002, 9. [4] 江俊辉. 基于ARM的嵌入式系统硬件设计[J]. 微计算机信息, 2005. [5] BOBINI A, CORBET J.Linux Device Drevers[M]. O |