gps.c阅读

读懂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阻塞状态,直到线程被停止

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值