【IT168 專稿】全球導航設備目前正成為嵌入式領域的一個新熱點,因此在WinCE平臺上開發導航設備也正成為潮流熱點。GPS 系統最初只用於軍事、航空、航海等專業領域,但近年來隨著技術的發展,體積、功耗和成本都得到極大改善,使到GPS 系統在民用市場開始顯山露水,例如在汽車導航系統和手持設備中均得到了廣泛的應用。我公司近來也積極的參與到這股熱潮之中,在上周我成功的完成了公司委派給我負責的一個WinCE平臺的GPS導航項目。
這個基於WinCE平臺的GPS導航項目主要包括WinCE內核和GPS驅動的定製、電子地圖製作和嵌入式GIS應用軟體的開發等幾個方面。其中,我負責WinCE系統軟硬體平臺的搭建和底層驅動的開發。本文不涉及複雜的GIS地理信息應用程式,主要是結合本次項目的實踐,詳細介紹GPSID中間驅動層的運行機制和內部原理,以及如何使用GPSID驅動協議和底層接口來開發GPS導航設備。
1. 什麼是GPS全球定位系統?
一部完整的GPS導航設備分為軟體和硬體兩大部份。GPS硬體模塊主要包括天線、低噪音放大器(LNA)、射頻接收轉換器(RF Section)、數字基帶(Digital Baseband)、微處理器、微處理器周邊外設(Processor Peripherals)、輸入輸出和驅動(I/O and Driver)等幾個部分。軟體部分則分為作業系統軟體、GPS底層驅動軟體和應用軟體。應用軟體主要分為電子監控地圖軟體、導航軟體和功能性軟體。其中,基於WinCE系統的GPS底層驅動程序是本次項目中我負責開發的核心。
(1)GPS技術的定位原理
全球定位系統(Global Positioning System)是美國研製的,歷時20年於1994年全面建成,具有在海、陸、空進行全方位實時三維導航與定位能力的新一代衛星導航與定位系統。全球定位系統由三部分構成:①太空衛星部份:由 24 顆衛星所組成,分成六個軌道,繞行地球一周約12 小時。每個衛星均持續發射載有衛星軌道數據及時間的無線電波。②地面監控部份:這是為了追蹤及控制上述衛星的運轉所設置的地面管制站,主要工作是負責修正與維護每個衛星能保持正常運轉,以確保每個衛星都能提供正確的訊息。③GPS用戶設備:主要由接收機硬體和處理軟體組成。
用戶通過用戶設備接收GPS衛星信號,並實時地計算出接收機所在位置的坐標、移動速度及時間。其中GPS的太空衛星部份、地面監控部份均為美國控制,我們通常所說的GPS設備是指第3 部分:用戶設備部分。
一般來說,在地面上的GPS 接收器能接收5~12 個衛星信號,而為了獲得地面上的定位坐標,GPS 導航至少需要四個衛星信號。三個用來確定GPS 接收器的緯度、經度和海拔高度,第四個則提供同步校正時間。當然所能接收到的衛星數量越多,解碼出來的位置就越精確。GPS 是利用衛星和用戶GPS接收器進行球面幾何運算,一般地參與計算的衛星越多,幾何球面的計算越精確,但同時計算的時間也會越長。
通常是採用四顆衛星定位的較多,不過一般會是先用三顆衛星快速的計算進行粗定;然後再用四顆衛星來進行精確定位,這是一個較為實用的方法。這四顆衛星形成四個方程式,即四元二次方程,包括未知數為接收機所處位置的三維坐標X、Y、Z 及衛星鐘差,經度和緯度的計算都是在GPS 模塊裡面完成的。
GPS 定位計算的數學模型主要分為:最小二乘法(LS)、TDOA 雙曲線模型、Fang 算法、Chan 算法、Friedlander 算法、SX 和SI 算法。其中,Chan 算法較為準確。當然,GPS 定位只能得到位置、方向和速度等信息。然後,還要再根據經度和緯度來配合電子地圖裡面的經度和緯度來確定在地圖上的位置,最後才是完成GPS 定位在電子地圖上的顯示。
(2)硬體平臺和數據格式的實現
本項目的嵌入式GPS導航系統的硬體核心是三星公司的ARM9系列的RISC處理器S3C2410A晶片,該晶片強大的實時處理能力和豐富的外圍接口非常適合GPS嵌入式系統的開發,本項目許多的應用功能正是基於該晶片的特點而設計的。但在多次的測量和調試中,我們發現這款產品還有一定的不足,值得進一步的深入去研究。例如:在打開GPS接收模塊之後,系統的響應速度將有顯著的下降,雖然我們對WinCE內核和編譯器進行了適當的優化,但情況並沒有顯著的改善。
問題可能是在硬體平臺的處理速度和可調用的資源有限,也有可能是在軟體接收上的程序結構不合理,例如嵌套過多導致最終出現了不應有的誤差。後來,考慮到硬體成本和綜合性能上的比較,我們決定從軟體上著手。例如加強WinCE內核優化、動態GPSID驅動響應速度等來糾正響應誤差和改善反應性能,實踐證明這是很值得研究的一個方向。
(3)GPS信號的接收和讀取
雖然接收機與衛星的位置、偽時延構成的多元多次方程看起來有點複雜。但慶幸的是,程式設計師不需要做與此相關的工作,它們都被GPS接收機自己處理了。GPS接收模塊可以自己接收並處理衛星信號,並完成定位的計算,同時把定位計算結果通過接口以某種電文格式遞交給計算機。因此,嵌入式系統只需要簡單的打開與GPS模塊的連接口,就能不斷的收到GPS接收機傳送過來的數據了。
通常,GPS接收機都會被設計成為標準串口設備,不管是CF接口還是藍牙接口,都被映射成為串口設備。因此,在程式設計師的眼中傳送的GPS數據都是按一定的數據格式傳輸的,而和硬體設備的接口類型沒有關係,只需如同一般的串口設備來對待即可。GPS接收機的定位數據格式一般會在接收機的使用說明書上明確的標註,通常所見的都是採用NMEA(美國國家航海電子協會)標準。
NMEA 0183是一種航海、海運方面有關於數位訊號傳遞的標準,此標準定義了電子信號所需要的傳輸協議、傳輸數據時間。這個協議是文本格式的。因此,開發GPS導航設備的要點在於要理解相關的GPS數據格式和協議,以及主機系統和GPS接收機的信息傳輸接口。
2. 方便快捷的GPSID中間驅動層
(1)WinCE和GPS接收器的通信方式
一般來說,在提供GPS功能的嵌入式設備中都有一個GPS接收器(Receiver)。它是用來接收GPS信號的,同時GPS接收器也是把接收到的衛星信號轉換成NMEA Data的設備。因此,GPS接收器一旦啟動後,會自動連接衛星接收信號,並通過內含的算法計算出位置等信息,然後以NMEA Data的格式輸出。再餘下的工作就是WinCE系統如何獲取信息的通信過程和應用軟體如何實現具體的導航功能了。
因此,在WinCE上實現GPS信息傳輸有3種選擇:①是直接使用串口連接GPS接收器來獲取信息;②是通過GPS Intermediate Driver中間驅動層來實現信息傳輸;③是使用第三方類庫來實現通信傳輸。
(2)什麼是GPS中間驅動程序(GPSID)?
GPS傳統的編程其實很麻煩,既要同串口進行通信,又要去解析NMEA的語法,同時訪問GPS的程序會一直都在運行,這就需要保證這些訪問程序是在單獨的線程中運行。因此,傳統的通過串口傳輸GPS數據的開發方式是很痛苦的事情。但現在隨著WinCE系統新版本的升級,WinCE系統內置了GPS Intermediate Driver。
通過它我們能夠很方便的取得GPS數據,而且開發基於 GPS定位系統的 WinCE應用程式也變得簡單多了。目前,GPS中間驅動程序(GPSID)正成為導航設備開發者手中的利器。
GPS Intermediate Drive(中間驅動程序,GPSID)是一個位於應用程式和GPS設備中間層的設備驅動。GPSID是對串口操作進行了封裝,因此對於系統層來說它是一個普通的驅動,是一個插在GPS設備與應用程式之間的系統中間件。這樣的好處是使開發人員不需要通過串口直接訪問 GPS 設備,而是訪問 GPSID 提供的 API 函數,然後再由GPSID 去訪問 GPS 設備。這樣一來,編寫出來的 GPS 應用程式就具有設備無關性了,也使到只要應用GPSID就可以用相同的代碼去訪問幾乎所有類型的GPS接收器了。
GPSID的API函數主要有兩類:一類是gpsapi.dll函數:GPSOpenDevice、GPSCloseDevice、GPSGetPosition、GPSGetDeviceState。另一類是:coredll.dll函數:CreateEvent、CloseHandle、WaitForSingleObject、WaitForMultipleObjects、EventModify。
同時,GPSID 還實現了另外的兩個好處:一是多個應用程式可以同時訪問同一個 GPS 設備,因為訪問的是 GPSID,而僅僅把GPSID當作虛機硬體克隆,避免了對串口重疊操作的等候弊端。二是GPSID最大的好處是可以幫助解析NMEA語法,這樣可以用非常簡單的應用程式接口就得到GPS位置信息了。而且,GPSID 的所有設置信息都保存在註冊表中,可以通過修改註冊表來更改 GPSID 的設置。
例如,可以讓 GPSID 從一個包含 NMEA 命令的 .txt 文件讀取 GPS 數據,而不需要再從 GPS 設備中讀取數據。因此,應用GPSID函數庫後既可以訪問解析後的GPS數據,也可以訪問原始的GPS數據,還可以通過IOCTL函數來控制GPSID的執行以及進行GPS硬體的電源管理。
3.如何應用GPSID實現WinCE和GPS模塊的通信?
(1)查看GPS設備的工作狀態
在和GPS模塊通信之前,我們需要先查詢GPS模塊的工作狀態。例如,可以調用API函數 GPSGetDeviceState來獲得GPS設備的工作狀態。在這裡我建議參考微軟在WinCE SDK安裝目錄下的GPS工程樣例。在該Demo的GPS.cs中微軟封裝了GPS的操作類。比如GPSOpenDevice (),GPSCloseDevice (),GPSConnectDevice (),這些函數都可以很方便的使用。其中,GPSDeviceState.cs是用於取得目前GPS設備的狀態信息。GPSPosition.cs是每次GPS數據取得後,都會放入該類。而LocationChangedEventArgs.cs是一旦位置改變,即可取得新的GPSPosition。
(2)創建GPS事件對象,獲取GPS數據
在調用GPSDeviceState.cs取得目前GPS設備的狀態信息後,我們下一步的工作是需要啟動一個工作線程,以創建GPS事件對象。具體流程是:先通過調用CreateEvent來創建Handles,然後調用GPSOpenDevice API函數將Handle傳入得到GPS設備的Handle。得到GPS設備的Handle之後,可再創建一個線程來監聽GPS數據及設備狀態。然後,再通過調用CreateGpsEventThread方法來創建線程。
例如,當GPS設備的狀態改變時,就可以調用DeviceStateChanged事件取得當前設備的狀態。當GPS設備的位置改變時,就可以調用LocationChanged事件取得當前的坐標。然後,再使用WaitForSingleObject()函數或WaitForMultipleObjects()函數來處理事件通知。最後,通過重複調用DeviceStateChanged事件、LocationChanged事件、WaitForSingleObject()函數或WaitForMultipleObjects()函數,和調用GPSGetPosition()以獲取完整的GPS信息。這樣一個基本的獲取GPS數據的過程就完成了。
(3)應用程式的相應處理
在獲取GPS事件的線程中,不斷的通過GPSID中間驅動層就能從串口讀入數據,然後分析就能得到定位信息、衛星狀態和定位誤差,再通過回調函數指針將這些信息送回主線程就可以實現應用程式的相應處理了。最後,可調用GPSCloseDevice()函數關閉設備,以節省GPS接收模塊的電源管理。
在本次項目的調試中,因為經常會出現整個程序陷入緩慢的等待情況。所以,我們在WinCE 下的GPS編程時,除了採用單獨的線程來處理讀寫串口操作外,還採用了利用通信事件的方法。通信事件就是當發生重要事件時,WinCE可以向應用程式發送的通知,這樣就可以大大的提高GPS的響應速度,避免讓用戶陷入不知所措的長久等待之中。