近期在Android2.3上調GPS,使用的是locosys LS2005B模組(gps芯片是atheros ar1520),供應商給的參考資料是2.2/2.1的,自己找到的大部分資料也是該版本的,調試過程參考了系統源碼下的sdk/emulator/gps/gps_qemu.c,相對比2.2,需要添加如下內容:
const GpsInterface* gps__get_gps_interface(struct gps_device_t* dev)
{
return &athrGpsInterface;
}
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->get_gps_interface = gps__get_gps_interface;
*device = (struct hw_device_t*)dev;
return 0;
}
static struct hw_module_methods_t gps_module_methods = {
.open = open_gps,
};
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 = "Atheros AR1520 GPS Module",
.author = "Qualcomm Atheros USA, Inc.",
.methods = &gps_module_methods,
};
上面內容是我參考修改的,改完后,重大問題又來了,系統能自動調用到該庫了(關于2.2與2.3中gps的改動,附言會提及),但每次啟動到Android時就掛了,Android遮罩動畫不停的走,偶爾能進入Android,也是沒一會就重回老路,一直跑動畫去了,無奈之下只得查代碼了,最終發現在com_android_server_location_GpsLocationProvider.cpp里面的static void nmea_callback(GpsUtcTime timestamp, const char* nmea, int length)函數中JNIEnv* env = AndroidRuntime::getJNIEnv();這語句執行后env的值都為NULL,而下面的語句沒有判斷就調用了env->CallVoidMethod()函數,此時不掛才怪,后來在網上找了一下資料,發現原來問題出在了HAL層,于是針對HAL層的代碼進行了如下修改:
在gps_state_init()函數中最后會開線程,使用了如下語句:
if ( pthread_create( &state->thread, NULL, gps_state_thread, state ) != 0 ) {
LOGE("could not create gps thread: %s", strerror(errno));
goto Fail;
}
而這樣會造成上面的env獲不到數據,故修改成如下語句:
//state->thread =,有看到會把下面語句返回值賦給該量,調試時沒有嘗試,故先放著。
state->callbacks.create_thread_cb("athr_gps",gps_state_thread, state);
由于此句會使用到callbacks一量,而查找到gps_state_init()是由athr_gps_init()函數調用的,在該函數中,s->callbacks = *callbacks;語句是在gps_state_init(s);之后,故將其修改到之前,至此,終于調通了,數據也能正常上報了。