基于uClinux的GPSOne/GPS双定位信息接收
2007-05-31 14:52
267 查看
在系统存在多个输入或输出流但不希望其中任一个流被阻塞的场合,经常使用复用I/O的方法解决。uClinux中,用户程序多使用select机制实现I/O复用控制,select函数允许进程对一个或多个设备文件进行非阻塞的读或写操作。
select的函数定义于中,原型如下:
int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
该函数允许进程指示内核等待多个事件中的任一个发生,并仅在一个或多个事件发生或经过某指定的时间后才唤醒进程。该函数的第1个参数n表示文件描述符集合中最大值再加1;第2个参数readfds,表示可读的文件描述符集合,用于查看是否有可读取数据;第3个参数writefds表示可写的文件描述符集合,用于查看是否能写入数据;第4个参数exceptfds用于异常控制;最后一个参数timeout决定了select将会阻塞多久才把控制权移交给调用它的进程。调用select之前,必须对此参数进行初始化。若timeout值为0,则select直接返回0。此时I/O操作没有等待就立即返回,相当于一种非阻塞I/O的调用。
在应用中,通常先调用select查看哪个I/O设备可读/写。如果没有可读/写的设备,并且没有设置超时返回功能,那么进程将阻塞在select调用上;如果有,则select函数返回,紧接着可通过测试参数readfds和writefds来确定哪个I/O设备可读或能写,而后以非阻塞方式操作该I/O设备,从而实现期望功能。
在实现select应用的过程中,还会使用到这些select相关接口:
void FD_ZERO(fd_set *fdset);
void FD_SET(int fd, fd_set *fdset);
void FD_CLR(int fd, fd_set *fdset);
int FD_ISSET(int fd
, fd_set *fdset);
其中,fd_set表示设备文件描述符集合,fd表示设备文件描述符。FD_ZERO函数用于清除设备文件描述符集合所有元素;FD_SET函数用于把某个文件描述符添加至文件描述符集合;FD_CLR函数用于从文件描述符集合中删除某个文件描述符;而FD_ISSET用于检测设备文件描述符集合的某个文件描述符是否有效,有效则表示该位对应的设备有数据可读或可写。
4 轮询检测方法与select方法的比较
4.1 轮询检测方法
轮询检测方法是指对串口进行非阻塞的读写操作。当操作未成功时,让进程或线程挂起一段时间,然后再使用非阻塞调用来重新查询串口是否有可读/写数据。用此方法,相当于系统不断地对接收或者发送操作的执行结果进行探测,直到把数据发出去或者接收完成定量的数据,才退出此轮询循环。而对于接收与发送不确定哪个时刻会到达的情况,即随机性比较高的读/写操作,采用轮询方法会造成CPU资源浪费。如果轮询频率过低,则会使系统少接收一部分数据或接收过慢;反之,则接收方会因为等待太久而不能接收更多新的数据。轮询频率过高的情况,会让CPU过度频繁地查询串口状态,造成过多的耗用CPU执行周期,降低其利用率。
4.2 select机制能充分利用系统时间的原因
与频繁调用非阻塞读写函数来轮询监听I/O的方法相比, select调用允许用户把进程本身挂起来,同时使系统内核监听所要求的一组文件描述符的任何活动。只要确认在任何被监控的文件描述符上出现活动,select调用将返回指示该设备文件已经准备好的信息。这样就使进程能相对实时地监测到I/O设备上随机的变化,而不必由进程本身去探测输入数据是否准备好。
5 利用select I/O的机制实现GPS与GPSOne数据的接收
本文提出的基于GPS与GPSOne信号的双定位的解决方案,即对系统两个串口定位信号的监听与处理,充分利用uClinux下基于Select的I/O复用机制,更利于较复杂系统的控制和管理。
方案实现的程序流程如图4所示。
以下代码为使用Select I/O机制接收GPS信息和GPSOne信息的软件实现:
int Maxfd = fd_gps>fd_gpsOne? fd_gps: fd_gpsOne;//得到串口描述符中较大的一个
struct timeval tv;//定义超时控制结构
fd_set fds; //文件描述符集合变量
tv.tv_sec = 5;//设定超时值 5 s
tv.tv_usec = 0;
while(1){//通过GPSOne串口,发送GPSOne定位请求
Rt = send_port (fd_gpsone, "AT+GPSSTRT/r", strlen("AT+GPSSTRT/r");
if (Rt) == -1)
printf("Error happened!");
FD_ZERO (&fds);//初始化文件描述符集合
FD_SET(*fd_gps, &fds);//设置文件描述符集合的相应位
FD_SET(fd_gpsOne, &fds);//使用select,让内核开始监听GPSOne和GPS串口设备
fd_sel = select((Maxfd)+1, &fds_gps, NULL, NULL, &tv);
if (fd_sel < 0){
printf("Error happened while receiving gps data./n");}
else if (FD_ISSET(*fd_gps, &fds)){//若GPS串口设备有数据可读
recv_len = recv_port(fd_gps, buf, 254);
if (recv_len > 0){
memcpy (gps_info, buf, recv_len)
;//信息保存到
gps_info数组中gps_info_process(gps_info);//解析定位信息处理
}
}
else if (FD_ISSET(*fd_gpsOne, &fds)){//若GPSOne串口设备有数据可读
recv_len = recv_port(*fd_gpsOne, buf, 254);
if (recv_len > 0){memcpy (gpsOne_info, buf, recv_len); //信息保存到gpsOne_info数组中
gpsOne_info_process(gpsOne_info);//解析定位信息处理
}
}
sleep(1);
}
6 设计总结
本文详细说明了串口编程的基本方法和步骤,并提出一种基于select的I/O复用机制处理多个串口信息的方案,同时给出这种方案的具体实现。此方案具有较高的可靠性,保证了多个串口的信息可以很好地被接收和处理,而且不相互干扰,利于系统更好地管理多个文件设备。特别是在数据采集和数据传输领域中,select利用内核同时监听多个设备描述符机制,可以被广泛地应用于嵌入式系统多路I/O采集的设计中。
参考文献
[1] Kurt Wall. GNU/Linux编程指南[M].张辉,译. 北京:清华大学出版社,2005.
[2] Richard Stevens W. UNIX网络编程[M]. 第2版. 第1卷·套接口API和X/Open传输接口API.北京:清华大学出版社,1998:121131.
[3] 马忠梅,李善平,康慨,等. ARM&Linux嵌入式系统教程[M].北京:北京航空航天大学出版社,2005:255261.
select的函数定义于中,原型如下:
int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
该函数允许进程指示内核等待多个事件中的任一个发生,并仅在一个或多个事件发生或经过某指定的时间后才唤醒进程。该函数的第1个参数n表示文件描述符集合中最大值再加1;第2个参数readfds,表示可读的文件描述符集合,用于查看是否有可读取数据;第3个参数writefds表示可写的文件描述符集合,用于查看是否能写入数据;第4个参数exceptfds用于异常控制;最后一个参数timeout决定了select将会阻塞多久才把控制权移交给调用它的进程。调用select之前,必须对此参数进行初始化。若timeout值为0,则select直接返回0。此时I/O操作没有等待就立即返回,相当于一种非阻塞I/O的调用。
在应用中,通常先调用select查看哪个I/O设备可读/写。如果没有可读/写的设备,并且没有设置超时返回功能,那么进程将阻塞在select调用上;如果有,则select函数返回,紧接着可通过测试参数readfds和writefds来确定哪个I/O设备可读或能写,而后以非阻塞方式操作该I/O设备,从而实现期望功能。
在实现select应用的过程中,还会使用到这些select相关接口:
void FD_ZERO(fd_set *fdset);
void FD_SET(int fd, fd_set *fdset);
void FD_CLR(int fd, fd_set *fdset);
int FD_ISSET(int fd
, fd_set *fdset);
其中,fd_set表示设备文件描述符集合,fd表示设备文件描述符。FD_ZERO函数用于清除设备文件描述符集合所有元素;FD_SET函数用于把某个文件描述符添加至文件描述符集合;FD_CLR函数用于从文件描述符集合中删除某个文件描述符;而FD_ISSET用于检测设备文件描述符集合的某个文件描述符是否有效,有效则表示该位对应的设备有数据可读或可写。
4 轮询检测方法与select方法的比较
4.1 轮询检测方法
轮询检测方法是指对串口进行非阻塞的读写操作。当操作未成功时,让进程或线程挂起一段时间,然后再使用非阻塞调用来重新查询串口是否有可读/写数据。用此方法,相当于系统不断地对接收或者发送操作的执行结果进行探测,直到把数据发出去或者接收完成定量的数据,才退出此轮询循环。而对于接收与发送不确定哪个时刻会到达的情况,即随机性比较高的读/写操作,采用轮询方法会造成CPU资源浪费。如果轮询频率过低,则会使系统少接收一部分数据或接收过慢;反之,则接收方会因为等待太久而不能接收更多新的数据。轮询频率过高的情况,会让CPU过度频繁地查询串口状态,造成过多的耗用CPU执行周期,降低其利用率。
4.2 select机制能充分利用系统时间的原因
与频繁调用非阻塞读写函数来轮询监听I/O的方法相比, select调用允许用户把进程本身挂起来,同时使系统内核监听所要求的一组文件描述符的任何活动。只要确认在任何被监控的文件描述符上出现活动,select调用将返回指示该设备文件已经准备好的信息。这样就使进程能相对实时地监测到I/O设备上随机的变化,而不必由进程本身去探测输入数据是否准备好。
5 利用select I/O的机制实现GPS与GPSOne数据的接收
本文提出的基于GPS与GPSOne信号的双定位的解决方案,即对系统两个串口定位信号的监听与处理,充分利用uClinux下基于Select的I/O复用机制,更利于较复杂系统的控制和管理。
方案实现的程序流程如图4所示。
以下代码为使用Select I/O机制接收GPS信息和GPSOne信息的软件实现:
int Maxfd = fd_gps>fd_gpsOne? fd_gps: fd_gpsOne;//得到串口描述符中较大的一个
struct timeval tv;//定义超时控制结构
fd_set fds; //文件描述符集合变量
tv.tv_sec = 5;//设定超时值 5 s
tv.tv_usec = 0;
while(1){//通过GPSOne串口,发送GPSOne定位请求
Rt = send_port (fd_gpsone, "AT+GPSSTRT/r", strlen("AT+GPSSTRT/r");
if (Rt) == -1)
printf("Error happened!");
FD_ZERO (&fds);//初始化文件描述符集合
FD_SET(*fd_gps, &fds);//设置文件描述符集合的相应位
FD_SET(fd_gpsOne, &fds);//使用select,让内核开始监听GPSOne和GPS串口设备
fd_sel = select((Maxfd)+1, &fds_gps, NULL, NULL, &tv);
if (fd_sel < 0){
printf("Error happened while receiving gps data./n");}
else if (FD_ISSET(*fd_gps, &fds)){//若GPS串口设备有数据可读
recv_len = recv_port(fd_gps, buf, 254);
if (recv_len > 0){
memcpy (gps_info, buf, recv_len)
;//信息保存到
gps_info数组中gps_info_process(gps_info);//解析定位信息处理
}
}
else if (FD_ISSET(*fd_gpsOne, &fds)){//若GPSOne串口设备有数据可读
recv_len = recv_port(*fd_gpsOne, buf, 254);
if (recv_len > 0){memcpy (gpsOne_info, buf, recv_len); //信息保存到gpsOne_info数组中
gpsOne_info_process(gpsOne_info);//解析定位信息处理
}
}
sleep(1);
}
6 设计总结
本文详细说明了串口编程的基本方法和步骤,并提出一种基于select的I/O复用机制处理多个串口信息的方案,同时给出这种方案的具体实现。此方案具有较高的可靠性,保证了多个串口的信息可以很好地被接收和处理,而且不相互干扰,利于系统更好地管理多个文件设备。特别是在数据采集和数据传输领域中,select利用内核同时监听多个设备描述符机制,可以被广泛地应用于嵌入式系统多路I/O采集的设计中。
参考文献
[1] Kurt Wall. GNU/Linux编程指南[M].张辉,译. 北京:清华大学出版社,2005.
[2] Richard Stevens W. UNIX网络编程[M]. 第2版. 第1卷·套接口API和X/Open传输接口API.北京:清华大学出版社,1998:121131.
[3] 马忠梅,李善平,康慨,等. ARM&Linux嵌入式系统教程[M].北京:北京航空航天大学出版社,2005:255261.
相关文章推荐
- GPS定位信息的接收
- GPS定位信息的接收
- 基于Qt/Embedded的物流信息终端导航定位功能设计
- 实现Android的不同精度的定位(基于网络和GPS)
- 基于GPS的城市管道精确定位系统的单片机控制
- 转载: 对GPS全球定位系统定位信息的接收以及对各定位参数数据的提取方法(VC++)
- 基于STM32和GPS-NEO-6M模块实现GPS导航定位的
- 【ENVI入门系列】03.基于自带定位信息的几何校正
- 安卓开发-Gps定位获取位置信息
- iphone获取GPS的数据信息并定位
- 实现Android的不同精度的定位(基于网络和GPS)
- 基于Qt/Embedded的物流信息终端导航定位功能设计
- iphone中GPS精确定位及反向获取地址信息
- linux下编程epoll实现将GPS定位信息上报到服务器
- 实现Android的不同精度的定位(基于网络和GPS)
- Android开发,GPS获取实时时间并转为北京时间,定位信息,海拔高度,并进行显示
- 【iOS开发】解决iOS 8无法调用GPS定位信息的问题
- 基于基站和GPS的LBS定位
- iphone中GPS精确定位及反向获取地址信息
- iphone中GPS精确定位及反向获取地址信息