無線傳感器網(wǎng)絡(luò)操作系統(tǒng).ppt_第1頁
無線傳感器網(wǎng)絡(luò)操作系統(tǒng).ppt_第2頁
無線傳感器網(wǎng)絡(luò)操作系統(tǒng).ppt_第3頁
無線傳感器網(wǎng)絡(luò)操作系統(tǒng).ppt_第4頁
無線傳感器網(wǎng)絡(luò)操作系統(tǒng).ppt_第5頁
已閱讀5頁,還剩82頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、無線傳感器網(wǎng)絡(luò)技術(shù)講義,第十二章、操作系統(tǒng),2007年8月20日,內(nèi)容提要,WSN 操作系統(tǒng)概述 TINYOS 操作系統(tǒng) MANTIS 操作系統(tǒng) SOS 操作系統(tǒng) 三種操作系統(tǒng)的設(shè)計實現(xiàn)比較 WSN OS最新研究進(jìn)展 主要參考文獻(xiàn),WSN 操作系統(tǒng)概述 TINYOS 操作系統(tǒng) MANTIS 操作系統(tǒng) SOS 操作系統(tǒng) 三種操作系統(tǒng)的設(shè)計實現(xiàn)比較 WSN OS最新研究進(jìn)展 主要參考文獻(xiàn),內(nèi)容提要,WSN操作系統(tǒng)的設(shè)計目標(biāo),WSN是應(yīng)用相關(guān)的網(wǎng)絡(luò),其硬件節(jié)點功能、結(jié)構(gòu)、組織方式會隨應(yīng)用而不同。由此要求WSN操作系統(tǒng)能夠良好的模塊化設(shè)計,使應(yīng)用/協(xié)議/服務(wù)與硬件資源之間可以隨意搭配 WSN節(jié)點資源非

2、常有限(通信帶寬資源/能量資源/計算資源),操作系統(tǒng)必須能夠高效地使用各種資源 WSN是一個網(wǎng)絡(luò)系統(tǒng),其操作系統(tǒng)也必然是面向網(wǎng)絡(luò)化開發(fā)的。網(wǎng)絡(luò)化系統(tǒng)要求操作系統(tǒng)必須為應(yīng)用提供高效的組網(wǎng)和通信機(jī)制,本章講解的操作系統(tǒng),本章講解三個有代表性的開源的無線傳感器網(wǎng)絡(luò)操作系統(tǒng): Tiny OS 2.0:美國加州大學(xué)伯克利分校開發(fā) Mantis OS 0.9.5 (Multimodal Networks of In-situ Sensors) :美國克羅拉多大學(xué)開發(fā) SOS 1.7:美國加州大學(xué)洛杉磯分校開發(fā),內(nèi)容提要,WSN操作系統(tǒng)概述 TINYOS 操作系統(tǒng) MANTIS 操作系統(tǒng) SOS 操作系統(tǒng)

3、三種操作系統(tǒng)的設(shè)計實現(xiàn)比較 WSN OS最新研究進(jìn)展 主要參考文獻(xiàn),TinyOS 2.0 操作系統(tǒng),事件驅(qū)動,基于組件 使用nesC編寫 支持的平臺:eyesIFXv2、intelmote2、mica2、 mica2dot、micaZ、telosb、tinynode、btnode3 nesC:使用C作為其基礎(chǔ)語言,支持所有的C語言詞法和語法 增加了組件(component)和接口(interface)的關(guān)鍵字定義 定義了接口及如何使用接口表達(dá)組件之間關(guān)系的方法 目前只支持組件的靜態(tài)連接,不能實現(xiàn)動態(tài)連接和配置,組件模型,組件,接口,命令和事件,組件(component) Module組件(模件

4、) Configuration組件(配件) 組件特征 組件內(nèi)變量、函數(shù)可以自由訪問,但組件之間不能訪問和調(diào)用 組件可以提供(provide)和使用(use)接口 接口是一組相關(guān)函數(shù)的集合,它是雙向的并且是組件間的唯一訪問點。接口聲明了一組函數(shù),稱為命令(command),接口的提供者必須實現(xiàn)它們;接口還聲明了另外一組函數(shù),稱為事件(event),接口的使用者必須實現(xiàn)它們,組件,接口,命令和事件,接口的特點 Provides未必一定有組件使用,但uses一定要有人提供,否則編譯會提示出錯。在動態(tài)組件配置語言中uses也可以動態(tài)配置 接口可以連接多個同樣的接口,叫做多扇入/扇出 一個module可

5、以同時提供一組相同的接口,又稱參數(shù)化接口,表明該Module可提供多份同類資源,能夠同時給多個組件分享,組件命名規(guī)則,C和P的命名規(guī)則 :TinyOS 所有的終端程序組件都以字母C或P為結(jié)尾。以C結(jié)尾所命名的組件表示它是一個可用的抽象,而以P結(jié)尾的組件則表示它是私有的。以P結(jié)尾的組件不能被直接的連接,但可以對它做一些封裝以使它變成可用(變成名字以C結(jié)束的) 硬件平臺抽象命名規(guī)則 :TinyOS 2.0中的硬件抽象通常是三級抽象架構(gòu),稱作HAA(Hardware Abstraction Architecture)。 HAA的最底層是HPL( Hardware Platform Layer) HA

6、A的中間層是HAL (Hardware Abstraction Layer) HAA的最高層是HIL (Hardware Independent Layer),TinyOS2.0 的任務(wù),基本任務(wù)模型 :基本任務(wù)模型中任務(wù)的原型聲明如下: task void taskname(). 用戶使用post關(guān)鍵字拋出任務(wù),調(diào)用方式如下: result_t ret = post tastname() 任務(wù)接口模型 :任務(wù)接口擴(kuò)展了任務(wù)的語法和語義。通常情況下,任務(wù)接口包含一個異步(async)的post命令和一個run事件,這些函數(shù)的具體聲明由接口決定。 實例: Interface TaskParame

7、ter async error_t command postTask(uint16_t param); event void runTask(uint16_t param); 調(diào)用方式: call TaskParameter.postTask(34);/拋出任務(wù),TinyOS2.0調(diào)度器,TinyOS的調(diào)度器實現(xiàn)了任務(wù)和事件的兩級調(diào)度 任務(wù)之間不能互相搶占 ,底層硬件中斷觸發(fā)事件,事件能搶占任務(wù),事件之間也能互相搶占。命令和事件都可以post任務(wù)。任務(wù)中也可以調(diào)用命令 。 TinyOS 2.x調(diào)度器被實現(xiàn)為一個TinyOS組件。調(diào)度器既支持最基本的任務(wù)模型,也支持任務(wù)接口模型,并且由調(diào)度器負(fù)責(zé)

8、協(xié)調(diào)不同的任務(wù)類型。,TinyOS2.0調(diào)度器調(diào)度器組件,TinyOS調(diào)度器的形式說明 如下: module SchedulerBasicP provides interface Scheduler; provides interface TaskBasicuint8_t taskID; uses interface McuSleep; 配件TinySchedulerC封裝 了組件SchedulerBasicP 調(diào)度器必須提供參數(shù)化 的TaskBasic接口 調(diào)度器還必須提供Scheduler接口 TinyOS2.0允許用戶使用自己定義的應(yīng) 用程序(組件)取代系統(tǒng)調(diào)度器,內(nèi)存分配,TinyOS

9、使用了靜態(tài)的內(nèi)存分配和管理機(jī)制 。 TinyOS中的組件在編譯時分配所需要的內(nèi)存 組件之間能共享狀態(tài)(state)的唯一方法是通過函數(shù)調(diào)用 。 組件傳遞參數(shù)使用了兩種方法:值傳送和指針傳送 。 指針傳遞參數(shù)比較危險 推薦做法:在任何時候,每一個指針都有一個明確的所有者,并且只有所有者才能修改相應(yīng)的存儲區(qū)。,TinyOS 通信,消息緩沖區(qū):TinyOS 2.0中的消息緩沖區(qū)類型是message_t,并且仍采用了靜態(tài)包緩沖策略 。緩沖區(qū)大小可以適合任何節(jié)點的通信接口 ,組件不能直接訪問結(jié)構(gòu)的各域,所有緩沖區(qū)的訪問必須通過接口AMPacket和Packet(定義在opttinyos-2.xtosin

10、tefaces目錄)實現(xiàn)。 通信組件 :用戶可以使用如下四個主動消息通信組件實現(xiàn)無線消息的收發(fā) (定義在tostinyos-2.xtossystem ) : AMSenderC,AMReceiverC,AMSnooperC,AMSnoopingReceiverC,并發(fā)模型,TinyOS 一次僅執(zhí)行一個程序。程序運(yùn)行時,有兩個執(zhí)行線程:任務(wù)和事件。事件是由硬件中斷觸發(fā)的,事件之間可以互相搶占 任務(wù)之間不互相搶占,事件可搶占任務(wù),事件也可互相搶占??蓳屨歼\(yùn)行的函數(shù)用async 標(biāo)識,同步運(yùn)行的函數(shù)用sync nesC的規(guī)則是:異步函數(shù)調(diào)用的命令和事件也必須是異步的。一個函數(shù)(命令或事件)不是異步就

11、是同步(缺?。=涌诘亩x指明了命令和事件是異步還是同步 中斷(異步函數(shù))可以執(zhí)行同步函數(shù)的唯一方法就是post一個任務(wù) 使用原子語句塊來實現(xiàn)對臨界數(shù)據(jù)的訪問,系統(tǒng)啟動和初始化,TinyOS 2.x的啟動序列使用了3個接口: Init:初始化組件和硬件 ,它執(zhí)行的是順序的,同步的操作 ,在初始化完成前不會啟動任何組件 Scheduler:初始化和運(yùn)行任務(wù) ,用于初始化和控制任務(wù)的執(zhí)行 Boot:通知系統(tǒng)已經(jīng)成功的啟動。它定義了一個事件booted(),用它通知系統(tǒng)已經(jīng)被成功的啟動 TinyOS 2.x中的RealMainP(定義opttinyos-2.xtossystem中) 實現(xiàn)了標(biāo)準(zhǔn)的啟動

12、 序列,MainC封裝 了組件RealMainP,系統(tǒng)啟動和初始化,模塊RealMainP 的定義 module RealMainP provides interface Boot; uses interface Scheduler; uses interface Init as PlatformInit; uses interface Init as SoftwareInit; implementation 系統(tǒng)的啟動過程分為3個獨立的初始化過程:調(diào)度器初始化(Scheduler),平臺初始化( PlatformInit), 和軟件初始化( SoftwareInit)。 MainC導(dǎo)出Boo

13、t和SoftwareInit接口,用于應(yīng)用程序連接 不直接依賴于硬件資源的組件初始化都應(yīng)該連接到MainC.SoftwareInit,能量管理,TinyOS 2.x中的能量管理分為處理器能量管理和設(shè)備能量管理: 微處理器能量管理 ,TinyOS 2.x使用了一個dirty位,一個芯片相關(guān)的能量狀態(tài)計算函數(shù)和一個能量狀態(tài)重載函數(shù)來管理和控制微處理器的能量狀態(tài) 外設(shè)能量管理 ,TinyOS 2.0定義了2種不同的能量管理模型:顯式能量管理模型和隱式能量管理模型 如下接口用于實現(xiàn)設(shè)備能量管理: StdControl:若一個設(shè)備的開啟或關(guān)閉所花費的時間可以忽略,那么它應(yīng)該提供這個接口; SplitCo

14、ntrol:若一個設(shè)備的開啟或關(guān)閉所花費的時間不可以被忽略,那么它應(yīng)該提供這個接口; AsyncStdControl:由于上述2個接口都是同步接口,所以若想在異步代碼中控制一個設(shè)備的能量狀態(tài),那么就必須使用該接口,模擬服務(wù),TOSSIM是TinyOS的模擬器,它是一個程序庫 TOSSIM是一個離散的時間模擬器,當(dāng)它運(yùn)行的時候,會從時間隊列中依次取出事件(以時間排序)并且執(zhí)行它們 模擬事件可以是硬件中斷也可以是高層的系統(tǒng)事件(例如包接收事件) ,任務(wù)也可以成為模擬事件 支持兩種編程接口:Python 和C+,這兩種編程接口各有優(yōu)缺點,而且這兩種代碼之間的轉(zhuǎn)換比較簡單。 TOSSIM支持的唯一平臺

15、是micaz,而且還不支持能量檢測。,基于TinyOS2.0系統(tǒng)的編程,回顧組件和接口的概念 組件 ,nesC組件使用的是一個純局部的命名空間,這就是說一個組件除了要聲明它將執(zhí)行的函數(shù)外,還要聲明它所調(diào)用的函數(shù) 。每一個組件都有一個形式說明(specification),這個形式說明是一段代碼,它聲明了組件所提供(執(zhí)行)接口(函數(shù))和所使用(調(diào)用)的接口(函數(shù)) 接口 ,接口(interface)是相關(guān)函數(shù)的一個集合,用于可以根據(jù)功能的需要定義自己的接口,但在定義接口中的函數(shù)時,必須使用command或event關(guān)鍵字聲明該函數(shù)是命令或是事件,否則編譯時會報錯,模塊,nesC有兩種組件: 配件

16、(configurations),用于將組件連接在一起從而形成一個新的組件 模塊(modules),提供了接口代碼的實現(xiàn)并且分配組件內(nèi)部狀態(tài),是組件內(nèi)部行為的具體實現(xiàn) 模塊相關(guān)概念: 分段操作 ,分段接口的一個重要的特征就是兩個階段的調(diào)用是相反的:向下調(diào)用是開始操作,向上的signal操作是完成操作。在nesC中,向下調(diào)用的是命令,而向上調(diào)用的是事件,接口指定了這種關(guān)系的兩個方面,分段操作,分段接口實例: interface Read command error_t read(); event void readDone( error_t result, val_t val ); Read接口

17、的提供者需要定義Read函數(shù)和通知Readdone事件,而Rend接口的使用者則需要定義Readdone事件,而且能夠調(diào)用Read命令。,類型化接口,接口可以帶有類型參數(shù) ,接口的類型參數(shù)放在一對尖括號里 ,如果提供者和使用者的接口都帶有類型參數(shù),那么在連接時,它們的類型必須匹配 , 例: LocalTime接口帶有一個precision_tag參數(shù),定義在opttinysos-2.xtoslibtimer目錄中。如下: interface LocalTime async command uint32_t get(); 參數(shù)precision_tag雖然沒有在接口的命令中出現(xiàn),但它在連接時會被

18、用于類型檢查:該參數(shù)指明了最小的時間間隔,模塊實現(xiàn) 形式說明,module SenseC uses interface Boot; interface Leds; interface Timer; interface Read;/使用接口的聲明 ,模塊實現(xiàn),Implementation / 以下是實現(xiàn)部分 #define SAMPLING_FREQUENCY 100 event void Boot.booted() call Timer.startPeriodic(SAMPLING_FREQUENCY);/調(diào)用了Timer接口的命令 event void Timer.fired() /因為使用

19、了Timer接口,所以必須實現(xiàn)Timer接口中定義的事件 call Read.read();/調(diào)用了Read接口的命令 event void Read.readDone(error_t result, uint16_t data) /因為使用了Read接口,所以必須 /實現(xiàn) Read接口中定義的事件 if (result = SUCCESS) if (data ,任務(wù),原子語句,enum,任務(wù) 原子語句:在nesC中通過使用原子語句(atomic statements)的方式實現(xiàn)了對臨界數(shù)據(jù)保護(hù) ,例 command bool increment() atomic a+; b = a + 1;

20、 原子代碼塊保證了這些變量可以被原子的寫和讀。注意,這里并沒有保證這個原子的代碼塊不能被搶占。即使使用了原子代碼塊,兩個不涉及任何相同變量的代碼段還是可能互相搶占的。 靈活使用enum可節(jié)省存儲空間,配件和連接,組件之間是完全獨立的,只有通過連接才能綁定到一起 ,配件用于實現(xiàn)此功能。配件的定義與模塊類似 使用了三個操作-, Sleep; Sleep-Sched.McuSleep; 一個直接的連接總是從使用者指向提供者,箭頭的方向決定了調(diào)用關(guān)系 和模塊一樣,配件可以提供和使用接口。但是由于配件沒有代碼實現(xiàn),所以這些接口的實現(xiàn)必須依賴其他的組件。,導(dǎo)通連接(Pass Through Wiring)

21、,導(dǎo)通連接是指一個配件將兩個組件連接到一起,并且必須使用“=”操作符把使用者連接到提供者操作符。例: generic configuration AMReceiverC(am_id_t amId) provides interface Receive; interface Packet; interface AMPacket; implementation components ActiveMessageC; Receive = ActiveMessageC.ReceiveamId; Packet = ActiveMessageC; AMPacket = ActiveMessageC; ,扇入

22、,扇出,combine函數(shù),接口之間可以是n對k的關(guān)系,這里n是使用者數(shù),k是提供者數(shù) 扇出(fan-out)同一個調(diào)用者一次調(diào)用了多個函數(shù) 扇入(fan-ins)用來描述多個人調(diào)用同一個函數(shù)。 接口之間是一個n對k的關(guān)系,任何提供者的signal將會引起n個使用者的事件處理函數(shù),并且任何使用者調(diào)用一個命令將會調(diào)用k個提供者的命令 combine函數(shù) ,它將多個返回值組合后只返回一個值。一個數(shù)據(jù)類型可以有一個相關(guān)的combine函數(shù)。因為一個fan-out總是涉及到調(diào)用N個相同的函數(shù),調(diào)用者最終得到的返回值是對所有的被調(diào)用者的返回值使用combine函數(shù)之后得到的返回值。,參數(shù)化連接,參數(shù)化接

23、口用于提供同一接口的多個實例。如: configuration ActiveMessageC provides interface SplitControl; interface AMSenduint8_t id; interface Receiveuint8_t id; 參數(shù)化接口本質(zhì)上是一個接口數(shù)組,數(shù)組的索引就是接口的參數(shù)。 nesC還提供了一個unique函數(shù)用于保證參數(shù)不重復(fù),缺省連接,unique()和uniqueCount()函數(shù),nesC提供了缺省連接處理 。如果一個組件連接到了某個接口,那么就按照該連接調(diào)用接口中的函數(shù)。若沒有,則命令(或事件)會執(zhí)行缺省的處理函數(shù) (使用de

24、fault關(guān)鍵字標(biāo)識),盡量不要使用缺省連接處理 unique():保證每一個相同的接口必須有不同的參數(shù)ID ,它將把所有的對unique()調(diào)用變換成整數(shù)標(biāo)志符。unique函數(shù)需要一個字符串關(guān)鍵字作為參數(shù)。例AMQueueEntryP.Send - AMQueueP.Sendunique(UQ_AMQUEUE_SEND) uniqueCount():該函數(shù)是用來計算調(diào)用unique的客戶總數(shù)目,這樣就可以使組件能夠分配正確的狀態(tài)總數(shù),通用組件(Generic Components),通用組件不是單一實例的,它在配件內(nèi)能被實例化 通用組件與非通用組件原型定義的最大差別有兩點: 在關(guān)鍵字com

25、ponent(表示module或configuration)之前有一個generic關(guān)鍵字,它表示該組件是通用組件 通用組件在組件名字后必須帶有參數(shù)列表,從這方面來看類似于函數(shù)的定義。若該通用組件不需要參數(shù),那么該參數(shù)列表為空 目前通用組件支持如下三種類型的參數(shù): 類型(types)參數(shù):這些參數(shù)可以作為類型化接口的參數(shù),聲明時使用typedef 數(shù)值常數(shù)(numeric constants)參數(shù) 字符串常數(shù)(constant strings)參數(shù),通用組件(Generic Components),使用通用組件時需要在配件中使用關(guān)鍵字new實例化一個通用組件,這個實例是配件所私有的。用戶每使用

26、一次new便被會創(chuàng)建一個實例。在使用關(guān)鍵字new實例化通用組件的時候,系統(tǒng)使用了代碼拷貝的方式生成新的實例。例如: configuration ExampleVectorC implementation components new BitVectorC(10); 上面的語句使用new關(guān)鍵字創(chuàng)建了一個大小為10的BitVectorC組件,通用模塊和通用配件,通用模塊帶有三種參數(shù),如果參數(shù)是一個類型,那么必須用typedef關(guān)鍵字聲明。例如通用模塊VirtualizeTimerC(opttinyos-2.x toslib timer),如下: generic module VirtualizeT

27、imerC(typedef precision_tag, int max_timers) provides interface Timer as Timeruint8_t num; uses interface Timer as TimerFrom; implementation 在上面這個例子中生成了一個VirtualizeTimerC代碼的拷貝,并且分配了uniqueCount(UQ_TIMER_ MILLI)個毫秒精度的定時器。 通用配件構(gòu)成了更高層次的虛擬化和抽象。使用通用配件與使用通用模塊的方法是一樣的,內(nèi)容提要,WSN操作系統(tǒng)概述 TINYOS 操作系統(tǒng) MANTIS 操作系統(tǒng) S

28、OS 操作系統(tǒng) 三種操作系統(tǒng)的設(shè)計實現(xiàn)比較 WSN OS最新研究進(jìn)展 主要參考文獻(xiàn),Mantis操作系統(tǒng),輕量級的基于搶占的多線程無線傳感器網(wǎng)絡(luò)操作系統(tǒng) 類Unix編程環(huán)境,編程語言為c語言 整個內(nèi)核占用的RAM小于500個字節(jié) 適合于無線傳感器網(wǎng)絡(luò)中處理復(fù)雜任務(wù)(例如加密解密,數(shù)據(jù)融合,定位,時間同步等)的需求 目前支持MICA系列的節(jié)點和MANTIS課題組研發(fā)的namph節(jié)點。,Mantis OS系統(tǒng)介紹,應(yīng)用程序線程和底層操作系統(tǒng)API相互獨立,所以MOS通過提供不同平臺的API就可以實現(xiàn)對多個平臺的支持 MOS系統(tǒng)由內(nèi)核 (kernal/scheduler), 網(wǎng)絡(luò)棧,通信層 (COM

29、M)以及其 他組件構(gòu)成(如 dev驅(qū)動層),Mantis OS內(nèi)核和調(diào)度器,提供了類似于UNIX風(fēng)格的調(diào)度器 和POSIX 服務(wù) 基于優(yōu)先級的多線程調(diào)度和在同一優(yōu)先級中進(jìn)行輪轉(zhuǎn)調(diào)度的服務(wù) 時間片可配置 ,缺省為10ms 支持互斥信號量和計數(shù)信號量 邏輯上把RAM可以分成兩部分:一部分在編譯時分配給全局變量,其他部分以堆的形式管理。 內(nèi)核的主要全局?jǐn)?shù)據(jù)結(jié)構(gòu)是線程表,每一個線程占一個條目 系統(tǒng)在以下情況下會引發(fā)上下文切換:調(diào)度器接收到一個來自硬件定時器的中斷,系統(tǒng)調(diào)用和信號量操作。定時器中斷是唯一一個被內(nèi)核處理的硬件中斷 沒有軟件中斷,內(nèi)核和調(diào)度器線程表的定義,內(nèi)核的主要全局?jǐn)?shù)據(jù)結(jié)構(gòu)是線程表,每一

30、個線程占一個條目 typedef struct thread_s stackval_t *sp; 線程當(dāng)前的堆棧指針 stackval_t *stack; 堆棧基指針 uint16_t stackSize; 堆棧的大小 void (*func)(void); 指向線程開始函數(shù)的指針 uint8_t state; 目前線程的狀態(tài) uint8_t suspend_state; 當(dāng)前線程的掛起狀態(tài) uint8_t priority; 線程的優(yōu)先級 uint32_t st; 線程的睡眠時間 uint8_t port; 端口號(只用于網(wǎng)絡(luò)接收) struct thread_s *next; 指向線程列表

31、中的下一個線程 thread_t;,線程,線程的狀態(tài)有五種:空閑狀態(tài),運(yùn)行狀態(tài),就緒狀態(tài),阻塞狀態(tài),休眠狀態(tài) 阻塞狀態(tài)又分為二種:阻塞空閑狀態(tài)和阻塞休眠狀態(tài) 線程設(shè)置了5個優(yōu)先級:內(nèi)核優(yōu)先級,休眠優(yōu)先級,高優(yōu)先級(能搶占所有其他的優(yōu)先級的線程),正常優(yōu)先級,空閑優(yōu)先級。系統(tǒng)缺省定義的最大線程個數(shù)為6 內(nèi)核為每一個優(yōu)先級維護(hù)一個含有頭指針和尾指針的就緒列表 Idle線程是空閑優(yōu)先級的線程,所以只有當(dāng)其他的所有線程都處于阻塞狀態(tài)時才被運(yùn)行。idle線程可以檢測cpu的使用情況,并且調(diào)整內(nèi)核參數(shù)以節(jié)省能量。,內(nèi)核相關(guān)數(shù)據(jù)結(jié)構(gòu)定義,內(nèi)核為每一個優(yōu)先級維護(hù)一個含有頭指針和尾指針的就緒列表 typedef

32、 struct thread_t *head; thread_t *tail; tlist_t; 信號量數(shù)據(jù)結(jié)構(gòu)定義如下: typedef struct int8_t val; /該字節(jié)用于作為互斥信號量或計數(shù)信號量 tlist_t q; /頭指針和尾指針 mos_sem_t; 在任何時刻,任何一個線程或是屬于就緒列表,或是屬于信號量列表 指示當(dāng)前正在運(yùn)行線程的全局?jǐn)?shù)據(jù)結(jié)構(gòu),定義如下: thread_t* _current_thread,系統(tǒng)啟動過程,整個MOS系統(tǒng)是從主函數(shù)main()開始運(yùn)行的 Main()函數(shù)中生成了一個新線程:pre_start()。這個新生成線程主要的任務(wù)是初始化系統(tǒng)

33、,例如串口,傳感器等 pre_start()中又調(diào)用了start()函數(shù),而start()是用戶程序的開始執(zhí)行函數(shù),所有的用戶程序都應(yīng)該以start()函數(shù)開始。 調(diào)度器啟動函數(shù)mos_sched_start()的定義如下: void mos_sched_start(void) running = TRUE; kernel_timer_init();/初始化硬件定時器,這些定時器用于控制休眠時間和時間片大小的 sleep_timer_init(); ENABLE_INTS();/一旦中斷使能了,調(diào)度器便會開始調(diào)度線程和把時間分片 dispatcher(); /開始調(diào)度第一個線程 idle_lo

34、op(); /若無線程可調(diào)度,調(diào)度器進(jìn)入空閑狀態(tài) ,網(wǎng)絡(luò)協(xié)議棧和通信層(COMM層),整個網(wǎng)絡(luò)棧有四層組成 應(yīng)用層,網(wǎng)絡(luò)層,MAC 層和物理層 第三層及三層以上 由網(wǎng)絡(luò)協(xié)議棧提供,它可被作為一個或多個用戶級線程執(zhí)行 ,提供零拷貝服務(wù) 網(wǎng)絡(luò)協(xié)議的不同層可以執(zhí)行在不同的線程中,或者網(wǎng)絡(luò)協(xié)議棧中所有的層可以執(zhí)行在同一個線程中 MAC 和物理層由通信層(COMM層)提供 COMM層為通信設(shè)備的驅(qū)動程序定義了統(tǒng)一接口,這些設(shè)備包括串口,無線通信設(shè)備等,它實現(xiàn)了異步的I/O操作 ,也管理數(shù)據(jù)包緩沖和同步設(shè)備驅(qū)動程序 COMM層也實現(xiàn)了零拷貝操作和零輪詢 ,高層的網(wǎng)絡(luò)協(xié)議或用戶線程可以使用COMM層提供的統(tǒng)

35、一接口函數(shù)與通信設(shè)備交互,設(shè)備驅(qū)動層(DEV層),設(shè)備驅(qū)動層(dev層)涵蓋了同步IO設(shè)備的驅(qū)動程序(如傳感器,外部存儲器等)和異步通信設(shè)備的驅(qū)動程序(如無線電,串口等),每一個設(shè)備都為上層用戶提供了 POSIX風(fēng)格的系統(tǒng)調(diào)用函數(shù) MOS使用了一個靜態(tài)表來存儲每一個設(shè)備的函數(shù)指針 每一個設(shè)備都使用一個互斥信號量,幫助多個使用者互斥地使用設(shè)備 設(shè)備的狀態(tài): DEV_MODE_OFF, DEV_MODE_IDLE, DEV_MODE_ON,能量管理,提供了標(biāo)準(zhǔn)的接口用來控制外部設(shè)備的能量狀態(tài) ,可以使用dev_mode()函數(shù)來設(shè)定底層設(shè)備的能量狀態(tài) ,三種不同的能量設(shè)備狀態(tài):開啟,關(guān)閉和空閑 M

36、OS的微處理器能量管理與線程調(diào)度是緊密結(jié)合的,并且它支持2個級別的節(jié)能 : 當(dāng)調(diào)度器就緒隊列空閑了,調(diào)度器會隱式的使微處理器進(jìn)入空閑狀態(tài) ,此時消耗更少的能量 當(dāng)系統(tǒng)中所有的線程都通過調(diào)用了函數(shù)mos_thread_ sleep()要求進(jìn)入休眠狀態(tài)時,調(diào)度器就會使處理器進(jìn)入更節(jié)能的休眠狀態(tài) ,此狀態(tài)下,只有一個定時器處于運(yùn)行狀態(tài)以便在休眠周期到的時候能喚醒相應(yīng)的進(jìn)程。,Mantis OS模擬器,提供了原型環(huán)境,用于在真正配置網(wǎng)絡(luò)前測試傳感器網(wǎng)絡(luò)應(yīng)用程序 MANTIS允許程序員在虛擬傳感器節(jié)點和真實的傳感器節(jié)點上測試同一個程序 MANTIS把虛擬環(huán)境和真實的網(wǎng)絡(luò)結(jié)合在一起,例如允許虛擬節(jié)點和物理

37、節(jié)點共存,并且在原型環(huán)境中還可以互相通信 MANTIS的虛擬節(jié)點可以使用MANTIS API以外的API MOS可以在X86(Linux 或Windows)平臺上作為一個應(yīng)用程序運(yùn)行 (稱為 XMOS) XMOS 不能完美的模擬傳感器節(jié)點,Mantis OS模擬器,Mantis OS 編程,C語言作為編程語言 MOS系統(tǒng)在初始化完畢后會自動調(diào)用start()函數(shù)從而啟動應(yīng)用程序運(yùn)行 可以使用MOS_thread_new ()生成新的子線程,使用無交互后臺程序命令,提供了一種與連接在串口上的傳感器節(jié)點交互的方式 ,用戶也可以定義自己的命令 用來生成新線程的函數(shù),其原形如下: uint8_t mo

38、s_thread_new (void(*function_start)(void), uint16_t stack_size, uint8_t priority) start函數(shù)里生成一個新的command daemon 線程 使用MOS_register_function函數(shù)可以注冊用戶定制的函數(shù): bool mos_register_function (char *name, void(*func_pointer)(void),設(shè)備層( Device Layer),設(shè)備層提供了與硬件設(shè)備交互的通用接口 設(shè)備的驅(qū)動被定義在MANTIS/src/MOS/dev中,設(shè)備列表定義在MANTIS/s

39、rc/MOS/dev /include/dev.h中 通過調(diào)用以下函數(shù)使用設(shè)備: dev_read (DEV_NAME, (uint8_t *)buf, bytes_to_read) dev_write (DEV_NAME, (uint8_t *)buf, bytes_to_write) dev_ioctl (DEV_NAME, REQUEST, PARAMETERS.) dev_open(DEV_NAME) dev_close(DEV_NAME),設(shè)備層使用新設(shè)備,為了使用新設(shè)備,需要做以下工作: 把設(shè)備的驅(qū)動程序(.c文件)放到MANTIS/src/MOS/dev中,并且將它的頭文件放在相

40、應(yīng)的子目錄中 創(chuàng)建新設(shè)備所需要的每一個函數(shù) 為dev_open() ,dev_close()這兩個函數(shù)增加一個信號量 最后,把init調(diào)用放在main.c中,init應(yīng)該能夠初始化該設(shè)備的mutex信號量,并且執(zhí)行與該設(shè)備相關(guān)的其它初始化,使用通信層,COMM掩蓋了創(chuàng)建緩沖區(qū)和底層不同硬件通信設(shè)備接口的細(xì)節(jié),以方便用戶使用 調(diào)用comm_send發(fā)送數(shù)據(jù)包時,需要把指向包緩沖區(qū)的指針作為參數(shù) ,COMM層將阻塞這個發(fā)送進(jìn)程,并把這個指針傳遞給具體的設(shè)備驅(qū)動程序,由低層的驅(qū)動程序完成數(shù)據(jù)的發(fā)送,發(fā)送完成后,被阻塞的線程會繼續(xù)運(yùn)行。 接收緩沖區(qū)是由COMM層自己管理的,設(shè)備的驅(qū)動程序可以申請緩沖區(qū)

41、,并把收到的數(shù)據(jù)包放入該緩沖區(qū)。 應(yīng)用程序線程調(diào)用com_recv時,它將會被阻塞,直到設(shè)備填滿了緩沖區(qū),同時會返回指向填滿數(shù)據(jù)緩沖區(qū)的指針,使用完該緩沖區(qū)后必需調(diào)用com_free_buf(聲明為靜態(tài)存儲的除外)來釋放緩沖區(qū),使用通信層使用comBuf,接收數(shù)據(jù)包時按下列方法使用comBuf: 1包含源文件: #include com.h 2創(chuàng)建一個comBuf指針,該指針指向的緩沖區(qū)將在com_recv()函數(shù)中分配,如下: static comBuf *recv_pkt; 3使設(shè)備進(jìn)入監(jiān)聽模式,這里需要使能接收中斷以便開始接收數(shù)據(jù),如下: com_mode(IFACE_NAME, IF_

42、LISTEN); 4最后將接收到的數(shù)據(jù)放到緩沖區(qū)的負(fù)載部分,從而完成接收,如下: recv_pkt = com_recv(IFACE_NAME); 發(fā)送操作中,除了需分配靜態(tài)comBuf*(或使用剛使用完的com_recv()中)之外,其他方面與接收操作相同,休眠和定時,休眠使用mos_thread_sleep函數(shù)使線程進(jìn)入休眠狀態(tài),其原型如下: void mos_thread_sleep (uint32_t sleeptime) 使用計時器時鐘 ,可以使用realtimer來實現(xiàn)計時操作,它是底層硬件定時器的抽象 #include “realtime.h” /包含頭文件 real_timer

43、_init(); /初始化為CTC模式 uint32_t time; time = *real_timer_get_ticks(); /獲得計時值 調(diào)用real_timer_clear()可以重啟計時器,將運(yùn)行的值重新設(shè)為0即可,使用定時器Alarms,Alarm用來實現(xiàn)節(jié)點上的定時器功能,使用alarm過程如下 : 提供alarm的頭文件,如下: #include clock.h 下一步需要實例化alarm 實例化mos_alarm_t 結(jié)構(gòu)(windows平臺或linux平臺) 下一步需要設(shè)定回調(diào)函數(shù),當(dāng)alarm觸發(fā)(溢出)時該函數(shù)將被調(diào)用 設(shè)定mos_alarm_t的其他參數(shù),不同平臺

44、的使用方法也不同 使用mos_remove_alarm函數(shù)移除一個alarm : mos_remove_alarm ( switch (msg-type) /下面實現(xiàn)了對不同消息的處理 case MSG_INIT: s-pid = msg-did; / 初始化模塊具體的狀態(tài),如定時器等 return SOS_OK; /其他消息的處理 case MSG_FINAL: / 釋放模塊占用的資源 return SOS_OK; default: return -EINVAL; return SOS_OK; ,模塊交互( Module Interaction),在下面的幾種情形下,模塊間會發(fā)生交互: 模塊

45、間消息傳遞。 對一個函數(shù)的直接調(diào)用,這個函數(shù)被另一個模塊所注冊。 模塊調(diào)用內(nèi)核函數(shù)ker-*實現(xiàn)對系統(tǒng)內(nèi)核的調(diào)用 SOS中的消息都是異步的,模塊發(fā)出一個消息后,該消息便被放入了消息隊列。SOS主調(diào)度循環(huán)從優(yōu)先級隊列中取得消息并將消息傳遞給目標(biāo)模塊的消息處理程序 模塊之間的直接函數(shù)調(diào)用用于實現(xiàn)模塊間需要同步運(yùn)行的操作。SOS使用了函數(shù)注冊和訂閱機(jī)制實現(xiàn)了直接函數(shù)調(diào)用,模塊交互,模塊A調(diào)用通過消息調(diào)用模塊B 模塊A直接調(diào)用模塊B,Module A,Module B,Module A,Module B,函數(shù)注冊,static mod_header_t mod_header SOS_MODULE_HE

46、ADER = .mod_id = TREE_ROUTING_PID, /模塊的id號 .state_size = sizeof(tree_route_state_t), /模塊狀態(tài)占有的空間 .num_timers = 2, /使用了2個定時器 .num_sub_func = 0, / 沒有訂閱其他函數(shù) .num_prov_func = 1, /提供了一個函數(shù)供其他函數(shù)訂閱 .code_id = ehtons(TREE_ROUTING_PID),/代碼ID .platform_type = HW_TYPE, .processor_type = MCU_TYPE, .module_handler

47、 = tree_routing_module, /模塊的消息處理函數(shù) .funct = 0 = tr_get_hdr_size, Cvv0, TREE_ROUTING_PID, MOD_GET_HDR_SIZE_FID, , ;,函數(shù)注冊,模塊頭中的.funct指明了Tree_routing模塊提供給其他模塊的函數(shù)的信息 第一個參數(shù)是該模塊提供給其他模塊的函數(shù)名 第二個參數(shù)是函數(shù)的原型信息 第三個參數(shù)和第四個參數(shù)分別是模塊ID和函數(shù)ID 原型信息編碼了基類型信息和是否含有動態(tài)內(nèi)存的參數(shù),函數(shù)訂閱 動態(tài)訂閱,兩種方法:一種是靜態(tài)的,另一種是動態(tài)的 靜態(tài)訂閱是指模塊在編譯時指定它要調(diào)用的函數(shù) st

48、atic mod_header_t mod_header SOS_MODULE_HEADER = /省略 .num_sub_func = 1, /訂閱了一個函數(shù) .num_prov_func = 0, /沒有提供給其他模塊可訂閱的函數(shù) /省略 .funct = 0 = error_8, Cvv0, TREE_ROUTING_PID, MOD_GET_HDR_SIZE_FID, ;,函數(shù)訂閱動態(tài)訂閱,動態(tài)函數(shù)訂閱 :使用動態(tài)函數(shù)訂閱時,只需在模塊頭中指明原型信息,并且模塊ID和函數(shù)ID均使用系統(tǒng)預(yù)定義的運(yùn)行時ID static mod_header_t mod_header SOS_MODULE

49、_HEADER = /省略 .num_timers = 1, .num_sub_func = 2, .num_prov_func = 0, /其他部分的定義 .funct = 0 = error_16, Svv0, RUNTIME_PID, RUNTIME_FID, 1 = error_8, cCC2, RUNTIME_PID, RUNTIME_FID, , ; 其中:#define RUNTIME_FID 255 #define RUNTIME_PID NULL_PID,函數(shù)訂閱動態(tài)訂閱,用戶還需要在程序中顯式的使用內(nèi)核函數(shù)ker_fntable_subscribe()實現(xiàn)對函數(shù)的訂閱,得到

50、函數(shù)指針,該函數(shù)的原型如下: int8_t ker_fntable_subscribe(sos_pid_t sub_pid, sos_pid_t pub_pid, uint8_t fid, uint8_t table_index) 第一個參數(shù)是訂閱者模塊ID, 第二個參數(shù)是提供者模塊ID, 第三個參數(shù)是被訂閱函數(shù)的ID, 第四個參數(shù)是函數(shù)記錄的索引 成功訂閱函數(shù)后,用戶使用SOS_CALL(fnptrptr,type, args.)來調(diào)用被訂閱到的函數(shù),模塊與內(nèi)核交互,通過系統(tǒng)調(diào)用獲得內(nèi)核服務(wù) 跳轉(zhuǎn)表把系統(tǒng)調(diào)用重定向到服務(wù)提供者 內(nèi)核的升級獨立于模塊 系統(tǒng)調(diào)用開銷- 12 個時鐘周期,Data

51、 Collector Module,系統(tǒng)跳轉(zhuǎn)表,優(yōu)先級 調(diào)度器,SOS 內(nèi)核,硬件,系統(tǒng)調(diào)用,中斷服務(wù),系統(tǒng)消息,硬件API,模塊插入(Module Insertion),模塊插入過程如下 : 運(yùn)行于節(jié)點上的分布協(xié)議監(jiān)聽網(wǎng)絡(luò)中的新模塊。 當(dāng)監(jiān)聽到一個模塊的廣播后,它檢查該模塊的版本是否比運(yùn)行在自己節(jié)點上的模塊更新,或者節(jié)點對這個模塊感興趣并且有空閑的程序空間可以容納這個模塊。 當(dāng)上述的2種情況之一成立,則分布協(xié)議開始下載模塊并立即檢查數(shù)據(jù)包頭中的元數(shù)據(jù)。元數(shù)據(jù)中包含了模塊ID,所需的內(nèi)存空間大?。ㄓ糜诖鎯δK的局部狀態(tài)),模塊版本信息(用于區(qū)分模塊的新舊)。 若SOS內(nèi)核不能為模塊分配用于存儲

52、模塊局部狀態(tài)的內(nèi)存,模塊插入立即失敗退出。 在模塊插入期間會創(chuàng)建一個內(nèi)核數(shù)據(jù)結(jié)構(gòu),該結(jié)構(gòu)以模塊ID(包含在元數(shù)據(jù)中)作為索引。這個數(shù)據(jù)結(jié)構(gòu)存儲了模塊消息處理函數(shù)的絕對地址,指向用于存儲模塊狀態(tài)的動態(tài)內(nèi)存的指針和模塊的標(biāo)志。 內(nèi)核通過給模塊調(diào)度一個final消息來啟動模塊刪除 ,收到final消息后,內(nèi)核將通過釋放動態(tài)分配的存儲空間,定時器,傳感器驅(qū)動程序和被模塊所擁有的其他的資源,消息調(diào)度,非搶占的優(yōu)先級調(diào)度策略 優(yōu)先級隊列有兩種:高優(yōu)先級和低優(yōu)先級 高優(yōu)先級隊列用于實時性比較高的事件,包括硬件中斷和敏感定時器等 低優(yōu)先級隊列用于調(diào)度大多數(shù)普通的事件 優(yōu)點:改善了系統(tǒng)的中斷響應(yīng)服務(wù)性能 消息也

53、能夠傳遞參數(shù) 使用post_short和post_long這兩個函數(shù)把消息放入相應(yīng)的隊列 系統(tǒng)的主調(diào)度函數(shù)定義在sos-1.7kernelsched.c,消息調(diào)度相關(guān)數(shù)據(jù)結(jié)構(gòu)定義,SOS中消息結(jié)構(gòu)定義如下: typedef struct Message sos_pid_t did; /消息目標(biāo)模塊的ID sos_pid_t sid; /源模塊的ID uint16_t daddr; /節(jié)點的目的地址 uint16_t saddr; /節(jié)點的源地址 uint8_t type; /模塊消息類型 uint8_t len; /負(fù)載長度 uint8_t *data; /指向?qū)嶋H的數(shù)據(jù)負(fù)載 uint16_t

54、 flag; /表示消息的狀態(tài) uint8_t payloadSOS_MSG_PAYLOAD_LENGTH; /靜態(tài)分配的負(fù)載 struct Message *next; /指針,用于連接下一個消息 PACK_STRUCT Message,消息調(diào)度相關(guān)數(shù)據(jù)結(jié)構(gòu)定義,優(yōu)先級消息隊列定義如下: typedef struct uint8_t msg_cnt; /隊列中的消息總數(shù) uint8_t lm_cnt; /低優(yōu)先級消息數(shù) uint8_t sm_cnt; /系統(tǒng)消息數(shù) uint8_t hm_cnt; /高優(yōu)先級消息數(shù) Message *hq_head;/高優(yōu)先級隊列 Message *hq_ta

55、il; Message *sq_head;/系統(tǒng)隊列 Message *sq_tail; Message *lq_head;/低優(yōu)先級隊列 Message *lq_tail; mq_t;,消息調(diào)度消息調(diào)度函數(shù)定義,系統(tǒng)的主調(diào)度函數(shù)(定義在sos-1.7kernelsched.c): void sched(void) ENABLE_GLOBAL_INTERRUPTS(); /使能全局中斷 for(;) SOS_MEASUREMENT_IDLE_END(); DISABLE_GLOBAL_INTERRUPTS(); /關(guān)閉全局中斷 if (int_ready != 0) ENABLE_GLOBAL

56、_INTERRUPTS(); if (true = sched_stalled) continue; handle_callback(); else if( schedpq.msg_cnt != 0 ) ENABLE_GLOBAL_INTERRUPTS(); if (true = sched_stalled) continue; do_dispatch(); /這個函數(shù)實現(xiàn)了真正的消息調(diào)度,它定 else /義在sos-1.7kernelsched.c文件中 SOS_MEASUREMENT_IDLE_START(); atomic_hardware_sleep(); watchdog_rese

57、t(); ,動態(tài)內(nèi)存,模塊需要內(nèi)存存儲狀態(tài)信息 采用了簡單的最佳適應(yīng)固定塊內(nèi)存分配策略 ,塊的大小有三種 空閑的內(nèi)存按照塊的大小組成空閑鏈表常數(shù)時間的內(nèi)存分配和回收開銷 提供了一種用于請求數(shù)據(jù)所有權(quán)改變的機(jī)制 動態(tài)內(nèi)存塊還帶有少量的注釋數(shù)據(jù) ,用于檢測內(nèi)存溢出 運(yùn)行時動態(tài)分配和回收內(nèi)存的方法提高了內(nèi)存的利用率 pkt = (uint8_t*)ker_malloc(hdr_size + sizeof(SurgeMsg), SURGE_MOD_PID),模擬服務(wù),源代碼級的網(wǎng)絡(luò)模擬 UDP很好的模擬了無線信道 模擬框架提供了一種簡單的方式用來支持SOS應(yīng)用程序開發(fā) 無需安裝交叉編譯器 需要定制內(nèi)核

58、 支持用戶定義的拓?fù)浜彤悩?gòu)軟件配置 用于驗證功能的正確性 使用Avrora實現(xiàn)了指令級的模擬 指令周期精確模擬 用于驗證定時信息 參考/avrora/,SOS應(yīng)用程序編寫,編程語言:C,減小了學(xué)習(xí)新的編程語言的難度 可以充分利用C的編譯器,開發(fā)環(huán)境,調(diào)試器和其他的為C所設(shè)計工具 代碼實例請參考課本,WSN操作系統(tǒng)概述 TINYOS 操作系統(tǒng) MANTIS 操作系統(tǒng) SOS 操作系統(tǒng) 三種操作系統(tǒng)的設(shè)計實現(xiàn)比較 WSN OS最新研究進(jìn)展 主要參考文獻(xiàn),TinyOS,MOS和SOS的設(shè)計實現(xiàn)比較,下面從設(shè)計操作系統(tǒng)必須考慮的幾個方面列舉了這三個系統(tǒng)的設(shè)計考慮,WSN操作系統(tǒng)概述 TINYOS 操作系統(tǒng) MANTIS 操作系統(tǒng) SOS 操作系統(tǒng) 三種操作系統(tǒng)的設(shè)計實現(xiàn)比較 WSN OS最新研究進(jìn)展 主要參考文獻(xiàn),WSN OS最新研究進(jìn)展,在我們書籍的編寫過程中,操作系統(tǒng)的設(shè)計者也正在努力

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論