读懂gps.c首先需要理解如下几个方法
epoll机制:
https://blog.csdn.net/yusiguyuan/article/details/15027821
https://blog.csdn.net/outsinre/article/details/5669764
socketpair的用法和理解
https://blog.csdn.net/weixin_40039738/article/details/81095013
接下来看代码
static int
gps_state_init( GpsState* state, GpsCallbacks* callbacks )
{
...
// state->control[0]用于写,state->control[1]用于读
if ( socketpair( AF_LOCAL, SOCK_STREAM, 0, state->control ) < 0 ) ;
...
// state->monitor_control[0]用于写,state->monitor_control[1]用于读
if ( socketpair( AF_LOCAL, SOCK_STREAM, 0, state->monitor_control ) < 0 ) ;
...
// 创建并启动state thread
state->thread = callbacks->create_thread_cb( "gps_state_thread", gps_state_thread, state );
...
// 创建并启动monitor thread
state->monitor_thread = callbacks->create_thread_cb( "gps_monitor_thread", gps_monitor_thread, state );
}
static void
gps_state_thread(void* arg)
{
...
for (;;) {
...
nevents = epoll_wait( epoll_fd, events, 2, -1 );
...
for (ne = 0; ne < nevents; ne++) {
...
int fd = events[ne].data.fd;
if (fd == control_fd) { // 接收父线程write的cmd
...
}else
if (fd == gps_fd) {
for (;;) {
// 从串口读数据
// 将数据拆分并给相应测成员变量赋值
// 将数据丢给callback以供应用层数据监听
...
}
}
}
}
}
static void
gps_monitor_thread(void* arg)
{
...
while(1)
{
...
// epoll_fd中有事件会立即返回,否则一直wait,直到timeout 返回值为0,0为超时
nevents = epoll_wait( epoll_fd, events, 1, timeout);
if(nevents == 0) //timeout
{
if(gps_state == GPS_STATE_ENABLED && (epoll_timeout_ctrl == 1) )
{
chip_to_reset(); // 监控芯片是否有正常出数据,若长时间无数据则重启芯片
ALOGI("[%s %d]no nmea > 3s, chip reset", __FUNCTION__, __LINE__);
}
}
...
}
}
static void
gps_state_start( GpsState* s ) {
...
do { ret=write( s->control[0], &cmd, 1 ); }
...
send_cmd_to_monitor(s->monitor_control[0], CMD_START);
...
}
static void
gps_state_stop( GpsState* s ) {
...
send_cmd_to_monitor(s->monitor_control[0], CMD_STOP);
do { ret=write( s->control[0], &cmd, 1 ); }
...
}
具体流程如上图:
1.开机LocationService会启动,随即调用gps.c中的gps_state_init
2.init过程主要创建两个线程,线程一直处于epoll_wait状态
3.直到有应用获取定位 数据,会调用到 gps_state_start,两个线程的for(;;)中的epoll_wait开始产生返回值,阻塞状态解除
4.直到gps_state_stop被调用,两个线程重新进入到epoll_wait阻塞状态,直到线程被停止