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