向兵
(武汉理工大学计算机科学与技术学院,武汉430063)
随着嵌入式及通信技术的发展,移动手持设备出现在很多应用场合,比如天然气公司开始采用智能化的方式来管理用户的用气情况,如何在服务端和表具终端间进行通信,成为系统的主要考虑因素。本文对系统进行需求分析后,以移动手持设备进行小规模通信为出发点,提出使用短信通信的方式来解决这一问题的方法。这种方式不仅使通信质量能够得到保证,而且价格合理,易于操作员来管理和维护,是一种行之有效的通信方式。
短信通信示意图如图1所示。PC机表示服务器端运行程序的平台,是操作员对表具和手持设备操作的环境;表具表示天然气表具,在里面配置了接收命令的固化程序;手持设备表示本论文研究的平台,是短信通信程序运行环境的主要部分。三者之间均可进行通信,它们之间已经有完整的命令帧格式,下面讨论如何设计并实现这样的通信子系统,而不研究具体的命令帧格式,假定是在统一的帧格式下完成的。
现场操作员需要设备有与表具进行通信的功能,能够测试表具的通信状况。因此,需要解决的主要有以下几个问题:
①选取合适的手持设备,能够有运行短信通信程序的基本硬件配置(需要配备GPRS模块)。
②选取合适的嵌入式操作系统,保证程序的稳定运行。
③如何进行有效的收发短信来完成通信功能,以测试表具的通信状况。
④需要有对文件操作的支持,操作员是需要上传和保存文件的。
图1 短信通信示意图
嵌入式系统的开发既要实现程序的功能性,也要选取特定的硬件平台,嵌入式系统是为了完成某一项或有限项功能,系统功能可以根据产品的设计要求进行裁剪、调整[1]。并具体阐述了选取硬件设备与完成程序的功能。
NLS-PT850是新大陆公司的一款基于嵌入式处理器的智能手持设备,它的基本硬件配置为ARM7处理器、32位RISC、74MHz频率以及标准手机键盘和扫描仪;内存为8MRAM、2MNOR Flash和32MNand Flash(可扩展至128M)。上面搭载uBASE-III嵌入式实时多任务操作系统。嵌入式硬件设备的考虑应该完全满足目标系统的要求,在功能上很容易满足,但是在性能上,尤其是在功耗上应最适合系统,而不是越充分越好。手持设备硬件结构框图如图2所示。
该手持设备配备了GPS模块,具有SIM卡接口,存储容量合适,程序下载方便,因此选取该设备来作为短信通信系统的硬件平台。
图2 手持设备硬件结构框图
uBASE-III是一个嵌入式实时多任务操作系统,主要有多任务内核模块、内存管理模块、文件系统、设备管理模块、应用程序管理模块等[2]。uBASE-III之所以在很多嵌入式设备上广泛使用,有一个很重要的原因是它提供了一个C++类库“UFCL(ubase Foundation Class Library)”。另外,它还提供了大量的API,供程序员调用。这里选取该嵌入式操作系统的原因是它支持文件操作和短信通信。
文件系统用于文件操作,将程序中的相关数据以二进制文件的形式存放在Flash存储器中。uBASE-III采用了zfile2.0文件系统,zfile2.0是专为嵌入式系统设计的Flash文件系统,常用的函数有:
◆打开一个文件以便读写其内容
ZFILE*zfopen(const char*filename,const char*pmode);
◆从当前文件指针位置开始写入size*count个字节的数据
int zfwrite(const void*buf,int size,int count,ZFILE*stream);
◆从当前文件指针位置读入size*count个字节
int zfread(void*buf,int size,int count,ZFILE*stream);
◆关闭打开的文件
int zfclose(ZFILE*stream);
uBASE-III系统对文件的支持相比其他环境也有一些不足之处,在嵌入式设备上使用文件操作有很多的限制,比如uBase-III的文件系统仅有单层目录结构,即不能创建子目录、文件系统API,不区分文本模式和二进制模式的概念,都当作是二进制模式。
短信通信是这样定义的:uBASE-III提供了一套短消息编程接口“SMS_API”,它是通过向连接在主机串行端口上的GSM Modem(或笼统地称为“移动设备(ME)”)发出AT命令来完成短消息的发送、接收,以及对移动设备的其他相关操作的。该编程接口内部使用PDU(Protocol Description Unit)格式与ME交换短消息的内容,也就是说,在AT命令的接口层来看,短消息是使用PDU报文来表示的,PDU报文是由许多字段组成的,不同的字段描述了短消息的不同属性。该编程接口使用SSmInfo结构体来描述PDU的各个字段,用户通过设定SSmInfo的不同成员来指定所要发送短消息的各种“属性”,同样,用户也是通过SSmInfo的各个成员来获取编程接口所读取到的短消息的详细信息的[3]。SMS_API提供了如下几大类操作:
◆GSMOpen():打开GSM设备;
◆InitSms():根据相应参数初始化设备;
◆SendOrWriteSm_1Sm():发送短信,支持中文和英文。
这些接口函数是在该系统上编写应用程序的基础,尤其是该系统中,GSM短信模块和文件相关操作是主要内容。
图3为短信通信系统主程序流程,系统在登录后就处于收发短信的状态中。
可以将主程序中的短信分为两部分,前台为操作员提供短信编辑命令,发送短信主要函数如下:
int SendSms(char*strPhoneAddr,unsigned char*pMessage,int msgBytes){
SSmInfo smi={0},*pSmi=&smi;
strcpy((char*)smi.Addr_MS,(char*)strPhoneAddr);int i,errcode;
for(i=0;i<5;i++){
//这里需要端口号、发送方式、SSmInfo对象、短信内容、
//有效字节数和编码方式
errcode=SendOrWriteSm_1Sm(g_ComPort,CMD_
CMGS,pSmi,(Uint8*)pMessage,msgBytes,BITS_DCS_DEF_ALPHABET);
if(errcode==0){return 0;
}
}
return 1;
}
图3 短信通信系统主程序流程
后台用于接收短信,进行处理后通常会对文件继续操作。这部分的难点在于如何设置短信通知格式,如何在后台运行处理短信和写回文件部分程序,并且要对前台的用户作出提示。因此这里用到了uBASE-III提供的多线程技术,让处理短信的主要函数工作在后台线程,有短信到来自动会处理“_thread_checkUnreadSm()”函数,列出“未读短信”,转到处理部分。这样就避免了在主程序中对“未读短信”的轮询,避免了处理器处于一种资源浪费且效率并不高的模式。函数代码如下:
static int_thread_checkUnreadSm(void*param){
RE_CODE errcode=0;
errcode=ListSm(g_ComPort,MSGSTAT_RECUNREAD,s_SmNotify,NULL,NULL,NULL);
return errcode;}
其中“ListSm()”函数是短信模块提供的API,供程序员直接调用,可以列出各种格式的短信,具体方式和其他函数可以参考相关文档。
在操作员对表具进行测试的时候,需要先上传“操作员数据”(用于存放操作员的用户名和密码)、“移动设备参数”,同时在程序运行过程中还会产生“通信命令帧核销数据”等文件,如何合理组织这些文件的结构和访问方式是本系统中又一重点内容,因为这些文件中的某些项是互相有关联的,并不完全独立。因此最核心的问题就是如何定义文件的结构,结构确定了,程序的操作方式也就确定了。拿“通信命令帧核销数据”举例,它里面包括了流水号、设备号、操作码、帧顺序号、核销状态和命令帧,后面的操作要依赖于其中的所有项,因此采用了定义结构体的方式,将上面的基本项封装起来,以结构体为基本单位去实现文件的操作。文件采用TXT格式,便于创建和导出。文件操作代码如下:
int DeleteFrameVerifyInfo(int index){
UEnterMutex(g_mtxFrameVerifyOP,TIMEOUT_INFINITE);
……//相关处理函数
ULeaveMutex(g_mtxFrameVerifyOP);
return 0;
}
其中有一点要注意,多线程持有同一文件句柄进行读写操作是允许的,文件系统内部代码会将不同线程的读写操作串行化。因此,在对文件进行读写操作时,要注意互斥问题。
嵌入式操作系统在如今很多工业领域都有广泛的应用,它的优势往往在于内核可裁剪,体积小,应用在嵌入式设备上功耗低。本文就从移动手持设备通信引申,以uBASE-III系统和NLS-PT850设备为实例,着重从短信通信方式和文件操作两个方面来讲解短信通信的嵌入式软件开发的流程和方法。该示例程序在目标设备上可稳定运行,通信状况良好,可以作为移动手持设备短信通信的一个解决方案。
[1]黄智伟,邓月明,王彦.ARM9嵌入式系统设计教程[M].北京:北京航空航天大学出版社,2008:237-238.
[2]肖巍,文大化.基于uBASE-III嵌入式程序设计的研究[J].长春理工大学学报,2010,33(4).
[3]陈冬林,谭云兰.基于GSM短消息的编码方法及其编程实现[J].计算机与现代化,2006(3).