GPS(ublox MAX 7c)移植 (飞思卡尔 IMX6 Android4.3平台)

1.Ublox 驱动在系统中位置

     GNSS Driver 就是对应了ublox的驱动, 它在android的HAL层。

                                                 GPS(ublox MAX 7c)移植 (飞思卡尔 IMX6 Android4.3平台)_第1张图片


2. 移植步骤

      ublox提供的driver是HAL的代码,最终将生成一个so文件,向gps的framwork层提供解析后的gps数据,HAL层的代码相当于Linux的应用层,在framwork层启动时会载入这个so文件,然后会启动里面的一个gps服务线程,这个线程向上提供gps数据,向下通过接口(可以为UART或是I2C)设置gps reciever(max7)和获取raw data,这个驱动实际上也不能称为驱动,也就是个linux应用。移植步骤分为两个:

    a. 测试硬件通道

       测试UART口,数据的收发。

    b. 移植driver

 

3. 测试UART口

     其实UART口的测试不用摆在最前面,把驱动调通了再看也不迟. 如果你明确的知道这个uart的gpio没有配置,或者uart驱动没加载, 或者不确定,,  那应该先看看gpio口是否配置了,如果配置了,再看uart驱动是否在board文件中加载了,  再调uart口. uart的调试主要有打开、关闭,收发数据,对于没有数据输出的uart不太好测试,那只有等设备driver调通了在测试也可以。发送数据可以测试,需要一个uart转usb的转接板,我用的pc端串口工具是putty,简单好用,测试的时候先把板子上的uart口的tx、rx接出来,直接连到转接板上,vcc和ground也接上(有的不用接VCC),这样打开putty,设置好波特率就可以调试了,这个方法也可以用来调试linux的调试端口,可以替代部分adb的功能,这个端口一般是tty**0,在我们的项目中是“ttymxc0”,而我调试gps的uart口是“ttymxc4”,uart口的命名都类似,如果不确定可以去\dev 目录下看看,当然要进入系统才能看到。

 

4.源码移植

4.1 步骤

     通过查看厂商提供文档和代码目录下的Readme,我得出了如下的Driver移植步骤

     a. 代码要拷贝到指定位置 "hardware/u-blox/gps“
     b. apply patch:

          patch文件在源码的patch目录下,区分了不同的android版本。

     c. 设置SUPL的支持(未设)

         这个选项有问过厂商一个app的小妹,但是似乎她不太懂,他们这个driver是新的3.0,还很不完善,这个小妹说要disable这个选项,那其实简单的disable掉还不行,因为还要好多编译错误,所以后来我就没有修改了,直接enable,如果要disable,要在Android.mk里面修改两个地方。

      d. 修改 u-blox.conf 

   (The u-blox.conf file is proprietary to u-blox and is read solely by the u-blox GNSS driver.)

   (The gps.conf file is read by the framework and any settings relevant to the GNSS driver are passed to it via the driver interface.)

       BAUDRATE_DEF  :这个是gps reciever的默认波特率,这个波特率会被configure文件里BAUDRATE变量重新设置,BAUDRATE是最终的波特率。

       SERIAL_DEVICE :这个是串口的设备名,ttymxc4。串口的打开在ubx_serial.cpp的openSerial里面,有的时候要查看下/dev/ttymxcf4是否有可以读写属性,否则打开可能会失败。
       RECEIVER_GENERATION:这个是gps reciever的版本,我们是7c,所以要写成7.

      e. 设置文件自动拷贝

      obj/lib/gps.default.so要拷贝到/system/lib/hw/gps.default.so, 这个系统会自动拷贝,不用考虑,makefile的自动脚步会做到。

      拷贝gps.conf and u-blox.conf 到/system/etc,这里 的rootfs就是指目标机器的目录,我们的项目是sabresd_6dq,所以是

      拷贝到out/target/product/sabresd_6dq/system/etc/下,自动拷贝也要借助mk文件的帮忙,可以使用PRODUCT_COPY_FILES这个宏,但是据说不能写在Android.mk文件里面,会报错,我写在了vim ./device/fsl/imx6/imx6.mk文件里面

 

PRODUCT_COPY_FILES := \
         device/ti/panda/gpio-keys.kl:system/usr/keylayout/gpio-keys.kl \
 	frameworks/native/data/etc/android.hardware.usb.host.xml:system/etc/permissions/android.hardware.usb.host.xml \
 	frameworks/native/data/etc/android.hardware.wifi.xml:system/etc/permissions/android.hardware.wifi.xml \
+ 	hardware/u-blox/gps/gps.conf:system/etc/gps.conf \
+	hardware/u-blox/gps/u-blox.conf:system/etc/u-blox.conf


      f. 在所有修改大致完成后,就可以开始编译项目了,我使用的是全编译,因为也修改了java文件。

       source build/envsetup.sh
       lunch

       13

       make -j20                      //20个线程一起编译,与cpu的线程数有关

 

4.2移植过程中的问题

a. 编译问题

问题一:build/core/base_rules.mk:130: *** hardware/u-blox/gps/asn1: MODULE.TARGET.STATIC_LIBRARIES.libAsn1 already defined by hardware/gps/asn1.  Stop.

这个问题经研究发现在hardware目录下有个gps目录,这个目录里面的driver是u-blox gps旧版本的driver,所以引起了这个冲突,把这个目录删除了就可以。

问题二:就是SUPL disable后一堆编译问题,所以就没有diable了

b. gps模块未供电

之前gps receiver的uart口一直没有数据,收发都没有,但是gps是只要上电就会有数据发出,所以没有数据肯定是有问题,所以我就怀疑没有供电,找到了vcc的口,果然没有电压,然后硬件帮忙飞了个线,暂时可以收发数据了,但是要根本解决还是要找到这个enable这个vcc的gpio口,然后再代码里面使能它。

vim arch\arm\mach-mx6\board-mx6q_sabresd.c
static void gps_power_on(bool on)
{
 /* Enable/disable aux_3v15 */
 gpio_request(SABRESD_CABC_EN1, "aux_3v15_en");
 gpio_direction_output(SABRESD_CABC_EN1, 1);
 gpio_set_value(SABRESD_CABC_EN1, on);
 gpio_free(SABRESD_CABC_EN1);

 

c. 模块加载

开机后,我发现并没有ublox的log打印,所以我怀疑ublox的驱动模块没有加载

查看log发现

D/GpsLocationProvider( 2494): set_capabilities_callback: 1u
E/GpsLocationProvider( 2494): no AGPS interface in set_agps_server
。。。。。。。。
D/athr_gps( 2494): gps entered nmea thread
D/athr_gps( 2494): gps entered timer thread

看到一个叫athr_gps的so被加载了,也就是说它替换了ublox的so,查看/system/lib/hw目录,发现了如下两个gps so

gps.SABRESD.so
gps.defualt.so
第一个其实就是athr_gps的so,查看模块的Android.mk可以看到名字,第二个才是ublox的so。

而且android的加载模块的方式是优先加载带开发板类型的模块,比如gps.BAORDTYPE.so,都没有最后才加载defualt的so,所以这里并没有加载gps.defualt.so。


查看源码目录:hardware/imx/libgps

看看里面的Android.mk

  1 LOCAL_PATH := $(call my-dir)
  2 ifneq ($(TARGET_PRODUCT),sim)
  3 # HAL module implemenation, not prelinked and stored in
  4 # hw/..so
  5     ifeq ($(USE_ATHR_GPS_HARDWARE),true)
  6         include $(CLEAR_VARS)
  7         LOCAL_PRELINK_MODULE := false
  8         LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
  9         LOCAL_SHARED_LIBRARIES := liblog libcutils libhardware
 10         LOCAL_SRC_FILES := athr_gps.c
 11         LOCAL_SRC_FILES += gps.c
 12         LOCAL_MODULE := gps.$(TARGET_BOOTLOADER_BOARD_NAME)
 13         LOCAL_MODULE_TAGS := optional
 14         include $(BUILD_SHARED_LIBRARY)
 15     endif
 16 endif


看到这个模块会生成一个 LOCAL_MODULE := gps.$(TARGET_BOOTLOADER_BOARD_NAME)的so,所以gps.SABRESD.so就是它生成的,所以要把它disable掉,我看到

ifeq ($(USE_ATHR_GPS_HARDWARE),true)这个判断,所以只要diable USE_ATHR_GPS_HARDWARE就可以了。修改是如下:

把所有下面的文件修改掉:

android4.3.111/device$ grep -r USE_ATHR_GPS_HARDWARE . 
./fsl-proprietary/gps/Android.mk:ifeq ($(USE_ATHR_GPS_HARDWARE),true)
./fsl/sabresd_6dq/BoardConfig.mk:USE_ATHR_GPS_HARDWARE := true
./fsl/sabreauto_6q/BoardConfig.mk:USE_ATHR_GPS_HARDWARE := false
./fsl/arm2_6sl/BoardConfig.mk:USE_ATHR_GPS_HARDWARE := true
./fsl/evk_6sl/BoardConfig.mk:USE_ATHR_GPS_HARDWARE := false
./fsl/arm2_6dq/BoardConfig.mk:USE_ATHR_GPS_HARDWARE := true
./fsl/hbs_6dq/BoardConfig.mk:USE_ATHR_GPS_HARDWARE := false
./fsl/imx53_smd/BoardConfig.mk:USE_ATHR_GPS_HARDWARE := true

 

d. 在模块的readme里面看到可以支持电源管理,但是要有gpio连接,而且要修改如下的函数,这个还没有做,先放在这里:
Two functions within the file ubxgpsstate.cpp
bool CUbxGpsState::powerOn(void)
void CUbxGpsState::powerOff(void)
e. 据readme说这个v3.0是u-blox M8的driver,但也可使用 u-blox 7 and 6 的driver

3. 测试方法

a. pc端工具u-center:

    在系统驱动没有调试好之前,如果想测试串口和gps硬件,可以使用pc端工具u-center,usb连接引出的串口线,来调试uart的数据是否正确,但是在没有发送修改波特率之前,ublox的uart口的默认波特率是9600,这个要注意下。

b. 手机端apk u-center

     在没有adb之前我使用了编译的方法,把apk文件安装在了系统上。

     把apk文件放rootfs的app目录下:

     out/target/product/sabresd_6dq/system/app/u-center.apk

4. 设置接受数据的速率(默认1000ms)

调用:

android.location.LocationManager.requestLocationUpdates(String provider, long minTime, float minDistance, LocationListener listener)


设置minTime为指定值,我们这里为500ms, 如下log中:

D/u-blox  ( 2461): CGpsIf::setPositionMode: (1648632264): mode=1(GPS_POSITION_MODE_MS_BASED) recurrence=0(GPS_POSITION_RECURRENCE_PERIODIC) min_interval=500 preferred_accuracy=0 preferred_time=0
V/u-blox  ( 2461): CUbxGpsState::putRate: Put Rate rate=500
V/u-blox  ( 2461): CUbxGpsState::writeUbxCfgRate: Send CFG-RATE rate=500
V/u-blox  ( 2461): CUbxGpsState::saveAiding: Saving aiding data to /data/persistence.agnss
V/u-blox  ( 2461): CUbxGpsState::saveDatabase: Encoded Measurement rate!
V/u-blox  ( 2461): CUbxGpsState::saveDatabase: Encoded LEG Receiver Aiding State data!
V/u-blox  ( 2461): CUbxGpsState::saveDatabase: Create file structure for encoded data!
V/u-blox  ( 2461): CUbxGpsState::saveAiding: Aiding data saved succesfully

你可能感兴趣的:(Android)