GPS机制分析(5)

news/2024/7/4 9:42:21

1. 概述

​ 上面的几篇文章论述了gps的打开启动初始化等动作,万事俱备只欠东风了。这一系列文章主要讲的是Position信息如何从modem层传递到loc eng层最后一直到Java上层的。由于loc eng层到modem层是属于消息触发的,也就是说正常的流程是:modem层传上来一个消息,经过一系列处理传递到loc eng层,loc eng层传递给gps库,android framework层,然后上层应用就可以获取到数据。

​ 高通平台的GPS核心部分都在modem里面,这里面实现了GPS相关的协议,可以把这个部分看做是GPS service,另外一部分在ap侧,我们把这部分看做是GPS client。Client主要是通过QMI的通信方式接收service发过来的信息,client也可以通过QMI发送信息给service,QMI之上有一个loc_api层,具体作用是通过qmi读取service发送过来的信息,当然也可以通过qmi发送信息给service。

2. AP数据结构

​ 这里我们主要涉及三个重要的数据结构,分别是qmiLocEventPositionReportIndMsgT_v02、UlpLocation、GpsLocation:qmiLocEventPositionReportIndMsgT_v02是一个很重要的数据结构,它是AP侧和Modem侧之间传递的Position数据结构,是一个连接两者的桥梁,由于结构比较庞大,截取一部分如下,完整结构具体请看:

vendor/qcom/opensource/location/loc_api/loc_api_v02/location_service_v02.h

img

UlpLocation*是loc eng层使用的格式, UlpLocation里包含了GpsLocation:

hardware/qcom/gps/core/gps_extended_c.h

img

GpsLocation*是hal层能够识别的格式:

hardware/libhardware/include/hardware/gps.h;

img

​ 三个数据结构的大致关系是:解析qmiLocEventPositionReportIndMsgT_v02类型的event,

​ 提取其中需要的数据,填充到UlpLocation结构中,由于包含了GpsLocation,因此GpsLocation也同时被填充;

小结:

​ 数据库都准备好了,下面就开始分析数据是如何从modem到AP侧,最后到Java上层的。

3. Modem流程分析

modem_proc\gps\gnss\loc_mw\src\ loc_task.c

img

首先初始化middlewaremodule,设置IPC以及timers,初始化QMI等一系列工作:

img

通过os_IpcReceive接受消息,调用loc_middleware_proc对p_msg进行处理:

img

在loc_middleware_proc函数里根据p_msg的MsgId判断消息类型,再调用不同的处理函数:

img

在locQmiShimProcessIpc函数中,与location相关的命令再调用locQmiShimProcessInitQmiLoc函数处理:

modem_proc\gps\gnss\loc_mw\src\loc_qmi_shim.c

img

img

在这个函数里注册了locQmiShimClientConnectCb这个回调:

img

而这个回调函数主要的作用是通知shim层连接的到来,初始化连接,触发loc:

img

img

在locQmiShimEventCb回调中,第二个参数是e_LocEvent,即loction事件,函数根据这个事件的类型,调用相关的处理函数,我们这边只关注LOC_EVENT_PARSED_POSITION_REPORT事件类型,即解析后的position的report事件:

modem_proc/gps/gnss/loc_mw_inc/loc_api_2.h

img

img

往下调用了locQmiHandleParsedPositionReport函数,通过解析第二个参数pz_ParsedPositionRpt,

解析出经纬度等GPS信息,填充到pz_IndInfo:

img

这里我们看到这个数据结构:qmiLocEventPositionReportIndMsgT_v02,也就是在ap侧解析的GPS的event信息,

并最终剥离出上层能够识别的GpsLocation数据结构的:

img

img

这里使用到一个宏:LOC_QMI_SHIM_SET_VALUE,作用就是验证variable是否有效,如果有效,就把value的值赋值给variable:

img

img

在函数最后,将q_Id的值设为QMI_LOC_EVENT_POSITION_REPORT_IND_V02,

AP侧在eventCb里根据QMI_LOC_EVENT_POSITION_REPORT_IND_V02做判断,调用reportPosition方法继续传输数据。

4. NMEA数据的解析

先看一段QXDM log,是获取NMEA的一个大致流程:

img

loc_middleware_proc中打印Received IPC Message with id 10.Loc enabled 1

img

因为cmd_type是1,也就是LOC_CMD_TYPE_REPORT_POSITION:

modem_proc\gps\gnss\loc_mw\src\loc_task.h

img

img

因此接下来调用了loc_pd_process_cmd_request这个函数,在这个函数中,因为cmd_type是LOC_CMD_TYPE_REPORT_POSITION类型,因此调用loc_pd_notify_client函数:

modem_proc\gps\gnss\loc_mw\src\ loc_pd.c

img

​ 在loc_pd_notify_client函数中,调用loc_pd_report获取position信息,对应输出的log:loc_pd_get_sv_repoet:health_svmask 0x0和gnss report, mask = 48, num_sv = 19,再调用loc_client_invoke_callback函数,eventtype是LOC_EVENT_NMEA_POSITION_REPORT,处理nmea的event事件,对应输出的log:“loc_client_invoke_callback, client_handle = 3, event_type = 2, maxclients = 5”

img

img

img

img

loc_pd_ext_event_cb函数中,调用了loc_pd_queue_report_position_request:

img

img

img

img

​ 在loc_middleware_queue_cmd_internal函数里的处理,对应了log:“send msg_id=10, cmd=1 to locthread”。最后调用了tm_nmea_gpgga_put函数,对应输出”Generated NMEA $GPGGA”,在tm_nmea.c里,有分别处理GPGGA、GNGNS、GPGSV、GPGSA等格式的函数,感兴趣的可以深入学习了解:

modem_proc\gps\gnss\sm\tm\src\tm_nmea.c

img

modem_proc\gps\gnss\sm\tm\src\tm_util.c

img

img

最后格式化输出,也就是按照NMEA标准的格式输出。

5. gps数据从modem到AP

从loc_api层的locClientIndCb开始走起:

vendor/qcom/opensource/location/loc_api/loc_api_v02/loc_api_v02_client.c

locClientIndCb的主要作用是根据indications的类型,将解析出来的数据发给相应的callback处理:

img

首先获取message的size和indType,后面根据IndType判断indication的类型:

img

解析qmi message,ind_bug是传入数据,indBuffer是解析之后的数据;

img

​ Qmi_client_message_decode返回QMI_NO_ERR,并且解析的indType是eventIndType后,走下面的流程,eventCallback赋值给了localEventCallback,解析出来的数据indBuffer赋值给了eventIndUnion.pPositionReportEvent,

​ 其中pPositionReportEvent的数据类型是qmiLocEventPositionReportIndMsgT_v02:

img

qmiLocEventPositionReportIndMsgT_v02里包含了latitude、longitude等位置信息:

img

​ 上面eventCallback赋值给了localEventCallback,其实也就是赋值给了后面的globalEventCb,在继续往下之前,我们看一下globalEventCb的绑定过程:

vendor/qcom/opensource/location/loc_api/loc_api_v02/LocApiV02.cpp

img

img

img

globalCallbacks的赋值又是一个典型的callback绑定动作,由于类型是locClientCallbacksType,

所以是把globalEventCb绑定到locClientCallbacksType的一个成员函数上,这个成员函数就是eventIndCb。

vendor/qcom/opensource/location/loc_api/loc_api_v02/loc_api_v02_client.h

img

继续回到locClientOpen函数中,又调用了locClientOpenInstance:

vendor/qcom/opensource/location/loc_api/loc_api_v02/loc_api_v02_client.c

img

img

​ 到此,eventCallback跟eventIndCb成功绑定,也就是说eventCallback 跟globalEventCb绑定在一起了,由于eventCallback在前面绑定到了localEventCallback,所以就是说localEventCallback绑定的是globalEventCb;因此对localEventCallback的调用,也就是调用了globalEventCb:

vendor/qcom/opensource/location/loc_api/loc_api_v02/LocApiV02.cpp

img

​ 由于locApaV02Instance是LocApiV02类型的,所以调用到了LocApiV02的eventCb函数,在eventCb里根据eventId做判断,如果eventId是QMI_LOC_EVENT_POSITION_REPORT_IND_V02,则调用reportPosition:

img


http://www.niftyadmin.cn/n/2828931.html

相关文章

GPS机制分析(6)

7. gps数据从HAL传输到Java ​ 上面UlpLocation类型的mLocation作为参数传入,这里传递的还是UlpLocation类型的数据,不是hal层使用的GpsLocation类型,因此我们看一下UlpLocation类型的数据转换成GpsLocation类型的数据的过程: h…

IPC—Android Binder (1)

IPC是Inter-Process Communication的缩写,含义就是跨进程通信。 多进程场景 WebView加载图片推送 原因 内存不够->内存就够了 App运行独立的虚拟机——每个进程分配运行内存是有限的——32M、64M、48M 加载一个大图片——直接OOM 如果一旦奔溃,…

AndroidGPS定位应用流程

AndroidGPS定位应用流程 这里先了解下应用层流程。 根据这个框架,GPS在应用层实现的最基本流程示例: public class MainActivity extends Activity {private LocationManager mLocationManager;Overrideprotected void onDestroy() {super.onDestroy…

怎么把照片做成消消乐_开心消消乐特效制作如何快速的消除过关

开心消消乐特效制作如何快速的消除过关。在闯关的时候,我们想要制作三星过关,特效的制作是我们必须的过程。如果没有特效帮助我们大量的消除,想要得到3星的分数是比较困难的。但是在释放特效的时候,我们是需要一定的技巧的。单独的…

debian卸载php_在 Ubuntu/Debian 下安装 PHP7.3 教程

介绍最近的 PHP 7.3.0 已经在 2018 年12月6日 发布 GA,大家已经可以开始第一时间体验新版本了,这里先放出 PHP7.3 安装的教程以便大家升级。适用系统: Ubuntu 18.04 LTS / Ubuntu 16.04 LTS / Ubuntu 14.04 LTS / Debian 9 stretc…

图解C/C++中函数参数的值传递、指针传递与引用传递

因为一直对这几种函数参数的传递方式理解的不是很透彻,花了一段时间仔细捋清了他们之间的区别。这个问题也是编程初级阶段会经常遇到的问题,也是有可能在面试中遇到的基本问题,在此进行了简单的总结一下,一是加深自己的理解&#…

Scenario 6 –HP C7000 Virtual Connect FlexFabric SUS with A/A Uplinks, 8

概述:HP c7000 VC FlexFabric SUS配置为Active/Active、LACP、FCoE、vSphere首先,创建两个SUS,名称分别是VLAN-Trunk-1和VLAN-Trunk-2。VLAN-Trunk-1共有2个uplink Port( Bay1-VC的x5、x6),VLAN-Trunk-2共有…