基于嵌入式Linux的移动终端的软件设计
扫描二维码
随时随地手机看文章
1引言
实时操作系统()是嵌入式应用软件的基础和开发平台,应用程序都是建立在它之上。实时嵌入式操作系统的种类繁多,大体上可分为两种:商用型和免费型。商用型的实时操作系统功能稳定、可靠,有完善的技术支持和售后服务,但价格昂贵。免费型的实时操作系统在价格方面具有优势,目前主要有、μC/OS等。
与其它嵌入式操作系统相比,嵌入式具有开放源代码、高可靠性以及强大的网络功能等优势,因此选用了嵌入式系统作为移动终端的软件平台。
2车辆概述
车辆是融全球定位技术()、地理信息技术(GIS)和通用分组无线业务()于一体的高科技系统,由移动终端、网络和监控中心组成[1]。移动终端安装在各个移动车辆上,其上的接收器实时采集卫星定位信息,然后通过串口1传送给ARM处理器。ARM处理器先解算出有用的数据(经纬度、速度、状态等),然后按照TCP/UDP协议的格式封装成TCP/UDP数据包,接着加上IP报头和报尾封装成IP数据报。由于ARM处理器与通信模块之间的通信遵循PPP(PointtoPointProtocol,点对点协议),因而,需要将IP数据报按照PPP帧的帧格式封装成PPP帧,然后传递给接在串口2上的GPRS通信模块。GPRS通信模块通过无线链路将数据进一步发送到SGSN(ServingGPRSSupportNode,GPRS业务支持节点)。SGSN进行相应的协议转换,并按照GPRS特有的GTP(GPRSTunnelProtocol,GPRS隧道协议)将数据封装成GTP包,然后通过GPRS骨干网传送到相应的GGSN(GatewayGPRSSupportNode,GPRS网关支持节点)。GGSN也进行相应的协议转换,再根据外部数据网的协议格式对数据进行新的封装,并且根据其目的IP地址选择路由进行传送,从而最终传送到监控中心。监控中心在具有地理信息处理和查询功能的电子地图上进行车辆运动轨迹的显示,并对被监控车辆的准确位置、速度、运动方向、行车状态等参数进行监控和查询。同时,监控中心也可以向移动终端发送文本信息和控制命令。
由此可见,移动终端的核心功能是接收信号、处理GPS数据以及通过GPRS网络与监控中心进行通信(包括向监控中心发送定位信息和接收监控中心的指令)。
3移动终端软件系统的设计
3.1总体设计
在移动终端上,软件系统主要由三个部分组成:GPS信号接收程序、GPS数据处理程序和GPRS通信程序。在嵌入式Linux系统平台下,移动终端的软件系统结构如图1所示。
图1 移动终端的软件系统结构
3.2GPS信号接收程序
对于移动终端,它的第一个任务就是接收GPS信号。在嵌入式Linux系统平台下,GPS信号接收程序的层次结构如图2所示。
图2 GPS信号接收程序的层次结构
其中,tty层、N_TTY行规程(LineDiscipline)层和低层驱动程序是嵌入式Linux系统中串行通信驱动模块三个固有的逻辑层,这三层之间有相互调用的接口函数。嵌入式Linux系统提供了多种行规程供各类设备进行选择,如:TTY行规程(N_TTY)用于连接终端输入驱动设备和终端显示驱动设备,而PPP行规程(N_PPP)用来连接终端驱动设备和网络驱动设备。GPS信号接收程序使用了N_TTY行规程,GPS接收器接收到的数据必须经过N_TTY行规程模块进行规范处理。低层驱动程序用来直接对硬件进行操作,而_buffer是低层驱动程序和N_TTY行规程之间的高速接口,它保存GPS接收器接收到的数据。
在嵌入式Linux系统中,内核给接在串口1上的GPS接收器提供了一个设备节点/dev/ttyS0以及标准的文件系统接口[2]。这样,GPS信号接收程序对设备节点/dev/ttyS0的操作就会被内核映射成对GPS接收器的操作。当GPS接收器接收到卫星信号时,会触发低层驱动程序事先注册到系统中的中断处理函数,从而调用函数receive_chars()把数据填充到_buffer中,然后调用函数tty__buffer_()将数据传递给N_TTY行规程模块。N_TTY行规程模块中的函数n_tty_receive_buf()对数据进行规范化处理后将其存入tty缓冲区中,供应用层的GPS信号接收程序来读取。
当应用层的GPS信号接收程序开始运行时,它会向文件系统发出读请求,文件系统发现此请求的对象为tty设备,于是调用函数tty_(),接着调用函数_chan()读取tty缓冲区中的数据。
3.3GPS数据处理程序
GPS接收器与嵌入式Linux平台之间的通信协议有很多种,这里采用的通信协议是NMEA-0183,它规定了GPS数据的输出速率为4,800波特,其输出都是字符,工作模式为8-N-1。通信协议NMEA-0183中包含的语句有GPGGA、GPGLL、GPGSA、GPGSV、GPRMC、GPVTG等,要想知道车辆的位置信息,至少要提取出GPGGA、GPGLL、GPRMC中的一种。NMEA-0183协议报文的语句格式如图3所示。
图3 NMEA0183的报文格式
其中,$为串头,表示串的开始;AA为识别符;XXX为语句名;ddd…ddd为数据字段,字母或数字;*表示串尾;hh表示$与*之间所有字符代码的校验和;<CR>为回车控制符;<LF>为换行控制符。
在车辆中,主要关心的是时间、车辆的位置和速度等信息。因此,在移动终端上,GPS数据处理程序的主要功能是从GPS接收器接收到的数据中提取出GPRMC定位语句,忽略掉信息[3]。此后,移动终端上的GPRS通信程序负责将相关的数据发送给监控中心。
3.4GPRS通信程序
3.4.1拨号到GPRS网络的基本原理
移动终端要想通过GPRS通信模块访问,首先得附着在GPRS网络上,然后发起(PacketDataProtocol,分组数据协议)上下文激活过程[4],如图4所示。只有通过此过程,GPRS通信模块才能与GGSN建立一条逻辑通路,从而访问。
图4 上下文激活过程示意图
3.4.2移动终端上拨号程序的实现
在嵌入式Linux系统平台下,移动终端利用pppd(包含)拨号到GPRS网络。pppd是一个用户空间的后台服务进程(),而是pppd所带一个辅助工具,用来与GPRS通信模块建立会话。在上下文激活过程中,完成了第①步,而pppd完成了第②、③、④、⑩步。pppd拨号程序的层次结构如图5所示。
图5 pppd拨号程序的层次结构
其中,N_PPP层就是PPP协议层。PPP协议模块不仅提供简单的数据链路层功能,它还提供诸如鉴权(如PAP/),数据压缩/解压(如CCP)和数据加密/解密(如ECP)等扩展功能。由于GPRS通信程序要求透明化地使用这些扩展功能,而PPP协议模块本身无法对各种策略进行选择,于是pppd应运而生。PPP协议模块中策略性的内容都移到了pppd中,由pppd完成对鉴权、压缩/解压和加密/解密等扩展功能的选用。
在运行pppd的时候,pppd首先读取配置文件中的配置信息,其中包含了设置PPP协议模块的参数、GPRS通信模块连接的端口(/dev/ttyS1)以及对chat进行调用的语句,等等。随后pppd调用chat,chat也会读取相应的配置文件(其中包含一些应答语句对和AT命令),然后使用默认的行规程N_TTY向GPRS通信模块发送AT命令,接着chat将控制权返还给pppd。pppd将行规程切换为N_PPP,而pppd与PPP协议模块之间采用了设备文件来进行通信,设备文件名是/dev/ppp。通过系统调用,pppd可以读取PPP协议模块的数据包(当然,PPP协议模块只会把应该由pppd处理的数据包发给pppd)。通过write系统调用,pppd可以把要发送的数据包传递给PPP协议模块,而通过系统调用,pppd可以设置PPP协议模块的参数,可以建立/关闭连接。
此后,pppd执行了PDP上下文激活过程的第②、③、④步。等PDP上下文激活过程的第⑤-⑨步(与移动终端不直接相关)完成之后,pppd执行第⑩步,在函数_ppp_()中调用(PPPIOCNEWUNIT)创建一个网络接口(如ppp0)。当PPP协议模块在处理PPPIOCNEWUNIT时,调用函数register_netdev()向内核注册PPP网络接口,该网络接口的传输函数指向函数ppp_start_xmit()。值得注意的一点是,如果关闭进程pppd,行规程会由N_PPP切换回默认的N_TTY,因此,在移动终端与监控中心通信的过程中不能关闭pppd进程。
至此,移动终端完成了向GPRS网络的拨号,这样它就拥有了一个可以用于与监控中心进行通信的网络接口(如ppp0)。
3.4.3移动终端与监控中心的数据交互
前面,移动终端已经与监控中心建立了网络链接。接下来,移动终端就可以与监控中心进行通信了。GPRS通信程序的层次结构如图1的右半部分所示。
在移动终端向监控中心发送定位信息的过程中,移动终端上的GPRS通信程序通过socket接口发送TCP/IP数据包,内核根据IP地址和路由表,找到PPP网络接口,然后调用函数ppp_start_xmit(),此时控制权就转移到了PPP协议模块。函数ppp_start_xmit()调用函数ppp_xmit_process()去发送队列中的所有数据包,而函数ppp_xmit_process()会进一步调用函数ppp_send_frame()去发送单个数据包。函数ppp_send_frame()根据前面pppd对PPP协议模块的设置调用压缩等扩展功能之后,又经函数ppp_()调用函数pch->chan->ops->start_xmit()发送数据包。函数pch->chan->ops->start_xmit()是具体的传输方式,对于串口发送方式,则是ppp_async.c:ppp_asynctty_open中注册的函数ppp_async_send(),函数ppp_async_send()经函数ppp_async_()调用函数tty->driver->write()(定义在低层驱动程序中)把数据发送到串口2(GPRS通信模块接在串口2上)。
ppp_async.c在初始化时(ppp_async_init),调用函数tty_register_ldisc()向tty注册了行规程N_PPP的处理接口,也就是一组回调函数。在移动终端接收监控中心指令的过程中,当GPRS通信模块收到数据时,就会回调N_PPP行规程中的函数ppp_asynctty_receive()来接收数据。函数ppp_asynctty_receive()调用函数ppp_async_input()把数据buffer转换成sk_buff,并放入接收队列ap->rqueue中。ppp_async另外有一个tasklet(ppp_async_process)专门处理接收队列ap->rqueue中的数据包,ppp_async_process一直挂在接收队列ap->rqueue上,一旦被唤醒,它就调用函数ppp_input()让PPP协议模块处理该数据包。在函数ppp_input()中,数据被分成两路,一路是协议控制数据包,放入队列pch->file.rqb中,交给pppd处理。另外一路是用户数据包,经函数ppp_do_recv()、ppp_receive_frame()进行PPP协议相关的处理后,再由函数netif_rx()提交给上层的TCP/IP协议模块进行处理,最后经socket接口传递给应用层的GPRS通信程序。
4总结
近几年,智能交通系统(包括车辆监控系统)发展非常迅速,因此,移动终端将会有非常广泛的应用前景。随着市场需求的不断扩大,更加丰富的功能将会被集成到移动终端上,而嵌入式Linux系统凭借其自身的优势将会被越来越多地应用到这个领域。