盛李立,王 忠,王春麗,王 浩
(1.武漢工程大學計算機科學與工程學院,湖北 武漢 430074;2.武漢大學電子信息學院,湖北 武漢 430072 )
最近幾年,在國內外醫療市場上,WIFI醫療設備的應用正以前所未有的速度增長.眾所周知,相比于傳統的有線網絡,無線局域網的應用價值體現在:可移動性、布線容易、組網靈活和成本優勢,另外,無線網絡通信范圍不受環境條件的限制.本文設計了一套基于Marvell 88W8686無線網卡芯片的無線通信系統,通過對SPI無線網卡的Linux設備驅動的深入理解和分析,成功地移植在S3C2440 ARM處理器上[2].實現了嵌入式系統的無線局域網接入.利用該平臺,可以進一步設計完善醫用心電監護儀和手持數據采集系統的無線數據傳輸,使得控制人員能夠遠離數據采集現場,而通過遠程終端來控制現場數據和各種控制信號,獲得較好的便利性,同時較好地解決了安全性問題.
無線網卡是無線局域網(WLAN)的重要組成部分,WLAN的物理層及MAC層是用無線網卡的硬件及其軟件完成的,而LLC層以上各層均由計算機軟件來實現.WLAN包括進行通信的網絡接口卡(簡稱無線網卡)和接入點/橋接器(AP/網橋).其中,無線網卡提供了最終用戶設備(手持設備)與接入點/橋接器之間的接口[6].
Marvell 88W8686無線網卡芯片集成了一片ARM兼容DECPU,包含SDIO和SPI以確保與多種主機系統互用DE高速串行主機接口,以及先進DE802.11 a/b/g RF收發器,完全與蜂窩網絡相容.該芯片兼容多種通信標準如L3,TCP/IP,UMA和IMS.
主控制器采用S3C2440[5],主頻高達400~533 MHz,基于ARM920T內核(16/32-bit RISC CPU)的高性能CPU,獨立的16 kB指令和16 kB數據cache,MMU虛擬內存管理單元,使得程序運行以及數據存儲更加高效,并可以支持Wince,Linux等多種主流操作系統,其集成了以下片上外設:LCD控制器(支持STN和TFT)、SPI控制器、SDIO控制器、USB控制器、NAND FLASH Controller等.
操作系統采用Linux 2.6.28;Bootloader采用vivi;根文件系統采用ramdisk.系統啟動后掛載yaffs2文件系統.系統的硬件平臺采用廣州友善之臂公司的mini 2440開發板,外圍接口包括1個SPI接口和一根IO外部中斷線.硬件電路:mini 2440開發板通過SPI0連接Marvell 88W8686;mini 2440開發板con4接口圖如圖1所示.
圖1 開發板mini 2440接口con4圖
SPI接口使用SPI0,中斷使用EINT1,復位使用nRESET,喚醒使用GPB0,電源使用VDD33V,地使用GND.
無線路由器采用武漢大學網絡與信息技術實驗室開發的WHU-VANET,支持802.11 a/b/g標準、TCP協議和TFTP協議.
整個系統硬件框圖如圖2所示,圖3為Marvell 88W8686硬件原理圖.
圖2 系統硬件框圖
Fig 2 System Hardware Diagram
圖3 Marvell88W8686硬件原理圖
Marvell 88W8686無線網卡芯片驅動實現的基本步驟如下:
·基于mini 2440開發板的Linux 2.6.28操作系統的移植;
·編寫基于mini 2440開發板的SPI接口驅動;
·編寫Marvell 88W8686無線網卡芯片的驅動程序;
·聯合WHU-VANET無線路由器進行調試和性能測試.
2.1.1 下載安裝交叉編譯環境 在本文中,使用的交叉編譯器是arm-linux-gcc 4.3.2,其具體下載地址請參考文獻[7],下載后,進行解壓安裝到根目錄.
2.1.2 獲取Linux內核源代碼 有很多方式可以獲取Linux內核源代碼,在本文中,是直接在Fedora9平臺上互聯網,直接在命令行通過wget命令獲取到最原汁原味的Linux-2.6.28的源代碼[8],然后進行解壓,接著針對mini 2440開發板進行對解壓后的內核進行以下修改:
① 指定交叉編譯變量
本文中,移植的目的是讓Linux-2.6.28.9可以在mini 2440上運行.
首先,要使得Linux-2.6.28.9的缺省目標平臺成為ARM的平臺.修改總目錄下的Makefile中的ARCH指定平臺為ARM_CROSS_COMPILE為解壓安裝后的arm-linux-gcc 4.3.2開發工具[2].
② 修改機器碼
首先很關鍵的一點,內核在啟動時,是通過bootloader傳入的機器碼(MACH_TYPE)確定應啟動哪種目標平臺的,友善之臂已經為mini 2440申請了自己的機器碼為1999,故需要修改ARCH/arm/tools/mach_types中的ARCH_S3C2440的機器碼362為1999,與supervivi傳入的機器碼參數一致即可!
③ 修改時鐘源頻率
修改arch/arm/mach-s3c2440/mach-smdk2 440.c文件下的時鐘源頻率,因為mini2440開發板上的晶振是12 MHz,故需要修改原SMDK2 440目標板上的晶振16.934 4 MHz為12 MHz.
④ 修改Nand Flash分區
系統默認的分區不是所需的,所以要自己修改,除此之外,還有Nand Flash的結構信息需要增加填寫,以便能夠適合系統自帶的Nand Flash驅動接口.
⑤ 修改DM9000驅動程序
參考Linux-2.6.18內核中的dm9000.c源文件來修改Linux-2.6.28中的DM9000的驅動程序,主要是在dm9000.c的dm9000_init()函數中添加dm9000寄存器初始化操作.
⑥ 獲取yaffs2源代碼
在命令行輸入 #git clone git://www.aleph1.co.uk/yaffs2,可以下載到最新的yaffs2源代碼.然后解壓為內核打上yaffs2補丁.在命令行輸入 #./patch-ker.sh c /opt/mini 2 440/linux-2.6.28.9 成功的為內核打上補丁.
⑦ 編譯測試
在Linux源代碼根目錄下執行
#make s3c2410_defconfig
對內核進行默認配置,然后在命令行輸入:
#make menuconfig
為內核添加對DM9000的支持,SPI驅動的支持,同時添加上對yaffs2文件系統和無線擴展工具的支持.
⑧ 燒寫到開發板運行測試
在命令行輸入:#make zImage
生成內核映像文件,然后通過wget下載到mini 2440開發板上運行.
從marvell官方網站下載SPI接口的驅動程序src_gspi8686.tar.gz,此驅動程序是基于PXA270的,所以需要移植到mini 2440平臺上,主要有以下工作要做:
1)對src_gspi8686里io文件中的gspi.c和gspi.h這兩個文件修改,針對各個具體函數,按照s3c2440 SPI的時序來編寫SPI驅動,在本設計中,具體需要修改的部分如下:
① 首先定義SPI字符設備的在內核中的主設備號,代碼如下:
static int major = 240;
② 內核提供了操作字符設備的函數接口,由file_operations結構封裝[4].
驅動程序就是要實現這些只有函數名,而無函數體的函數接口,以便響應用戶的系統調用,在這個結構中的每一個字段都必須指向驅動程序中實現特定操作的函數,對于不支持的操作,對應的字段可置為NULL值.針對本設計中的SPI字符設備驅動,需要實現的函數接口是:gspihost_open(),gspihost_release(),其他函數接口置空.
·gspihost_open()函數完成以下操作:調用try_module_get()函數來獲得SPI驅動模塊,同時將網卡的私有數據域置空.
·gspihost_release()函數完成以下操作:調用module_put()函數來釋放SPI驅動模塊,同時將網卡的私有數據域置空.
③ 完成讀寫數據和寄存器操作,具體需要實現的函數如下:
· gspi_write_data_direct()根據SPI的寫時序,首先使能mini 2440的SPI0時鐘,然后片選中Marvell 88W8686,根據Marvell 88W8686的數據手冊,寫操作的地址偏移量是0x8000,然后將具體的數據通過SPI的MOSI管腳把數據發送給Marvell 88W8686芯片.至此實現了gspi_write_data_direct()的函數體.
·gspi_write_reg()和gspi_write_data()函數的實現,均是調用gspi_write_data_direct()函數,只是傳遞的參數有差別.
·gspi_read_data_direct()根據SPI的讀時序,首先使能SPI0時鐘,然后片選中Marvell 88W8686,根據Marvell 88W8686的數據手冊,將請求的操作的地址偏移量通過mini 2440的SPI0的MOSI發送給Marvell 88W8686芯片,然后Marvell 88W8686芯片將具體地址的數據通過SPI0的MISO管腳把數據上傳給主機mini 2440.至此實現了gspi_read_data_direct()的函數體.
·gspi_read_reg()和gspi_read_data()函數的實現,均是調用gspi_read_data_direct()函數,只是傳遞的參數有差別.
④ GSPI模塊在使用中斷前要先請求一個中斷通道(或者中斷請求IRQ),然后在使用后釋放該中斷.在本系統中,mini 2440的SPI0使用的是輪詢發送中斷接收,中斷接收時,使用的是外部中斷線1,通過調用request_irq()函數來完成SPI0中斷的注冊.與此相反的是調用gspi_unregister_irq()函數來注銷中斷.
⑤ 實現gspihost_init_hw()函數,此函數主要完成以下操作:首先初始化mini 2440的SPI0的管腳;片選管腳初始化;設置SPI0的速率,模式,格式等;完成外部中斷線1管腳即EINT1的初始化.
⑥ 實現gspihost_module_init()函數, 此函數主要完成以下操作:調用ioremap()函數將SPI0和外部中斷線EINT1所使用的GPIO的地址空間映射到內核的虛擬地址空間,便于系統訪問;同時調用register_chrdev()來向內核注冊此SPI字符設備.
至此,基本上完成了SPI字符設備驅動程序的設計,待編譯調試無誤后既可下載安裝此SPI模塊到內核中去運行.
2)修改Makefile編譯修改過的代碼,編譯生成gspi.ko和gspi8xxx.ko.
Marvell 88W8686驅動程序調用流程如圖4所示.
圖4 Marvell驅動程序流程圖
在圖4中:系統首先調用Wlan_init_module()函數初始化gspi8xxx.ko模塊,然后調用Wlan_add_card()函數在系統內核中增加一個網卡設備,同時分配wlan_priv結構和初始化這個設備,再調用Alloc_etherdev()函數分配一個以太網設備并且注冊此以太網設備,再調用inti_waitqueue_head()函數初始化等待隊列,同時調用wlan_create_thread()函數來創建wlan_service_main_thread主線程,并且調用configureThreadPriority()函數來配置該線程的優先級.其實wlan_service_main_thread主線程相當于一個中斷服務程序,該線程處理由固件產生的接收事件或者接收的數據,并且發送從內核來的數據.接著調用sbi_register_dev()來注冊此設備,根據網卡和中斷獲得的數據來填充此設備的私有數據結構.調用sbi_get_cis_info()函數來獲得CIS表,接著調用wlan_init_fw()函數來初始化固件,并且調用register_netdev()函數來注冊此網絡設備.至此,整個模塊的初始化流程到此結束.然后內核調用schedule()函數來進行進程調度,當wlan驅動有中斷時,就會進入wlan_service_main_thread()函數進行判斷,并且調用相應的函數進行處理.
(1)將編譯生成的gspi.ko模塊,Marvell 88W8686無線網卡驅動模塊gspi8xxx.ko,helper.bin及gspi.bin下載到ARM板中;
(2)修改文件執行權限,在命令行輸入:chmod +x *;
(3) 加載spi接口驅動 gspi.ko,在命令行輸入:insmod gspi.ko;
(4)加載網卡設備驅動及上載芯片固件,在命令行輸入:insmod gspi8xxx.ko helper_name=./helper.bin fw_name=./gspi.bin.
(5)加載驅動完成后,查看網卡信息,然后掃描可用的無線網絡,再連接到特定的AP,最終配置以太網信息并ping 測試.如圖5所示:ping測試成功,說明系統運行正常,WLAN通信正常.
圖5 ping結果圖
使用UDP方式SOCKET發送數據,模擬生命監護儀發送過程,數據發送量為8 kBytes/s.工作方式采用:連接AP、發送睡眠時緩沖數據、發送喚醒時數據、斷開連接、睡眠循環的工作方式,以達到低功耗的要求.
4.2.1實測數據 進各階段的占用時間通過linux系統自帶時間函數求得,單位為1 s,精確度為0.01 s,測試結果如圖6所示.
圖6 測試結果
由圖6可知,各階段所耗時間為:
a)連接時間:1.60 s
b)休眠1 s時緩存的8 kBytes發送時間:0.01 s
c)工作時16 kBytes數據(假設為2 s內的數據量)發送時間:0.01 s
d)斷開連接時間:0.08 s
e)休眠時間:1.04 s
4.2.2 技術指標計算 根據以上測試時間及數據量等數據,可以計算以下指標:
① 工作平均功耗:3.3 V*(170 mA*(1.60 s+0.01 s+0.01 s+0.08 s)+1.8 mA*1.04 s)/(1.60 s+0.01 s+0.01 s+0.08 s+1.04 s)=3.3 V*63.35 mA=209.01 mW
② 休眠功耗:3.3 V*1.8mA=5.94 mW
③ 平均數據量:(8 kBytes+16 kBytes)/(1.60 s+0.01 s+0.01 s+0.08 s+1.04 s)=8.76 kBytes/s
④ 最大傳輸延時:1.04 s+1.60 s+0.01 s=2.65 s
⑤ 發射功率最大是:18 dbm
⑥ 最大切換時間為,斷開連接時間加上連接AP時間:0.08 s+1.60 s=1.68 s
通過以上計算,所有數據均滿足生命監護儀和實際使用場合所規定的無線網卡技術指標.
WIFI醫療是一個潛力巨大的市場,快速發展的市場,將有力地推動WIFI醫療設備的開發.本文從工程應用的角度出發,研究并移植了Linux下的Marvell 88W8686無線網卡芯片的設備驅動,以此為基礎可以構建諸如便攜式的心電監護儀的無線傳輸系統,打破傳統的床旁監測的單一模式,為各級醫療機構提高醫療服務水平提供了良好的平臺.
參考文獻:
[1] 王標,郭敏,單保慈.基于ARM的無線網卡設備驅動設計[J].現代電子技術,2009(7):101-103.
[2] 孫天澤,袁文菊.嵌入式設計及Linux驅動開發指南——基于ARM9處理器[M].北京:電子工業出版社,2005:28-35,115-125.
[3] 劉崢嶸.嵌入式Linux應用開發詳解[M].北京:機械工業出版社,2005:22-35.
[4] [美]Corbet J.Linux設備驅動程序[M].3版.北京:中國電力出版社,2006.
[5] Samsung.S3C2440A 32-BIT CMOS MICROCON-TROLLER USER’S MANUAL Revision 1[EB/OL].http://www.mcuoL.com/dounLoad/254/2179.htm,2004.
[6] Marvell 88W8686 Data Sheet.Integrated MAC/Baseband/RF Low Power SoC IEEE802.11a/g/b[EB/OL].http://www.datasheet ardhive.com /88%20Mawell-datacheet.htul,2007.
[7] Aam-linux-gcc cross-compilation sites[EB/OL].http://www.codesourcery.com/sgpp/lite/arm/portal/release,644.
[8] Linux-2.6.28 Sourece sites[EB/OL].http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.28.9.tar.gz.