無(wú)線傳感器網(wǎng)絡(luò)底層平臺(tái)的深層研究
摘要:無(wú)線傳感器網(wǎng)絡(luò)應(yīng)用一般需要無(wú)線操作系統(tǒng)的支撐,才能有效地管理和調(diào)度資源,提高系統(tǒng)的效率。無(wú)線傳感器網(wǎng)絡(luò)的底層平臺(tái)是連接上層軟件和底層硬件的橋梁,是無(wú)線操作系統(tǒng)研究的重要技術(shù)之一。合理的底層平臺(tái)能夠提高系統(tǒng)的兼容性、穩(wěn)定性、可移植性和開(kāi)發(fā)效率。本文主要研究了無(wú)線傳感器網(wǎng)絡(luò)操作系統(tǒng)的底層平臺(tái),對(duì)無(wú)線模塊、USART、SPI、中斷和定時(shí)器進(jìn)行了詳細(xì)介紹。
關(guān)鍵詞:無(wú)線傳感器網(wǎng)絡(luò);底層平臺(tái);STM32;CC2520
引言
目前,對(duì)WSN(Wireless Sensor Netwoek)的研究主要集中在協(xié)議棧、定位算法、能耗管理以及體系結(jié)構(gòu)設(shè)計(jì)上,而針對(duì)無(wú)線傳感網(wǎng)絡(luò)操作系統(tǒng)的研究卻相對(duì)較少,尤其是對(duì)其底層平臺(tái)的研究更少,所以針對(duì)無(wú)線傳感網(wǎng)絡(luò)操作系統(tǒng)底層平臺(tái)的研究有十分廣闊的空間。本論文針對(duì)意法半導(dǎo)體STM32系列MCU和TI公司的CC2520無(wú)線模塊進(jìn)行介紹。主要描述了操作系統(tǒng)底層平臺(tái)的構(gòu)建,以及硬件驅(qū)動(dòng)程序的實(shí)現(xiàn)。本論文的底層硬件抽象層是針對(duì)CC2520無(wú)線射頻模塊的,包括了平臺(tái)構(gòu)建、相關(guān)寄存器,以及外圍接口等各個(gè)部分。而硬件驅(qū)動(dòng)程序主要是為完成無(wú)線通信所需的硬件驅(qū)動(dòng)設(shè)計(jì),這主要包括:相應(yīng)異步事件的中斷機(jī)制;和PC通信的USART驅(qū)動(dòng);連接MCU和CC2520的SPI驅(qū)動(dòng);完成超時(shí)計(jì)時(shí)的定時(shí)器等。這些模塊的有效組成,才能構(gòu)成一個(gè)完整的無(wú)線傳感器網(wǎng)絡(luò)最小通信系統(tǒng),完成節(jié)點(diǎn)間數(shù)據(jù)傳輸、數(shù)據(jù)處理,以及定位和導(dǎo)航等任務(wù)。
STM32系列MCU采用ARM公司V7架構(gòu)的Correx—M3內(nèi)核。CC2520是第二代ZigBee/IEEE 802.15.4收發(fā)器。
1 底層平臺(tái)研究
硬件抽象層的底層硬件模塊有很多,本節(jié)只簡(jiǎn)單介紹和無(wú)線傳感器網(wǎng)絡(luò)相關(guān)的底層模塊設(shè)計(jì)。
1.1 定時(shí)器
STM32系列的CPU能提供8個(gè)定時(shí)器,其中TIM1和TIM8是高級(jí)定時(shí)器,可用于各種用途,包括測(cè)量輸入信號(hào)的脈沖長(zhǎng)度(輸入捕捉)或產(chǎn)生輸出波形(輸出比較)等,它們的時(shí)鐘由APB2提供。TIM2~TIM7是普通定時(shí)器,時(shí)鐘由APB1提拱。圖1為STM32時(shí)鐘樹(shù)中有關(guān)定時(shí)器的部分。
從圖1可以看出,從系統(tǒng)設(shè)置的時(shí)鐘源產(chǎn)生的時(shí)鐘頻率輸入到AHB預(yù)分頻器,進(jìn)行分頻處理,然后經(jīng)過(guò)APB1預(yù)分頻器和APB2預(yù)分頻器給不同模塊提供不同的時(shí)鐘頻率。下面以定時(shí)器2作為例子說(shuō)明。當(dāng)AHB預(yù)分頻器輸入頻率為72 MHz的時(shí)候,由于APB1支持的最大頻率為36 MHz,所以APB1預(yù)分頻器,設(shè)置必須大于或等于2,假設(shè)設(shè)置為2,則在APB1倍頻器中,頻率被設(shè)置為72 MHz(當(dāng)APB1分頻數(shù)=1的時(shí)候,APB1倍頻器加倍系數(shù)為1,當(dāng)APBl分頻數(shù)>1的時(shí)候,APB1倍頻器加倍系數(shù)為2),所以最終提供給定時(shí)器2~7的頻率為72 MHz。所以只需要設(shè)置APB1預(yù)分頻器和APB1倍頻器的值,便可以提供不同頻率的定時(shí)器。定時(shí)器采用計(jì)數(shù)溢出的方式觸發(fā)定時(shí)器中斷,因此想要使用定時(shí)器,必須先配置好定時(shí)器中斷。
1.2 中斷
對(duì)STM32系列MCU的中斷配置步驟如下:
①系統(tǒng)初始化:如系統(tǒng)時(shí)鐘初始化,使用固件模板中自帶的SystemInit()函數(shù)即可,此函數(shù)把主頻默認(rèn)調(diào)整到72 MHz。
②GPIO配置:配置觸發(fā)CPU中斷的引腳,務(wù)必注意打開(kāi)相應(yīng)引腳的GPIO時(shí)鐘和AFIO時(shí)鐘。配置引腳的頻率和輸入模式,一般為浮空輸入模式。
③EXTI配置:首先指明當(dāng)前系統(tǒng)中使用哪個(gè)引腳作為觸發(fā)外部中斷的引腳,然后清除中斷標(biāo)志位,配置中斷請(qǐng)求和觸發(fā)方式(上升沿觸發(fā)或下降沿觸發(fā))。
④NVIC配置:主要配置中斷對(duì)應(yīng)的通道,并且設(shè)置優(yōu)先級(jí)別,最后需要對(duì)通道使能。
⑤編寫(xiě)中斷服務(wù)程序:中斷服務(wù)程序是發(fā)生中斷時(shí)實(shí)際運(yùn)行的程序,它打斷了正在運(yùn)行的程序,對(duì)相應(yīng)中斷事件進(jìn)行相應(yīng)處理。由于中斷程序打斷了現(xiàn)有程序的運(yùn)行,而且需要對(duì)中斷事件作出快速響應(yīng),所以要盡量短小,而且不能傳遞參數(shù),沒(méi)有返回值。
1.3 USART
USART模塊一般分為三大部分:數(shù)據(jù)發(fā)送器、數(shù)據(jù)接收器和時(shí)鐘發(fā)生器。所有模塊共享控制寄存器。時(shí)鐘發(fā)生器由波特率發(fā)生器和同步邏輯電路組成。
數(shù)據(jù)發(fā)送器部分由寫(xiě)入緩沖寄存器(USART DR)、校驗(yàn)位發(fā)生器、串行移位寄存器和控制邏輯電路構(gòu)成。使用寫(xiě)入緩沖寄存器,可以連續(xù)快速地發(fā)送多幀數(shù)據(jù)。
數(shù)據(jù)接收器是USART模塊最復(fù)雜的部分最主要的是數(shù)據(jù)接收單元和時(shí)鐘。數(shù)據(jù)接收單元用作異步數(shù)據(jù)的接收。數(shù)據(jù)接收器還包括移位寄存器、控制邏輯、校驗(yàn)位校驗(yàn)器和接收緩沖器。數(shù)據(jù)接收器支持與數(shù)據(jù)發(fā)送器相同的幀結(jié)構(gòu),同時(shí)支持?jǐn)?shù)據(jù)溢出、幀錯(cuò)誤和校驗(yàn)錯(cuò)誤的檢測(cè)。
無(wú)線節(jié)點(diǎn)可以通過(guò)USART與PC通信。本文只實(shí)現(xiàn)了簡(jiǎn)單的USART功能。串口使用前需要完成初始化,主要設(shè)置字長(zhǎng)、波特率、奇偶校驗(yàn)位、傳輸模式、數(shù)據(jù)位數(shù)、流控制、打開(kāi)串口時(shí)鐘和配置串口發(fā)送接收引腳等。
有了串口的輸入/輸出功能后,可以自己重寫(xiě)庫(kù)函數(shù)printf,便于調(diào)試和觀察節(jié)點(diǎn)運(yùn)行情況,讓節(jié)點(diǎn)終端輸出重定向到PC,然后在PC上通過(guò)串口工具顯示節(jié)點(diǎn)發(fā)送過(guò)來(lái)的數(shù)據(jù)信息,從而分析終端運(yùn)行情況。具體函數(shù)設(shè)計(jì)是:如果節(jié)點(diǎn)輸出字符串?dāng)?shù)據(jù),則直接調(diào)用串口輸出字符串函數(shù),通過(guò)串口把字符串?dāng)?shù)據(jù)發(fā)送到PC顯示;如果是輸出數(shù)字,則先把數(shù)字按指定顯示進(jìn)制轉(zhuǎn)換成字符串,然后按照輸出字符串方式處理。可以重寫(xiě)itoa()函數(shù),把輸入的數(shù)字按照任意進(jìn)制保存到字符串中。
1.4 SPI
SPI有三種寄存器:控制寄存器(SPI_CR)、狀態(tài)寄存器(SPI_SR)、數(shù)據(jù)寄存器(SPI_DR)。SPI接口包括4種信號(hào):MOSI——從器件數(shù)據(jù)輸入,主器件數(shù)據(jù)輸出;MISO——從器件數(shù)據(jù)輸出,主器件數(shù)據(jù)輸入;SCLK——時(shí)鐘信號(hào),由主器件產(chǎn)生;NSS——從器件選擇使能信號(hào),由主器件控制,有的芯片廠家會(huì)標(biāo)注為CS(Chip Select)。
由于無(wú)線模塊CC2520必須通過(guò)SPI接口才能和MCU通信,所以必須先實(shí)現(xiàn)SPI接口,才能控制CC2520接收和發(fā)送數(shù)據(jù)。SPI接口的處理方式和USART接口的處理方式很像,本文只實(shí)現(xiàn)了簡(jiǎn)單的SPI功能。SPI使用前必須初始化,主要工作包括設(shè)置主從模式、波特率、數(shù)據(jù)位數(shù)、數(shù)據(jù)幀格式、配置輸入/輸出引腳和時(shí)鐘信號(hào)的相位和極性等。
1.5 CC2520驅(qū)動(dòng)
MCU通過(guò)SPI接口控制CC2520啟動(dòng)、關(guān)閉、收發(fā)數(shù)據(jù)等。SPI接口由SI、SO、CSn和SCLK四個(gè)引腳構(gòu)成。在MCU和CC2520通信過(guò)程中,CC2520為SPI接口從設(shè)備,接收MCU發(fā)來(lái)的時(shí)鐘信號(hào)和片選信號(hào),并在MCU的控制下執(zhí)行發(fā)送數(shù)據(jù)、接收數(shù)據(jù)等操作;STM32為接口主設(shè)備,可以通過(guò)SPI接口訪問(wèn)CC2520內(nèi)部存儲(chǔ)區(qū)和寄存器。CC2520通過(guò)FIFO、FIFOP、SFD和CCA四個(gè)引腳來(lái)表示工作狀態(tài)。MCU可以通過(guò)讀取這些引腳的數(shù)據(jù)來(lái)獲得CC2520收發(fā)數(shù)據(jù)的狀態(tài)。SFD信號(hào)表示剛接收到或者剛發(fā)送完幀開(kāi)始信號(hào);FIFO信號(hào)表示一個(gè)或者多個(gè)字節(jié)在接收緩沖區(qū);FIFOP信號(hào)表示接收緩沖區(qū)中的字節(jié)數(shù)超出設(shè)置的門(mén)限或者接收到至少一幀完整的數(shù)據(jù);CCA信號(hào)表示信道空閑。
CC2520大概工作流程:首先是準(zhǔn)備工作。上層應(yīng)用程序中使用halRfInit()函數(shù)完成CC2520的一些初始化工作,如復(fù)位CC2520,關(guān)閉電壓調(diào)整器,根據(jù)CC2520數(shù)據(jù)手冊(cè)需要延時(shí)1100μs。延時(shí)完成后,開(kāi)啟電壓調(diào)整器,再延時(shí)200μs,然后使能CC2520,完成后,申請(qǐng)SPI資源并初始化。開(kāi)啟振蕩器,然后通過(guò)SPI接口配置CC2520中一些寄存器的默認(rèn)值,如TXPOWER、CCACTRL0、MAMCTRL0、MAMCTRL1等寄存器的值。然后對(duì)MCU和CC2520相連的引腳進(jìn)行初始配置,比如把RSTN、VREN和CSN配置為輸出模式,把FIFO、FIFOP、CCA和SFD配置為輸入模式。
上層應(yīng)用程序中使用basicRfInit()函數(shù)完成對(duì)信道、短地址和網(wǎng)絡(luò)ID的設(shè)置,并配置接收中斷處理函數(shù),用于接收到數(shù)據(jù)產(chǎn)生中斷時(shí)處理接收數(shù)據(jù)。
應(yīng)用程序執(zhí)行發(fā)送命令時(shí),按照協(xié)議棧從上層一層層封裝好數(shù)據(jù)后,最終把數(shù)據(jù)交給basicRfSendPacket()函數(shù)處理。具體發(fā)送過(guò)程如圖2所示。
圖中封裝的格式按照協(xié)議要求,內(nèi)容主要包括數(shù)據(jù)長(zhǎng)度、幀控制域(FCF)、目的地址、源地址、目的網(wǎng)絡(luò)ID、源網(wǎng)絡(luò)ID、發(fā)送數(shù)據(jù)、CRC(Cyclic Redundancy Check)校驗(yàn)碼等。當(dāng)采用的是硬件CRC檢驗(yàn)時(shí),不需要用戶(hù)計(jì)算添加CRC檢驗(yàn)碼,也不需要CRC檢驗(yàn)數(shù)據(jù)寫(xiě)入TXFIFO(CC2 520發(fā)送緩沖區(qū))中,有專(zhuān)門(mén)的寄存器存儲(chǔ)CRC檢驗(yàn)數(shù)據(jù),由硬件完成檢驗(yàn)和發(fā)送。當(dāng)采用軟件CRC檢驗(yàn)時(shí),需要用戶(hù)自己計(jì)算CRC檢驗(yàn)數(shù)據(jù),并填寫(xiě)在幀的最后兩字節(jié)中,隨幀中其他數(shù)據(jù)一起寫(xiě)入TXFIFO。
封裝好后把數(shù)據(jù)寫(xiě)入TXFIFO中,注意CC2520發(fā)送緩沖區(qū)為128字節(jié),不能超出這個(gè)范圍,否則會(huì)引發(fā)TXOVERFLOW異常。然后,打開(kāi)接收數(shù)據(jù)中斷后才能調(diào)用發(fā)送命令發(fā)送數(shù)據(jù),在這里可以對(duì)發(fā)送過(guò)程進(jìn)行完全的控制,比如在發(fā)送數(shù)據(jù)的過(guò)程中,可以通過(guò)捕獲SFD引腳的上升沿信號(hào)來(lái)對(duì)發(fā)送準(zhǔn)確計(jì)時(shí)。發(fā)送數(shù)據(jù)后等待接收方回復(fù)ACK,如果在規(guī)定時(shí)間內(nèi)沒(méi)有收到ACK,則判定重傳次數(shù)是否超過(guò)最大重傳次數(shù),沒(méi)有的話則按照一定策略退避一段時(shí)間后再重新發(fā)送這個(gè)數(shù)據(jù)包,如果超過(guò)最大重傳次數(shù)則丟棄這個(gè)包,并設(shè)置發(fā)送失敗標(biāo)志供上層程序參考。如果在規(guī)定時(shí)間內(nèi)收到ACK,則會(huì)觸發(fā)RX_FRMDONE中斷,會(huì)調(diào)用basicRfRxFrmDonelsr()接收數(shù)據(jù)中斷處理程序?qū)κ盏降腁CK包進(jìn)行分析,如果是對(duì)剛發(fā)送包的正確回復(fù),則表示發(fā)送成功,更新相應(yīng)信息,例如發(fā)送序列號(hào)加1,更新發(fā)送狀態(tài),清除TX_FRM_DONE異常等。
接收過(guò)程和發(fā)送過(guò)程類(lèi)似,具體接收流程如圖3所示。
2 測(cè)試
2.1 測(cè)試方法
測(cè)試的每個(gè)節(jié)點(diǎn)都通過(guò)一根串口線連接到PC。在測(cè)試程序中添加測(cè)試代碼,把測(cè)試節(jié)點(diǎn)發(fā)送和接收的MAC(Media Access Contro1)層數(shù)據(jù)信息通過(guò)串口發(fā)送到PC上。然后通過(guò)PC上的串口調(diào)試助手顯示出來(lái)。對(duì)這些數(shù)據(jù)信息進(jìn)行分析便可以知道節(jié)點(diǎn)上各模塊程序的運(yùn)行情況。
2.2 測(cè)試過(guò)程及結(jié)果
通過(guò)分析群首節(jié)點(diǎn)廣播數(shù)據(jù)幀到群中終端節(jié)點(diǎn)的過(guò)程來(lái)判斷底層模塊的運(yùn)行情況。群首節(jié)點(diǎn)A和群中終端節(jié)點(diǎn)(B、C、D)都通過(guò)串口線連接到PC上。群網(wǎng)絡(luò)號(hào)為0x0001,節(jié)點(diǎn)A、B、C、D地址分別為:0x0001、0x0002、0x0003、0x0004。A通過(guò)無(wú)線模塊發(fā)送廣播數(shù)據(jù)到B、C、D,并把發(fā)送數(shù)據(jù)發(fā)送到PC顯示,最后把接收到的ACK回復(fù)幀也發(fā)送到PC顯示;B、C、D通過(guò)無(wú)線模塊接收到A發(fā)過(guò)來(lái)的數(shù)據(jù),按自己節(jié)點(diǎn)地址大小進(jìn)行延時(shí)后對(duì)接收數(shù)據(jù)幀進(jìn)行回復(fù),并把接收數(shù)據(jù)幀和回復(fù)ACK幀通過(guò)串口發(fā)送到PC顯示。
圖4為群首節(jié)點(diǎn)發(fā)送數(shù)據(jù)幀和接收ACK幀的過(guò)程。協(xié)議棧MAC層幀的封裝格式按照IEEE 802.15.4標(biāo)準(zhǔn)。從圖4可以看出:第一個(gè)框中為發(fā)送節(jié)點(diǎn)發(fā)送數(shù)據(jù)幀,后面三個(gè)框中為接收到的終端節(jié)點(diǎn)回復(fù)的ACK幀。按照IEEE Std 802.15.4—2006標(biāo)準(zhǔn)中的幀封裝格式,發(fā)送窗口顯示的第一個(gè)字節(jié)為物理層數(shù)據(jù)長(zhǎng)度。后面緊跟的是FCF(Frame Control Field幀控制字段,占2字節(jié)),對(duì)發(fā)送可信廣播數(shù)據(jù)幀為0x8801。參考標(biāo)準(zhǔn)手冊(cè)中FCF設(shè)置,可以看出對(duì)數(shù)據(jù)幀的設(shè)置如下:節(jié)點(diǎn)地址和網(wǎng)絡(luò)地址都采用16位;在幀中同時(shí)包括源網(wǎng)絡(luò)ID、源節(jié)點(diǎn)地址、目的網(wǎng)絡(luò)ID、目的節(jié)點(diǎn)地址;需要ACK幀確認(rèn);沒(méi)有采用安全設(shè)置。后面是DSN(1字節(jié)),這是傳輸?shù)牡谝粋€(gè)幀,所以設(shè)置為0x01。后面為目的網(wǎng)號(hào)0x0001(占2字節(jié))。后面為目的節(jié)點(diǎn)地址0xFFFF(占2字節(jié)),這是廣播地址,當(dāng)CC2520發(fā)現(xiàn)目的節(jié)點(diǎn)地址為廣播地址時(shí),便向所有節(jié)點(diǎn)傳輸廣播幀。后面為源網(wǎng)絡(luò)號(hào)0x0001(占2字節(jié))。后面為源節(jié)點(diǎn)地址0x0001(占2字節(jié))。因?yàn)檫@是同一個(gè)網(wǎng)段中的群首向終端節(jié)點(diǎn)發(fā)送廣播幀,所以目的網(wǎng)絡(luò)號(hào)和源網(wǎng)絡(luò)號(hào)相同。后面接著的2字節(jié)為MAC層數(shù)據(jù),為了測(cè)試簡(jiǎn)單,測(cè)試時(shí)只發(fā)送了2字節(jié)的數(shù)據(jù)(1和2,ASCALL碼為0x31和0x32)。可信廣播幀要求接收節(jié)點(diǎn)回復(fù)ACK幀,后面三個(gè)框中數(shù)據(jù)分別是節(jié)點(diǎn)B、C、D回復(fù)的ACK幀?;貜?fù)幀的格式和數(shù)據(jù)幀的設(shè)置情況類(lèi)似,區(qū)別是回復(fù)幀的FCF為0x8802,表示是回復(fù)幀且不需要確認(rèn),回復(fù)幀中沒(méi)有數(shù)據(jù)字段,且回復(fù)幀中的目的網(wǎng)絡(luò)號(hào)、目的地址為接收數(shù)據(jù)幀中的源網(wǎng)絡(luò)號(hào)、源地址。
圖5為接收節(jié)點(diǎn)B的接收數(shù)據(jù)幀。從圖中可以看出,第一個(gè)框中為接收到的可信廣播數(shù)據(jù)幀,第二框中數(shù)據(jù)為發(fā)送的ACK幀。接收窗口中前面的數(shù)據(jù)和發(fā)送窗口中數(shù)據(jù)一樣。不一樣的是最后的2字節(jié)(具體解釋請(qǐng)參考3.5節(jié)CC2520接收過(guò)程)。接收節(jié)點(diǎn)解析目的地址,發(fā)現(xiàn)是廣播地址,需要再檢查FCF字段中的Ack Request是否為1,如果為1,則需要回復(fù)ACK幀。為了避免群中節(jié)點(diǎn)收到可信廣播數(shù)據(jù)幀,同時(shí)回復(fù)ACK幀造成信道碰撞,回復(fù)ACK幀的時(shí)候按照自己節(jié)點(diǎn)地址大小延時(shí)發(fā)送。群中其他節(jié)點(diǎn)(C、D)的接收串口顯示數(shù)據(jù)和節(jié)點(diǎn)B的類(lèi)似,這里就不再詳細(xì)說(shuō)明。
結(jié)語(yǔ)
從測(cè)試的結(jié)果看,發(fā)送節(jié)點(diǎn)通過(guò)CC2520發(fā)送的數(shù)據(jù)能被接收,節(jié)點(diǎn)正確接收并通過(guò)串口發(fā)送到PC。這說(shuō)明論文介紹的各個(gè)模塊都能夠正確穩(wěn)定地工作。通過(guò)這些底層模塊的協(xié)同工作,為上層操作系統(tǒng)和協(xié)議棧提供了通信的基礎(chǔ)服務(wù)。本論文只是簡(jiǎn)單地完成了各模塊的功能,還有很多可以改進(jìn)的地方,比如,可以在CC2520通信過(guò)程中加入精確的時(shí)序控制,為上層提供更好的服務(wù)。
評(píng)論