快一个月没更文了,这一个月都在处理一个作业,在高通Android11渠道上移植GNSS功用,中心涉及到很多技能细节,遂记载一下。

首要要搞清楚两个问题

什么是GNSS

这儿我简略阐明一下,GNSS全称是Global Navigation Satellite System,翻译过来叫全球定位卫星导航体系。那它跟咱们常说的GPS是啥关系呢?实际上GNSS泛指一切的卫星导航体系,包含全球的、区域的和增强的,GPS仅仅GNSS其中的一种,除了GPS,还有中国的斗极卫星导航体系,俄罗斯的Glonass,欧洲的Galileo等。

高通Android 11平台上移植GNSS

为什么要往Android渠道上移植GNSS

从大的概念来说,Google的Android渠道其实也仅仅供给了一个标准,它并不会对接详细的硬件厂商,所以Android体系其实可以说是一个空壳,需求什么样的功用就往上面移植什么功用,比方GNSS,Camera,Sensor,Audio,Video,Display等,而自己最近就担任公司某个项目的GNSS上层移植作业。

预备作业

移植作业大致分以下几个部分:

  • 硬件移植,确认移植哪个厂商的硬件
  • 驱动移植,确认Kernel层与HAL层的通讯协议,本文选用的UART通讯,除此之外还可以使用RIL通讯
  • HAL移植,解析NMEA数据,给上层供给接口,供HIDL和JNI调用
  • 适配Selinux,增加访问驱动节点的权限
  • 应用层测验验证,装置GPS测验东西(高德地图等),测验是否可以获取定位数据

自己主要担任过程3~过程5,HAL移植首要要得到该厂商对应的库文件,由于每个厂商的标准不相同,所以解析NMEA数据的办法也不太相同,所以这个必须要厂家供给,可所以c/c++源文件,也可所以编译好的so库,自己参与的项目是选用so。硬件预备好了,驱动调好了,拿到了厂商库文件,上层就可以开端移植了。

关于NMEA(National Marine Electronics Association),它是为海用电子设备拟定的标准格局,GNSS通讯数据也选用这种格局,大约长这样

高通Android 11平台上移植GNSS

详细格局定义可参阅《NMEA协议阐明及解析》

开端移植
  1. 首要在device目录下装备so库和UART装备文件的存放路径,同时增加对应的HAL层服务

    PRODUCT_PACKAGES += \
        android.hardware.gnss@1.0-impl \
        android.hardware.gnss@1.0-service
    # Add for gps.default.so
    PRODUCT_COPY_FILES += \
        vendor/gps/lib64/gps.default.so:vendor/lib64/hw/gps.default.so \
        vendor/gps/lib64/gps_cfg.inf:vendor/etc/gps_cfg.inf
    

    留意这儿so库的命名不是随意的,gps_cfg.inf中主要是装备UART节点称号和波特率

    NMEA_PORT_PATH=/dev/ttyXXX
    BAUD_RATE=115200
    
  2. 注册hal服务,类似Android四大组件相同,hal服务也需求在manifest.xml文件中注册

        <!-- gnss -->
        <hal format="hidl">
            <name>android.hardware.gnss</name>
            <transport>hwbinder</transport>
            <version>1.0</version>
            <interface>
                <name>IGnss</name>
                <instance>default</instance>
            </interface>
            <fqname>@1.0::IGnss/gnss_vendor</fqname>
        </hal>
    

    留意,除了要在manifest.xml中注册,还需求在compatibility_matrix.N.xml中注册,原因参见Google官网阐明,其中N为最新的版本号。

        <hal format="hidl" optional="true">
            <name>android.hardware.gnss</name>
            <version>1.0</version>
            <interface>
                <name>IGnss</name>
                <instance>default</instance>
            </interface>
        </hal>
    

    留意两个文件中的version版本号要共同,不然会编译失败

  3. 删除厂商自带的GNSS装备,自己调试的是高通渠道的,高通渠道自带GNSS,现在移植其他厂商的GNSS后要将高通的装备删除去。这个就不代码演示了,直接全局查找高通的vendor.xxx.gnss,xxx为厂商称号,然后将其删除即可。

  4. 到这一步,可以先编译验证一下,看能不能获取到定位数据,这时在开机log中会呈现大量有关gnss权限的日志

    04-21 09:01:33.647   415   415 W gnss@1.0-servic: type=1400 audit(0.0:24): avc: denied { read write } for name="ttyXXX" dev="tmpfs" ino=13516 scontext=u:r:hal_gnss_default:s0 tcontext=u:object_r:vendor_location_device:s0 tclass=chr_file permissive=0
    

    而且通过GPS测验东西是获取不到定位数据的,上述日志是典型的selinux错误日志,关于selinux,这儿不做详细讲解,可参阅《Android安全策略SELinux》,这儿日志的大约意思便是hal_gnss_default要访问vendor_location_device需求{ read write }权限,这种情况一般依据日志去增加权限就可以了,在device目录下装备

    allow hal_gnss_default vendor_location_device:chr_file { read write open };
    

    这儿贴一张selinux装备的个人经验办法图

高通Android 11平台上移植GNSS

  1. 权限增加完毕之后,编译验证,使用GPS测验东西,成功获取到定位数据

高通Android 11平台上移植GNSS
由于Display还没调好,所以屏幕分辨率有点儿低,迁就看吧。GPS测验东西下载链接放到文末端,当然,也可以使用高德地图测验,我这个分辨率翻开高德地图简直无法看,就不贴图了。

灵魂拷问

看到这儿,你或许不禁要问,就这么点作业,还要搞一个月吗?肯定摸鱼了。啊,这个要怎么说呢,首要第一,移植方案落地之前肯定需求花大量的时刻去做预备作业,比方从上层到底层,gnss的通讯流程,这个你得搞理解

高通Android 11平台上移植GNSS

这儿我打算独自写一篇关于GNSS从APP层到HAL的通讯流程,这儿先贴个大约流程图。

其次,由于涉及到跨厂商联调,这个难度跟客户做过联调的朋友应该都知道。然后由于涉及到权限te文件和makefile文件,只能全编译验证,我这个机器装备,Android 11初次全编译所需求的时刻大约是5个小时,后面增量编译也要一二非常钟,所以这个也很费时刻。最终,由于是公司内部项目,还涉及到一些内部问题,比方,高速URAT相比于一般URAT,需求额定的装备,这个作为framework开发,跟BSP开发沟通起来真的是困难,由于彼此都不太懂对方的作业内容。

拓宽

移植期间,深化学习了一下GPS,拜读了这篇文章《GPS定位技能》,里边讲解了GPS定位原理,地图投影,时刻体系,方位计算办法,GPS体系组成,定位发生差错的原因及削减差错的办法等等,虽然有些公式性的知识不太懂,但非常感叹博主知识面之广,不得不敬服,强烈推荐大家也去拜读一下。

附件

GPS测验东西:

链接: pan.baidu.com/s/1xvmwxFi0… 提取码: 5y61 复制这段内容后翻开百度网盘手机App,操作更便利哦