1. 程式人生 > >android gps hal大概分析

android gps hal大概分析

gps android hal層分析
我用的UT4412的板子由於上面沒有gps模組,自己找到了一個北斗模組給上一個3.3的電,TX、RX接到板子的串列埠上。
我做的gps是在網上下載的程式碼,下載之後程式碼放在hardware/libhardware/modules/下面,修改上一層的Android.mk 新增gps模組   如下:
hardware_modules := gralloc hwcomposer audio nfc gps hello
include $(call all-named-subdir-makefiles,$(hardware_modules))

在gps目錄下新增gps.c Android.mk檔案 如下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
LOCAL_SHARED_LIBRARIES := liblog
LOCAL_SRC_FILES := hello.c
LOCAL_MODULE := hello.default
include $(BUILD_SHARED_LIBRARY)

模組化編譯之後會在out/target/product/smdk4x12/obj/lib下生成gps.default.so,如果目錄下還有gps.goldfish.so檔案要把它刪除,不刪除會導致調不到自己gps.default.so庫檔案,然後打包 make snod,通過fastboot下載到板子上,在網上下載一個gps測試軟體通過adb下載到板子上,開啟軟體就可以測試。

下面分析一下HAL層的gps程式碼:
hw_module_t 這個結構體是hal層的關鍵,我們看到hw_module_t結構體是怎麼定義的
const struct hw_module_t HAL_MODULE_INFO_SYM = {
    .tag = HARDWARE_MODULE_TAG,
    .version_major = 1,
    .version_minor = 0,
    .id = GPS_HARDWARE_MODULE_ID,
    .name = "Goldfish GPS Module",
    .author = "The Android Open Source Project",
    .methods = &gps_module_methods,
};
成員tar:tag必須為HARDWARE_MODULE_TAG,這是Android硬體抽象層規範規定的,
成員id:是在hardware/include/gps.h裡定義#define GPS_HARDWARE_MODULE_ID "gps"
成員methods是最主要的,hw_module_t就是引出一個方法表
static struct hw_module_methods_t gps_module_methods = {
    .open = open_gps
};
而open_gps通常裡面會開啟linux驅動的裝置(gps並不需要linux的支援,所以就沒有開啟),和返回一個interface介面供jni層呼叫
static int open_gps(const struct hw_module_t* module, char const* name,
        struct hw_device_t** device)
{
    struct gps_device_t *dev = malloc(sizeof(struct gps_device_t));
    memset(dev, 0, sizeof(*dev));

    dev->common.tag = HARDWARE_DEVICE_TAG;
    dev->common.version = 0;
    dev->common.module = (struct hw_module_t*)module;
//    dev->common.close = (int (*)(struct hw_device_t*))close_lights;
    dev->get_gps_interface = gps__get_gps_interface;

    *device = (struct hw_device_t*)dev;
    return 0;
}
static const GpsInterface  qemuGpsInterface = {
    sizeof(GpsInterface),
    qemu_gps_init,
    qemu_gps_start,
    qemu_gps_stop,
    qemu_gps_cleanup,
    qemu_gps_inject_time,
    qemu_gps_inject_location,
    qemu_gps_delete_aiding_data,
    qemu_gps_set_position_mode,
    qemu_gps_get_extension,
};

const GpsInterface* gps__get_gps_interface(struct gps_device_t* dev)
{
    return &qemuGpsInterface;
}