zoukankan      html  css  js  c++  java
  • 高通MSM8255 GPS 调试分析&&Android系统之Broadcom GPS 移植【转】

    本文转载自:http://blog.csdn.net/gabbzang/article/details/12063031

    http://blog.csdn.NET/dwyane_zhang/article/details/6775738

    没事做整理一下GPS的流程,也算给自己一个交代。

    1.硬件抽象层:

    高通MSM的硬件层代码在:hardware/qcom/gps/loc_api下,高通的GPS集成在baseband侧,与Modem部分一样,同样是基于share Memory上高通自有的RPC协议实现。所以高通的硬件层分为两部分,一部分实现的是:硬件抽象层的接口实现,另一部分实现的是基于RPC协议封装的具体控制和数据操作,该部分主要是利用高通的RPC代码生成器生成。两个部分是通过一个glue层粘合在一起的。高通MSM的硬件抽象层在其子目录 libloc_api中,主要在loc_eng.cpp中。loc_eng_ioctl.cpp用于承载到glue层的具体控制和回调。而剩余其它几个文件主要是辅助GPS定位的XTRA和Net Initiated的实现。

    GpsInterface接口实现如下:

     高通的GPS硬件抽象层包含GPS数据的“获取”和“解析”,它们都通过RPC上报。然后再调用loc_eng_init注册的回调,向上层上报。

    上报部分的实现是基于loc_eng_process_deferred_action函数的线程中,该线程实现一个等待循环,当GPS有数据解析上报时,RPC部分会回调loc_eng_init初始化时的loc_event_cb,该回调函数会激活线程中的等待循环。线程通过loc_eng_process_loc_event函数处理获取数据,并调用loc_eng_report_xxx(xxx代表position、卫星状态sv等),将数据通过上层注册的回调函数进行上报。这部分代码如下:

    高通GPS还实现了XTRA与AGPS,其中AGPS的接口在sLocEngAGpsInterface中实现,内容如下:

    loc_eng_agps_set_server函数完成对server的配置。硬件抽象层根据loc_eng_set_position_mode中传入的配置,决定是否启用AGPS。其中启动函数为set_agps_server,该函数最终通过RPC写入GPS。

    Android系统之Broadcom GPS 移植

    http://blog.csdn.Net/dwyane_zhang/article/details/7458270

    1.      内核部分的移植:

    内核部分的移植基本上就是对芯片上下电,建立数据结构体,打通GPS通信的串口通道,以及建立文件设备结点供上层调用。所建立的文件结点是针对Power_enable和Reset两个脚。

    在板载文件board-msm7x30.c里需要做的任务:

    static void msm7x30_init_gps(void)

    {

     …

           vreg_l2 = vreg_get(NULL, "xo_out");    

           ret = vreg_set_level(vreg_l2, 2600);

           ret = vreg_enable(vreg_l2);

                  给芯片上电的电压为2.6V。

           vreg_l13 = vreg_get(NULL, "wlan");

           ret = vreg_set_level(vreg_l13, 1800);

           ret = vreg_enable(vreg_l13);

                  给芯片另外一个脚上电为1.8V。

    }

    除了以上两个引脚的上电以为,还有另外两个比较重要的引脚gps_poweron和gps_reset初始化的上电时序。如下:

    int gps_power_init(void)

    {

           gps_reset_level(0); //reset off

           mdelay(200);

           gps_reset_level(1); //reset on

           mdelay(200);

           gps_standby_level(0); //standby off

           return 0;

    }

    前面是对芯片的上电的完成,下面需要对GPS通道的UART进行配置。由于Uart驱动是比较成熟的驱动,所以只需要把uart3的资源加进驱动里面去就OK了。如下:

    struct platform_device *devices[]__initdata = {

     …

     &msm_device_uart3;

     …

     }

    以上板载里的添加就算完成了。

    下面是对gps_poweron和gps_reset这两个引脚完成文件结点的驱动,来提供给上层操作:

    这部分的驱动在kernel/drivers/gpio/gps-gpio.c文件中。

    #include <Linux/sysdev.h>
    #include <linux/errno.h>
    #include <linux/io.h>
    #include <linux/device.h>
    #include <mach/gpio.h>
    #include <linux/platform_device.h>
    #include <linux/gpio_gps.h>
    #include <asm/uaccess.h>
    #include <mach/hardware.h>
    #include <linux/device.h>

    static ssize_t gps_standby_show(struct device *dev,
                    struct device_attribute *attr, char *buf)
    {
            int len = 0;
            struct gps_gpio_platform_data *pdata = dev->platform_data;

            len += sprintf(buf + len, "%u ", pdata->standby_state);
            printk("======== %s len = %d ",__func__,len);
            return len;
    }

    static ssize_t gps_standby_store(struct device *dev,
                    struct device_attribute *attr, const char *buf, size_t size)
    {
            unsigned long state = simple_strtoul(buf, NULL, 10);
            struct gps_gpio_platform_data *pdata = dev->platform_data;

            pdata->standby_state = (int)state;
            printk(" ****** standby_state = %d ",pdata->standby_state);

            if(state)
                    pdata->gps_standby_level(1); //standby on
            else
                    pdata->gps_standby_level(0); //standby off

            return size;
    }

    static ssize_t gps_reset_show(struct device *dev,
                    struct device_attribute *attr, char *buf)
    {
            int len = 0;
            struct gps_gpio_platform_data *pdata = dev->platform_data;


            len += sprintf(buf + len, "%u ", pdata->reset_state);
            printk("======== %s len = %d ",__func__,len);


            return len;
    }

    static ssize_t gps_reset_store(struct device *dev,
                    struct device_attribute *attr, const char *buf, size_t size)
    {
            unsigned long state = simple_strtoul(buf, NULL, 10);
            struct gps_gpio_platform_data *pdata = dev->platform_data;
            printk(" ******%s  %s  line = %d ",__func__,__FILE__,__LINE__);

            pdata->reset_state = (int)state;
            printk(" ****** reset_state = %d ",pdata->reset_state);

            if(state)
                    pdata->gps_reset_level(1); //reset on
            else

                    pdata->gps_reset_level(0); //reset off

            return size;
    }

    static DEVICE_ATTR(GPS_nRST, 0644, gps_reset_show, gps_reset_store);
    static DEVICE_ATTR(GPS_PWR_EN, 0644, gps_standby_show, gps_standby_store);

    static int gps_gpio_probe(struct platform_device *pdev)
    {
        int ret;
        struct gps_gpio_platform_data *pdata = pdev->dev.platform_data;

        pdata->standby_state = 0;
        pdata->reset_state = 1;
        pdata->gps_power_init();
        ret = device_create_file(&pdev->dev, &dev_attr_GPS_nRST);
        //    ret = device_create_file(&pdev->dev, &GPS_PWR_EN);
        printk("//////   ret  = %d ",ret);
        if(ret)
            return ret;
        else
            return device_create_file(&pdev->dev, &dev_attr_GPS_PWR_EN);

    }

    static int gps_gpio_remove(struct platform_device *pdev)
    {
        struct gps_gpio_platform_data *pdata = pdev->dev.platform_data;
        pdata->gps_reset_level(0);
        pdata->gps_standby_level(0);

        return 0;
    }

    struct platform_driver gps_gpio_driver = {
        .probe = gps_gpio_probe,
        .remove = gps_gpio_remove,
        .driver = {
            .name   = "gps_gpio",
            .owner  = THIS_MODULE,
        },
    };

    static int __init gps_gpio_init(void)
    {
        return platform_driver_register(&gps_gpio_driver);
    }


    static void __exit  gps_gpio_exit(void)
    {
        platform_driver_unregister(&gps_gpio_driver);
    }

    late_initcall(gps_gpio_init);
    module_exit(gps_gpio_exit);

    MODULE_AUTHOR("zhangmin");
    MODULE_LICENSE("GPL v2");

    这里怎么实现就不详说了,看到代码了应该很好懂。

    这样GPS在内核的工作基本上就完成了。

    2.      GPS硬件抽象层的移植

    所有的工作在hardware/broadcom/gps/目录中完成。

    首先把broadcom的代码拿过来解压,直接把解压后的文件夹放在hardware/broadcom/gps/目录下。

    ①    创建一个Android.mk 里面的内容如下:

    LOCAL_PATH := $(call my-dir)

    include $(CLEAR_VARS)

    LOCAL_SRC_FILES := libgll.a

    LOCAL_MODULE := libgll

    LOCAL_MODULE_CLASS := STATIC_LIBRARIES

    LOCAL_MODULE_TAGS := user

    LOCAL_MODULE_SUFFIX := .a

    include $(BUILD_PREBUILT)

    include $(CLEAR_VARS)

    LOCAL_SRC_FILES := libglnet.a

    LOCAL_MODULE := libglnet

    LOCAL_MODULE_CLASS := STATIC_LIBRARIES

    LOCAL_MODULE_TAGS := user

    LOCAL_MODULE_SUFFIX := .a

    include $(BUILD_PREBUILT)

    ②    然后把Android.mk放在目录/prebuilt/android-arm/gps/下。

    ③ 然后把broadcom提供的libgll.a 和 libglnet.a文件也直接拷在目录/prebuilt/android-arm/gps/下。

    ④    创建一个buildspec.mk文件,内容如下:

    TARGET_ARCH_VARIANT:=armv7-a

    SHOW_COMMANDS:=y

    CONFIG_HAL_SERIAL_TYPE=UART

    CONFIG_HAL_SERIAL_DEV=/dev/ttyS0

    CONFIG_HAL_CMD=yes

    CONFIG_HAL_CMD_FILE=/cache/glgpsctrl

    CONFIG_HAL_LTO=yes

    CONFIG_HAL_LTO_DIR=/data/gps/

    CONFIG_HAL_LTO_FILE=lto.dat

    CONFIG_HAL_NMEA_PIPE=yes

    CONFIG_HAL_NMEA_FILE=/cache/gpspipe

    CONFIG_HAL_NV=yes

    CONFIG_HAL_NV_DIR=/data/gps/

    CONFIG_HAL_NV_FILE=gldata.sto

    CONFIG_HAL_RRC=no

    CONFIG_HAL_GPIO_SYSFS=yes

    CONFIG_HAL_CATCH_SIGNALS=yes

    CONFIG_HAL_EE_DIR=./gps/

    CONFIG_HAL_EE_FILE=cbee.cbee

    CONFIG_HAL_LCS_API=yes

    #CONFIG_HAL_LOG_ANDROID=yes

    CONFIG_HAL_TIME_MONOTONIC=yes

    CONFIG_HAL_SUPL=true

    ENABLE_TLS=yes

    然后把它放在hardware/broadcom/gps/目录下。

    ⑤    将broadcom提供的glconfig.xml文件放在frameworks/base/data/etc/目录下。

    ⑥    然后在frameworks/base/data/etc/目录下的Android.mk中添加以下几行:

    include $(CLEAR_VARS)

    LOCAL_MODULE := glconfig.xml

    LOCAL_MODULE_TAGS := user eng

    LOCAL_MODULE_CLASS := ETC

    # This will install the file in /system/etc

    LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)

    LOCAL_SRC_FILES := $(LOCAL_MODULE)

    include $(BUILD_PREBUILT)

    这样硬件抽象层的内容也移植完了。

    通过这两部的移植,基本上GPS就可以正常的工作了。

    如何检查GPS已经移植可以使用了呢?首先查看编译出来后在/system/bin/下是否生成了glgps这个可执行文件。

    然后用命令来测试下:

    glgps –c /system/etc/glconfig.xml Periodic

    这样把机器放在空旷的地方测试就会在机器的/data/gps/log/目录下生成NEMA数据。

    最后再用gpstest.apk来测试确认下是否真的搜到星定到位了。

    整个GPS驱动相对来说比较简单,因为厂商基本上已经封装的很好,如果遇到问题可以直接联系FAE一起讨论。

  • 相关阅读:
    Civil 3D 二次开发 创建Civil 3D 对象—— 01 —— 创建几何空间点
    Civil 3D 二次开发 创建Civil 3D 对象—— 00 ——
    Civil 3D 二次开发 创建AutoCAD对象—— 01 —— 创建直线
    Civil 3D 二次开发 新建CLR项目出现错误C2143
    Civil 3D 二次开发 创建AutoCAD对象—— 00 ——
    了解AutoCAD对象层次结构 —— 6 ——块表记录
    datepicker97使用
    使用angular 外接 templateUrl,使用ng-include
    angularJs 遮罩
    网上找的有关css兼容问题
  • 原文地址:https://www.cnblogs.com/zzb-Dream-90Time/p/6757092.html
Copyright © 2011-2022 走看看