最近負責 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、接口結構體
- GpsCallbacks
typedef 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 {
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);
};上層會通過動態庫,獲得此結構,等到GpsInterface從而打通APP到GPS device的全部通信。
- 還有 GpsNiInterface AGpsRilInterface等接口 在此不贅述