基于Android 的GPS 移植
最近负责 Android 驱动的GPS部分,所谓Android驱动 我觉得可以说成是linux应用
之前发了一个图描述了 Android GPS 架构
GPS芯片大多采用串口通信,所以只要CPU能够提供一个UART 驱动, 那么跟GPS芯片通信是没有问题的,
但是现在很多GPS功能不是一个单独的芯片,大部分都是一个芯片上有好几种无线模块 比如 Blletooth WiFi FM等
有时候 有些功能就会去复用一个UART,这样在管理上就相对麻烦, 要将一个UART驱动, 模拟成一个HCI的接口而后才能使GPS功能(TI1281)
比较好的是我们的项目是单一的GPS chip 听说apple也是用的这一款,不过人家拿的是全部的source code,而我们只有部分的code而没有核心算法的code 很郁闷, 但是即便是只有部分code从里边还是可以学到很多的机制
对于android GPS驱动来说主要的工作是实现HAL层 计编译生成一个叫做gps.***.so的动态库的 代码.
由app发出定位申请,此时会去启动一个定位服务线程,此线程会调用到Location provider 服务在App Framwork中,在次会通过被native方法调用到JNI中,JNI获得GpsInterface并传给接口一个回调函数的实现。
GpsInterface就是由HAL层最主要实现
介绍下gps.h下得重要相关结构题定义
在android2.3中gps.h定义在/hardware/inclue/hardware下
主要的结构
1、相关宏定义:
- 定位模式定义/** Requested operational mode for GPS operation. */
typedef uint32_t GpsPositionMode;
// IMPORTANT: Note that the following values must match
// constants in GpsLocationProvider.java.
/** Mode for running GPS standalone (no assistance). */
#define GPS_POSITION_MODE_STANDALONE 0 //纯GPS 使用卫星定位
/** AGPS MS-Based mode. */
#define GPS_POSITION_MODE_MS_BASED 1 //基于用户终端的A-GPS
/** AGPS MS-Assisted mode. */
#define GPS_POSITION_MODE_MS_ASSISTED 2 //基于用户终端辅助A-GPS - 工作模式/** Requested recurrence mode for GPS operation. */
typedef uint32_t GpsPositionRecurrence;
// IMPORTANT: Note that the following values must match
// constants in GpsLocationProvider.java.
/** Receive GPS fixes on a recurring basis at a specified period. */
#define GPS_POSITION_RECURRENCE_PERIODIC 0//周期性的
/** Request a single shot GPS fix. */
#define GPS_POSITION_RECURRENCE_SINGLE 1//单次工作 - 辅助数据(在测试GPS性能时候又是需要删除全部或部分的辅助数据)/** Flags used to specify which aiding data to delete
when calling delete_aiding_data(). */
typedef uint16_t GpsAidingData;
// IMPORTANT: Note that the following values must match
// constants in GpsLocationProvider.java.
#define GPS_DELETE_EPHEMERIS 0x0001
#define GPS_DELETE_ALMANAC 0x0002
#define GPS_DELETE_POSITION 0x0004
#define GPS_DELETE_TIME 0x0008
#define GPS_DELETE_IONO 0x0010
#define GPS_DELETE_UTC 0x0020
#define GPS_DELETE_HEALTH 0x0040
#define GPS_DELETE_SVDIR 0x0080
#define GPS_DELETE_SVSTEER 0x0100
#define GPS_DELETE_SADATA 0x0200
#define GPS_DELETE_RTI 0x0400
#define GPS_DELETE_CELLDB_INFO 0x8000
#define GPS_DELETE_ALL 0xFFFF - gps芯片可以处理的“能力”/** Flags for the gps_set_capabilities callback. */
/** GPS HAL schedules fixes for GPS_POSITION_RECURRENCE_PERIODIC mode.
If this is not set, then the framework will use 1000ms for min_interval
and will start and call start() and stop() to schedule the GPS.
*/
#define GPS_CAPABILITY_SCHEDULING 0x0000001/** GPS supports MS-Based AGPS mode */
#define GPS_CAPABILITY_MSB 0x0000002/** GPS supports MS-Assisted AGPS mode */
#define GPS_CAPABILITY_MSA 0x0000004/** GPS supports single-shot fixes */
#define GPS_CAPABILITY_SINGLE_SHOT 0x0000008 - 还有很多的定义此处不一一列举 在gps.h中都有很好的解释。
2、数据结构体
- GpsLocation
定义了一个表示方位的结构体,成员有经纬度,高度,速度,方位角等。 - GpsStatus
表示GPS的当前状态,只有两个成员一个是表示结构大小的成员,与一个表示Gps状态的类型GpsStatusValue/** GPS status event values. */
typedef uint16_t GpsStatusValue;
// IMPORTANT: Note that the following values must match
// constants in GpsLocationProvider.java.
/** GPS status unknown. */
#define GPS_STATUS_NONE 0/** GPS has begun navigating. */
#define GPS_STATUS_SESSION_BEGIN 1/** GPS has stopped navigating. */
#define GPS_STATUS_SESSION_END 2/** GPS has powered on but is not navigating. */
#define GPS_STATUS_ENGINE_ON 3/** GPS is powered off. */
#define GPS_STATUS_ENGINE_OFF 4 - GpsSvInfo
表示当前的卫星信息,有卫星编号,信号强度,卫星仰望角方位角等 - GpsSvStatus
表示卫星状态,包含了GpsSvInfo结构,可见卫星数,星历时间,年历时间,与用来定位的卫星的卫星构成的一个掩码 - AGpsRefLocation/* 2G and 3G */
/* In 3G lac is discarded */
typedef struct {
uint16_t type;
uint16_t mcc;
uint16_t mnc;
uint16_t lac;
uint32_t cid;
} AGpsRefLocationCellID;
typedef struct {
uint8_t mac[6];
} AGpsRefLocationMac;
/** Represents ref locations */
typedef struct {
uint16_t type;
union {
AGpsRefLocationCellID cellID;
AGpsRefLocationMac mac;
} u;
} AGpsRefLocation;
/** Represents the status of AGPS. */
typedef struct {
/** set to sizeof(AGpsStatus) */
size_t size;
AGpsType type;
AGpsStatusValue status;
} AGpsStatus
3、回调函数指针定义
/* Callback with location information. 告知上层位置信息*/
typedef void (* gps_location_callback)(GpsLocation* location);
/** Callback with status information.GPS状态信息回调*/
typedef void (* gps_status_callback)(GpsStatus* status);
/** Callback with SV status information.卫星状态信息回调 */
typedef void (* gps_sv_status_callback)(GpsSvStatus* sv_info);
/** Callback for reporting NMEA sentences. 向上层传递NEMA数据*/
typedef void (* gps_nmea_callback)(GpsUtcTime timestamp, const char* nmea, int length);
/** Callback to inform framework of the GPS engine's capabilities.告知上层次GPS能实现那些功能 */
typedef void (* gps_set_capabilities)(uint32_t capabilities);
/** Callback utility for acquiring the GPS wakelock.gps上锁 让gps功能不会被suspend*/
typedef void (* gps_acquire_wakelock)();
/** Callback utility for releasing the GPS wakelock. 释放锁*/
typedef void (* gps_release_wakelock)();
/** Callback for creating a thread that can call into the Java framework code.thread create
在次线程处理函数中通常会由一个无限的循环,去等待上层的请求,并应答*/
typedef pthread_t (* gps_create_thread)(const char* name, void (*start)(void *), void* arg);
4、接口结构体
- GpsCallbackstypedef struct {
/** set to sizeof(GpsCallbacks) */
size_t size;
gps_location_callback location_cb;
gps_status_callback status_cb;
gps_sv_status_callback sv_status_cb;
gps_nmea_callback nmea_cb;
gps_set_capabilities set_capabilities_cb;
gps_acquire_wakelock acquire_wakelock_cb;
gps_release_wakelock release_wakelock_cb;
gps_create_thread create_thread_cb;
} GpsCallbacks;
就是以上函数指针组成的结构体,是一组回调函数,函数的实现在JNI层是Android实现好了得,无需做(太大的)修改 - GpsInterface
Android GPS 最主要的数据结构,我们最主要的移植工作就是实现其中的函数/** Represents the standard GPS interface. */
typedef struct {
/** set to sizeof(GpsInterface) */
size_t size;
/*Opens the interface and provides the callback routines 初始化callbacks 为JNI传下来的
在此会使用callbacks中的create_thread_cb 来创建一个线程处理函数一直循环,等待任务处理*/
int (*init)( GpsCallbacks* callbacks );
/** Starts navigating. */
int (*start)( void );
/** Stops navigating. */
int (*stop)( void );
/** Closes the interface. */
void (*cleanup)( void );
/** Injects the current time. 填入时间*/
int (*inject_time)(GpsUtcTime time, int64_t timeReference,
int uncertainty);
/** Injects current location from another location provider 填入位置*/
int (*inject_location)(double latitude, double longitude, float accuracy);
/*删除全部or部分辅助数据 在性能测试时候使用*/
void (*delete_aiding_data)(GpsAidingData flags);
/*设置定位模式 与GPS工作模式等等*/
int (*set_position_mode)(GpsPositionMode mode, GpsPositionRecurrence recurrence,
uint32_t min_interval, uint32_t preferred_accuracy, uint32_t preferred_time);
/*自行添加的 接口 AGpsInterface接口通过次函数获得*/
const void* (*get_extension)(const char* name);
} GpsInterface; - AGpsCallbacks/** Callback with AGPS status information.
* Can only be called from a thread created by create_thread_cb.
*/
typedef void (* agps_status_callback)(AGpsStatus* status);
/** Callback structure for the AGPS interface. */
typedef struct {
agps_status_callback status_cb;
gps_create_thread create_thread_cb;
} AGpsCallbacks; - AGpsInterface/** Extended interface for AGPS support. */
typedef struct {
/** set to sizeof(AGpsInterface) */
size_t size;
/**
* Opens the AGPS interface and provides the callback routines
* to the implemenation of this interface.
*/
void (*init)( AGpsCallbacks* callbacks );
/**
* Notifies that a data connection is available and sets
* the name of the APN to be used for SUPL.
*/
int (*data_conn_open)( const char* apn );
/**
* Notifies that the AGPS data connection has been closed.
*/
int (*data_conn_closed)();
/**
* Notifies that a data connection is not available for AGPS.
*/
int (*data_conn_failed)();
/**
* Sets the hostname and port for the AGPS server.
*/
int (*set_server)( AGpsType type, const char* hostname, int port );
} AGpsInterface - struct gps_device_t
定义描述gps设备类型struct gps_device_t {上层会通过动态库,获得此结构,等到GpsInterface从而打通APP到GPS device的全部通信。
struct hw_device_t common;
/**
* Set the provided lights to the provided values.
*
* Returns: 0 on succes, error code on failure.
*/
const GpsInterface* (*get_gps_interface)(struct gps_device_t* dev);
}; - 还有 GpsNiInterface AGpsRilInterface等接口 在此不赘述