無線傳感器網絡中的操作系統是一個位于節點硬件和應用程序之間的軟件層,它給應用程序開發者提供了基本的編程理念。操作系統的主要作用是確保應用程序能與硬件資源進行交互、執行和優化任務,在多種應用程序和服務程序之間做選擇,并試圖獲取資源。
其他功能還包括:
◇內存管理。
◇電源管理。
◇文檔管理。
◇建立關系網絡。
◇一套編程環境和工具——命令、命令解釋器、命令編輯器、編譯器、調試器等,確保用戶能開發、調試和執行用戶的程序。
◇??進入操作系統訪問敏感資源的合法入口,如輸入組件。
傳統上,操作系統可分為單任務、多任務、單用戶和多用戶操作系統。一個單任務操作系統一次只能執行一個任務,然而一個多任務操作系統能同時執行多個任務。多任務操作系統需要大量的內存來管理多個任務的狀態,并使具有不同復雜性的任務并行執行。例如,在一個無線傳感器節點中,處理器子系統與通信子系統相互作用的同時也可以與傳感器子系統相互作用。一個多任務操作系統是這種類型環境的佳選擇。然而,由于有限的資源,并行處理對資源的開銷可能無法承擔。在單任務操作系統中一次只能執行一個任務,因此目標任務執行持續時間短。在單用戶操作系統中,在同一時間只有一個用戶能使用系統里的資源,然而一個多用戶操作系統允許多個用戶同時共享系統里的資源。
一個特定操作系統的選擇取決于很多因素,在接下來的內容中,將會討論典型的功能性和非功能性方面。
1.功能性方面
1)數據類型
在無線傳感器網絡中,不同子系統之間的通信是至關重要的。由于各種原因這些子系
統相互通信,例如交換數據、托管功能和信號。相互作用通過精心制定的協議和數據類型
而產生,并且它們都是由操作系統來支持的。復雜的數據結構具有較強的表達能力但消耗
資源,然而簡單的數據結構能節約資源但表達能力有限。在無線傳感器網絡中幾乎所有現
有的操作系統或運行環境都支持C語言編程和一些復雜的數據類型,如結構體和枚舉的原
始數據類型。
2)調度
任務調度是操作系統中的一個基本功能,任務如何有效地組織、確定優先級并執行,這些決定了操作系統的效率。
從廣義上講,有兩種調度機制:基于排隊和循環調度。在排隊調度中,來自各予系統的任務是暫時存儲在隊列中,并根據預定義的規則串行執行。有些操作系統對任務指定優先級,使它們可以優先被考慮。
基于隊列調度,可進一步分為先出和排序隊列。在一個先入先出的系統中任務是按照它們抵達的時間來執行的:先到達的任務將會先被執行,確保處理器是閑置的。一個非搶占的操作系統在另一個任務沒有完成前是不能執行其他任務的,然而在優先級的操作系統中,一個更高優先級的任務可能中斷低優先級任務。在一個有序的隊列計劃中,隊列中的任務是根據預定的準則進行排序。一種方法是根據它們的預估時間來排序任務,這種方法能防止持續時間長的任務中斷持續時間短的任務,該方法也被稱為短工作優先規則( SJF)。在SJF計劃中,排序會帶來系統開銷,因為每個隊列中的任務必須進行評估,估計執行期限,并據此進行排序任務。
先入先出的系統( FIFO)是簡單和經濟的,因為它會帶來低的系統開銷。然而,先入先出的系統可能對待任務不公平,因為持續時間長的任務可能會在很長一段時間內阻礙持續時間短的任務。
循環調度是一種分時調度技術,它可以并發處理多個任務。調度程序通過把時間分解成時間片來定義時間框架,并以多路復用方式把任務分配給各個時間片。這樣所有的任務都朝著完成的方向運行。
不管任務如何執行,一個調度器可以是一個非搶占式或搶占式調度。嚴格意義上的非搶占式調度,任務從執行一直到結束不會被另一個任務中斷。相反,嚴格意義上的搶占式調度決定任務之間的時間優先順序,允許更高優先級的任務中斷低優先級的任務。也有所謂的“禮貌先發制人( politely-preemptive)”的調度,即使任務可以被中斷,但如果它是在一個關鍵部分,調度程序也不會中斷這個操作。
3)棧
棧是一種數據結構,在內存中它通過將一個數據輸入到另一個數據來暫時存儲數據結構,訪問對象遵循后進先出的原則。當它開始執行子程序前,處理器內核使用棧來存儲系統狀態信息,運用這個方法可以記住當子程序完成后程序返回的地址。通過存儲當前子程序棧頂的狀態,子程序可以再一次調用其他子程序。當該子程序完成后,處理器彈出棧頂地址,跳回到調用入口。
在一個多線程的操作系統中,每個線程都需要它自己的棧管理狀態信息,這就是為什么在無線傳感器網絡中多線程操作系統如此昂貴的一個原因。
4)系統調用
操作系統提供了一些確保關注分離的基本功能,即需要訪問硬件資源和額外的底層服務的訪問機制的實施細節。用戶調用這些操作,他們希望在訪問硬件資源如傳感器、看門狗定時器或者進行無線收發時,不需要考慮硬件是如何進行訪問的。
5)中斷處理
一個中斷是由硬件設備產生的異步信號,使處理器中斷執行當前的指令,并調用相應的中斷處理程序。處理器把進程被中斷的狀態存儲在堆棧中,并將執行中斷處理子程序。例如,當一個通信子系統收到一個需要立即處理的數據包時可能會產生一個中斷信號。該處理器子系統必須暫停當前通信進程的執行,在操作系統中調用適當的模塊來處理數據包,處理完數據包后再返回執行通信進程。
另外,硬件設備在操作系統中可以定義多個中斷標志。在某些情況下,操作系統本身可以產生周期性中斷,用處理器來監控硬件資源的狀態,發現硬件中斷標志,并處理相應的中斷事件。
任務可以有不同的優先級,同樣,中斷信號也可以有不同的優先級,一個高優先級的中斷可以中斷低優先級的中斷。在這樣的系統中,程序可以選擇設置中斷屏蔽來避免被中斷。中斷屏蔽可以防止程序被一些不相關的低級別中斷所中斷。但屏蔽中斷可能存在破壞數據的危險。而一些操作系統在關鍵的操作中必須屏蔽中斷。
6)多線程
一個線程是一個處理器或一個程序在執行過程中所采取的路徑。在一個不可中斷操作系統的單一任務中,任務是單一的,并且只有一個執行線程。在多線程環境中,一個任務可以被分為多個邏輯塊,可相互獨立的并發執行。同樣,不同來源的多個任務也可并發執行。如果有必要,線程的相同任務可以共享一個共同的數據和地址空間來互相溝通。
一個多線程的操作系統主要有兩個優勢:
(1)任務之間互不阻止,這一點對于處理與任務有關的輸入/輸出系統特別重要。
(2)短期任務可以與長期任務一起執行。
因為線程具有占有資源的性質,它們不能被無休止地創建。創建線程能降低處理器的執行速度,可能沒有足夠的資源來分配大量的線程。因此,一些操作系統只能支持有限數量的線程,并把它們置入緩沖區中。緩沖區中的每一線程都等待分配任務,一旦得到請求,緩沖區就會分配一個可用的線程,直到任務完成,線程就會返回到緩沖區,并且等待下一次分配。如果緩沖區里所有的線程都被使用了,在下一個線程返回緩沖區之前,系統將會在隊列中等待即將到來的請求。以這種方式,操作系統能將線程數量控制在一定規模。
7)基于線程與基于事件的編程
無線傳感器網絡,支持并發任務。其中涉及輸入/輸出系統的任務特別重要,應選擇基于線程或基于事件的執行模式。
根據分散的堆棧和建立上下文信息的大規模,選擇基于線程或基于事件的執行模式。在一個單一的程序和單一的地址空間中,基于線程的程序使用多線程控制。這樣,當其他任務在不同的線程中執行時,被輸入/輸出設備阻止的線程可以被掛起。然而,程序員必須小心用鎖(lock)保護共享數據結構,并使用條件變量來協調執行線程。在處理所有這些問題時,操作系統需要同步執行程序。一般情況下,多線程環境編寫的程序代碼是復雜的、可能產生錯誤,并可能導致死鎖和惡性競爭。
在基于事件的編程中有事件和事件處理者。在操作系統調度中,當~個指定的事件發生時,事件處理程序會被命名。通常內核實現一個循環功能,當事件發生時,會以輪詢的方式調用相應的事件處理程序。一般情況下一個事件會被一次處理完,但如果碰到一個阻塞操作,它會寄存一個新的回調,并向調度程序返回控制。
8)內存分配
內存單元是一種寶貴的資源,這是操作系統的關鍵所在,此外,數據和應用程序代碼被暫時存儲在內存單元中。內存怎樣分配以及分配多長時間,決定任務執行的速度。內存可被分配到一個靜態或動態的程序中,靜態內存分配可以節省使用內存,但它只能用于程序內存的使用是預先知道的。程序啟動時分配靜態內存,作為執行操作的一部分,不會被釋放。因為程序的內存是在編譯時分配的,所以內存的使用率很高。另一方面,靜態內存分配不允許在運行時進行。
當程序編譯不知道所需內存的大小和被占用時間時,就采用動態內存分配。在使用動態數據結構的情況下,編譯時無法知道內存的大小,這樣的程序通常只是短暫使用內存。當它們不再需要特定的內存區時,它們會占用并短暫使用一部分內存。因為內存的資源是有限的,不再使用的內存可以被釋放或分配給不同的所有者。動態內存分配確保了編程的靈活性,但產生了相當大的管理開銷。
把增加節點的內存容量作為一項策略,大多數體系結構使用EEPROM或閃存來存儲程序代碼。因此,它可能用來部署相對復雜的應用程序和通信協議。然而,讀寫閃存的過程是耗能很大的。
2.非功能方面的問題
1)關注點分離
因為可用的資源極度緊張,被設計用來支持資源受限的設備以及由這些設備所建立的網絡的操作系統不同于通用的操作系統。在通用操作系統中,操作系統和在它上面運行的應用程序之間有一個清晰的分離,它們通過定義良好的接口和系統調用來互相交流。操作系統本身有幾個不同的服務可以獨立地進行升級、調試或刪除。在無線傳感器網絡中,這種方式是很難實現的。
在大多數情況下,操作系統由一個輕量級的模塊“編排”( wired)在一起,創造一個單塊的程序模塊代碼,負責傳感、處理和通信任務?!熬幣拧毙枰诰幾g時產生一個單一的系統映像,并可以在單個節點上安裝。一些操作系統提供了一個不可分割的系統內核以及一套庫組件來構建一個應用程序。也有其他的操作系統,提供了一個內核和一些可重構的底層服務,將其虛擬成節點的硬件組件。該服務可以在“編排”后構成應用程序,因為這些服務的核心功能相對獨立,即使它的功能是有限的,在一定程度上也是一個關注點分離,關注點分離確保了靈活和高效的重新編程和重新配置。更新或升級,可根據需要作為一個整體或部分。在軟件升級中,重新配置確保了通信帶寬和存儲空間的有效利用。
2)系統開銷
操作系統執行程序代碼,需要自己的資源共享。消耗多少資源取決于它提供的更高服務級別和應用時的規模和服務類型,操作系統所消耗的資源稱為系統的開銷( overhead)。
目前可用的無線傳感器節點擁有的資源是以幾千字節和幾百兆字節為單位來計量的,這些資源會在程序進行檢測、數據融合、自組織、網絡化管理和通信等方面被共享,鑒于這些任務,操作系統的開銷應該被理解。
3)可移植性
前面已經闡述了不同的硬件架構能被用于開發無線傳感器節點,在理想情況下,異構體系結構和操作系統的節點能夠共存和互相協作。然而目前現有的操作系統不提供這種類型的支持。
對于利用操作系統的可移植性來處理硬件架構的快速演變的問題,無線傳感器網絡仍然是一門新興技術。在過去的十年中,架構設計經歷了顯著的變化,越來越多領域的應用程序開始被研究。為了適應無法預料的要求,這種演變的趨勢將會繼續下去。而操作系統應該是便攜的和可擴展的。
4)動態編程
一旦無線傳感器網絡被部署,一部分應用程序或操作系統可能需要重新編程,原因如下:
◇??在初的部署設置時,無法獲取完整部署所需的條件參數,因此,網絡可能無法達到佳性能。
◇??應用需求和網絡操作中物理環境的屬性會隨著時間變化。當網絡正在運行時檢測和修復錯誤可能是必要的。
因為節點數量龐大,人工更換軟件是行不通的。另一種方法是開發一個操作系統,提供支持動態編程的功能。基于這樣的考慮,要求應用程序和操作系統之間有明顯的分離界限,才可能實現動態重編程的功能。另一方面,如果兩者之間有界限,在原則上可以實現動態編程,但其實際執行取決于幾個因素:首先,操作系統應該能接收“一片接一片的(pieceby piece)”軟件更新,將它組合并存儲在臨時內存中;其次,操作系統要確保這確實是一個更新版本;后,它應該能刪去舊的軟件,并安裝和配置新的升級版本。所有這些資源的消耗可能導致自身錯誤。
軟件重新編程需要多種傳輸協議代碼、壓縮和解壓縮代碼;并確保代碼的一致性和版本控制;以無線傳輸代碼的方式來提供可靠穩定抗干擾的( robust)傳輸策略。
當前發展中的編程工具和環境將在以后的章節中介紹。
3.原型
1)TinyOS (微操作系統.)
在無線傳感器網絡中微操作系統應用廣泛、可選范圍豐富并且運行環境有輔助工具。此外,它經歷了一個漫長的設計和演進過程,使其工作原理更容易理解。
微操作系統具有緊湊的結構,這使它能夠支持很多應用程序,概念上的架構包括一個調度器和一套組件,可通過定義良好的接口相互連接。組件可分為配置組件和模塊。配置組件是由兩個以上的模塊相互連接而被“編排”( wiring)組成,而模塊是微操作系統程序的基本構建塊。多種配置組成一個單一的可執行代碼,并產生一個微操作系統應用程序,微操作系統在應用和操作系統之間并沒有提供一個明確的關注點分離。
一個組件由一個框架、命令處理程序、事件處理程序和一套不可中斷的任務組成。組件是類似于面向對象編程語言中的對象,它封裝了狀態,并通過定義良好的接口進行交互。一個接口可以定義命令、事件處理程序和任務,并以它們自己的狀態在一定框架范圍內運行。因此,組什需明確其命令的用途和發出信號的事什,這種方式可以滿足在這個應用程序被編譯時確定所需的資源。
組件是分層結構,并通過命令和事件互相通信:高級別的組件給低級別的組件廣播發送命令,低級別的組件給高級別的組件發送響應事件信號。因此,高級別的組件實現事件處理程序,而低級別的組件控制處理器(或功能子程序)。物理硬件的組成是以層次結構為基礎的,圖3.1說明了應用程序和操作系統之間的邏輯邊界。
在圖3.1中可以看到,有兩個組件處于高級別,即路由組件和傳感器中的應用組件。路由組件是負責建立和維護網絡的,而傳感器的應用組件是負責傳感和處理的。通過動態交互信息,兩個組件互相通信,并與較低級別的組件異步。此外,通過發出無阻塞指令和表示對指定的事件的關注,一個高級別組件能與低級別組件相互通信。
圖3.2-圖3.4顯示了邏輯結構部件和組件配置,在圖3.2中組件A顯示了它服務接口C的功能,反過來又提供給命令Dl和信號事件D2。在圖3.3中,組件B表示宣布調用命令Dl和提供一個事件處理程序來處理事件D2的界面。
在圖3.4中,組件A和組件B之間的綁定是通過配置E來約束的。
?
圖3.1??低級別組件和高級別組件的邏輯邊界
?
微操作系統中定義的任務、指令和事件作為微操作系統運行環境的基本構建塊,是為單一的框架組件之間能進行有效通信。任務是從執行直到完成的單一過程。換句話說,雖然它們可以被事件中斷,但它們不能被其他任務搶占,這就是為什么微操作系統能支持并發( concurrency),并確保任務互不干擾或破壞對方的數據的原因。
因為任務要被完整執行,它可以分配一個單一的堆棧來存儲上下文消息。任務可以調用低級別的指令,發送信號給更高級別的事件,并調用其他任務,包括它們自己。例如,負責從通信子系統讀取數據包的任務可以重復調用自己,直到它已經完成讀取所有的數據包。在微操作系統中調用任務是以FIFO規則為基礎的,微操作系統架構對持續時間短的任務是有效的。
指令是由高級別組件到低級別組件的非阻塞請求,為了處理潛在的長期執行操作,微操作系統引入了分時操作的概念。在一個分時系統中,當任務完成后,函數調用會立即返回,并且調用的函數會通知調用者。它被稱為分時是因為它將調用和執行分割成兩個時間段來完成,一個典型的例子是數據包的傳輸任務。數據包傳輸可以阻塞任務,因為接收器在數據包重發之前要等待一個超時事件( ttim。。ut)。然而,在超時信號出現之前如果收到一個ACK數據包,接收器會放棄等待ttime。。。的控制。在微操作系統中,這個任務被分解成兩個事件:超時事件和數據包接收事件。
每一個對己被命名事件感興趣的組件都應該提供一個事件處理程序來處理它,硬件事件發生時將會調用事件處理程序。低級別的組件也能直接連接到硬件中斷的處理程序,如外部中斷、定時器事件、計數器事件。事件處理器會以不同的方式來處理可能發生的事件。它可以將后期高級別事件信息存入其結構中,或者調用低級別指令。
在微操作系統中資源分配是采用靜態內存分配來進行優化的,因為應用的內存需求是在其組成時就明確了,它避免了與動態分配有關的額外開銷。由于微操作系統缺乏明確的關注點分離,限制了它的適應性。此外,沒有額外支持的微操作系統和任何機制來動態加載和刪除組件。
作為一個基于事件的系統,微操作系統不支持直接執行上下文,因此一個復雜的程序通常需要一個狀態機。因為許多程序員認為狀態機難以管理,所以狀態機出現較少,文獻中提到一個典型的例子是處理與加密操作。這些操作需要幾秒鐘的時間來完成,占用了處理器的寶貴時間,使系統無法響應外部事件?;诰€程的操作系統用時間先決( time critical)或短周期的任務搶占來處理這種類型的情況。
2)SOS
SOS嘗試在靈活性和資源效率之間建寺平衡,與微操作系統有所不同,它支持運行程序代碼重新配置和重新編程。操作系統包括內核和一組模塊,可以裝載和卸載。在功能上模塊類似于微操作系統的組件,它實現了特定的任務或功能。此外,微操作系統組件能以同樣的方式“編排”建立一個應用程序,SOS應用程序由一個或多個互動模塊組成。不像微操作系統的組件,它在內存中有一個固定存儲區,在SOS模塊中是一個狀態獨立的二進制代碼,這種典型的特征確保了SOS能與其他模塊動態鏈接。
SOS內核提供底層硬件接口,此外,它提供一個基于優先級的調度機制,并支持動態內存分配。
(1).交互
交互模塊通過異步通信和直接調用注冊函數(registered function),源于模塊A到模塊B的消息要先經過位于優先級隊列排列的調度器。然后內核會調用模塊B中合適的消息處理程序,并把消息傳送給它。
模塊執行特定目的存在的消息處理程序。一個模塊可以通過直接調用它的注冊函數與另一個模塊進行交互。通過函數調用的交互作用比基于消息通信的速度要快,這種方法需要模塊來明確記錄其在內核中的公用函數,所有關注這些函數的模塊需要“訂閱”( subscribe)這些函數。在模塊初始化時,注冊函數通過調用一個名為ker_register_fn的系統函數來產生,調用確保模塊通知內核二進制映像函數被執行了。內核通過創建一個函數控制塊(FCB)來存儲函數的關鍵信息,這個信息是用來處理函數訂閱,并支持動態內存管理和運行時的模塊更新。圖3.5說明了兩個基本類型模塊之間的交互作用。
?
??????????????????圖3.5??SOS系統中模塊間的交互
模塊通過調用名為ker_get_handle的系統函數來訂閱一個命名函數,這樣做它們提供了帶有模塊的內核和函數的ID,這將用于定位關注的函數控制塊。如果查找成功,內核返回一個指向訂閱函數的函數指針的指針。訂閱者通過取消指針來訪問訂閱函數,這確保了內核通過FCB改變函數指針來重置新版本的功能,這個過程對用戶是透明的。
(2).動態重編程
以下5個基本特征確保了SOS支持動態編程。第一,模塊都是獨立的二進制文件,它們使用相對地址而不是絕對地址,因此它們可重定位。第二,模塊實現了兩種處理,初始化和終的消息處理程序。當首次加載模塊時,初始化消息處理器將調用內核。其目的是設置模塊的初始狀態,包括初始化定時器、函數注冊以及函數訂閱。在卸載模塊前,內核會調用終的消息處理器。其目的是釋放模塊擁有的所有資源,包括定時器、內存和注冊函數,使該模塊能正常退出系統。在終消息后,內核會進行垃圾回收。第三,編譯過程中,在已知的偏移二進制中,SOS使用一個鏈接腳本放置初始化處理模塊,腳本在模塊插入時可輕松地連接。第四,SOS保留外部的模塊狀態,這使新插入的模塊繼承了它所替換模塊的狀態信息。第五,當模塊插入時,SOS生成和保存含有相關模塊的初始化處理程序的絕對地址的原數據包,以及指針指向保持模塊狀態的動態內存。
在SOS中,動態模塊替換發生需3個步驟。
(1)當一個新的模塊使用時,代碼分發協議在網絡中發布公告,公告中包含了模塊的身份(ID)、版本號和所需內存的大小。當本地分發協議接收公告時,它評估數據包,決定模塊是否是已經在本地存在更新的版本或節點對新的模塊是關注的。在這兩種情況下,它也可以確保有足夠的空間在程序存儲器中下載模塊。
(2)?一旦決定下載模塊,該協議進行下載模塊并審查第一個數據包中的元數據。元數據包含了存儲該模塊所需本地內存的大小。如果SOS內核決定了它不具有足夠的隨機存儲空間來滿足運行該模塊所需的本地空間,模塊插入將會立即停止。
(3)換句話說,如果任何事情都很正常,那么模塊插入將會發生。在模塊插入時,內核創建的元數據用來存儲處理器的絕對地址,指向動態內存控制模塊的狀態和信息。SOS內核通過調度模塊的初始信息來調用模塊的處理器。
3)Contiki
Contiki是一種混合的操作系統,系統程序被分為內核服務和裝載程序。默認情況下,它的核心功能是作為一個事件驅動的內核,并作為應用程序庫支持多線程操作。有一個動態鏈接策略是用來匹配多線程庫和具有明確要求的應用。
像SOS -樣,Contiki實現了把由內核支持的基本系統與動態可裝載和可重編程服務的剩余部分分離。通過內核發布公告,服務程序之間相互通信。內核本身不提供任何硬件抽象,相反,它允許設備驅動程序和應用程序直接與硬件通信。這個內核的范圍有限,很容易重新編程和更換服務。
每一個Contiki通過一個私有內存來管理自己的狀態,保留一個指針來運行狀態。然而,服務與服務之間共享相同的地址空間,它還實現了一個事件處理程序和一個可選的輪詢處理器。圖3.6說明了ROM和RAM的內存分配。
?
圖3.6??Contiki操作系統的內存分配
如圖3.6所示,Contiki在編譯時被分成兩個主要部分:一部分是虛線內的服務,包括核心服務;另一部分是這些虛線外的可動態裝載服務。核心由內核、程序加載器、驅動通信硬件設備的通信協議棧和其他經常使用的服務組成。這些服務被編譯成一個二進制映像,并運行在無線傳感器節點上。這種操作系統只能被特殊的啟動引導加載器(boot loader)覆蓋或修改,其他情況下是不能被動態修改的。
該程序加載器負責將驅動程序下載到活動內存(active memory),它可以通過遠程數據的通信服務或直接從本地存儲來得到二進制文件。通常程序二進制文件存儲在EEPROM中。
內核是操作系統的核心要素,其基本任務是調度事件和定期輪詢處理。隨后,Contiki的程序執行由內核或通過輪詢機制調度事件來觸發。在沒有被中斷或被其他機制所搶占的情況下,事件處理程序完成一個完整的事件處理。當Contiki在多線程環境中運行時,可能會出現一個線程搶占另一個線程的情況。
內核支持同步和異步事件,同步事件被盡可能快地派遣到目標進程,一旦事件的進程結束,控制返回到張貼過程(posting process)。另一方面,異步事件在合適的時候被派遣。除了這些事件外,內核提供了一種輪詢機制,定期對硬件組件的狀態進行采樣。在這段時間內,調查處理器通過硬件設備的優先級來確定目標。
(1).服務架構
Contiki操作系統一個很有趣的特征是其支持動態加載和重新配置的服務,這是通過定義服務、服務接口、服務存根和服務層來實現的。Contiki服務模塊是針對微操作系統的。?Contiki服務包括服務接口及其實現,也就是所謂的過程。服務接口包括一個版本號,以及實現該接口的功能的指針函數的列表。服務存根通過服務接口與服務的動態通信來完成一個應用程序,服務層類似于查詢服務或注冊表服務。主動服務通過提供服務接口、地址信息和版本號來對服務進行描述,這樣一來,服務層保持跟蹤所有進行的服務。圖3.7.說明了應用程序與Contiki服務是如何進行交互的。
?
圖3.7??Contiki服務交互架構
因為程序是通過服務接口存根調用服務的,所以這種操作沒必要知道有關的實施細節或服務在內存中的地址。當服務接口被調用時,服務接口存根查詢服務層,并獲得一個服務接口的指針。一旦獲得服務的接口描述與服務的存根版本號配對,那么該接口存根就會調用執行所請求的功能。服務與使用該服務的程序的松散耦合使操作系統可以更新服務,而不需要修改應用程序。
(2).協議線程( Proto Thread)
Contiki通過結合一些事件和線程的功能來介紹協議線程的概念,協議線程可以視為輕量級(無堆棧的)線程,但它們也可以作為基于事件編程的中斷任務。一個協議線程提供有條件的阻塞等待聲明,PT__ WAIT_UNTILQ需要一個條件語句塊實例,直到該語句評估正確為止。當協議線程到達PT WAIT_UNTIL()聲明時,如果條件聲明是正確的,那么它不中斷地繼續執行。PT—WAIT_UNTIL()指令不需要任何條件聲明,包括復雜的布爾表達式。
因為協議線程是無堆棧的,只有明確的PT WAIT_UNTIL()聲明能阻塞這個線程,所以從調度的角度來看,系統中的所有協議線程在相同的堆棧中運行,上下文切換是通過堆棧彈出來實現的。通過分別使用PT__ BEGIN和PT END聲明來明確宣告協議線程的開始和結束,協議線程可以通過PT EXIT語句提前結束。
協議線程概念并沒有明確指明它什么時候或以什么方式來被調用或調度,在Contiki的實施中,運行在事件驅動內核頂層的過程被當作一個協議線程來執行,因此,當過程收到一個事件時協議線程被調用,例如,在過程從其他過程或計時器事件收到消息的時候。同樣,協議線程概念不預先確定內存是如何劃撥給管理協議線程狀態的。與調度一樣,這也是在特定條件下實現的。例如,只有預先知道操作系統是由基于一組固定的協議線程組成,才能通過提前靜態分配內存來進行狀態管理。如果協議線程的數量沒有提前知道,內存也可以以一種動態方式來分配。在Contiki執行中,靜態內存分配是一種典型的設置,并且協議線程狀態保存在進程控制塊中。
因為協議線程減少了明確的狀態機和狀態轉換,所以簡化了事件驅動的編程狀態機的設計。協議線程的成本是與內存開銷和幾個處理器的開銷有關的,為了說明協議線程的實用性,考慮一個MAC協議,定期關閉無線收發子系統,但要確保無線收發子系統在進入休眠狀態前完成通信。這種行為歸納如下:
(1)此時無線收發子系統打開。
(2)無線收發子系統周期性地保持收發狀態。
(3)?一旦超過,無線收發子系統就會關閉,但是它已完成一項正在進行的通信。
(4)如果通信沒有完成,那么MAC協議就要等待twait max時刻到達,相當于一個完整的通信周期。
(5)如果通信完成或超過大等待時間,無線收發子系統就會關閉,并且會保持休眠一個周期。
(6)這個過程(通信一休眠)不斷重復。
圖3.8和圖3.9分別顯示了基于事件與基于協議線程實現的通信子系統的睡眠調度。狀態機的實現需要一個明確的狀態變量,可以采用開啟、等待和關閉。有條件的if語句是用來執行不同的動態變量的值,代碼可以放置在事件處理函數中,無論什么時候事件發生都可以被調用。在這種情況下可能發生的事件是定時時間到時和通信結束。在圖3.8中可以看出,控制狀態機的代碼量超過總代碼量的三分之一,此外,該機制的6個步驟的結構不能直接從代碼中顯現出來。
協議線程實施休眠的時間安排顯然是更短、更直觀的。
?
4)LiteOS
LiteOS是一種基于多線程的操作系統,并且支持多個應用程序。它是基于一個操作系統和在它上面運行的應用程序之間完全分離的原則,不同于所有其他的操作系統,LiteOS并沒有提供用來“編排”起來建立應用程序的組件或模塊。就LiteOS而言,開發建立阻塞和確定它們彼此交互的方式,完全是應用程序開發人員的任務。
LiteOS提供幾種系統調用的方式:來自用戶的分離系統的殼調用,分層文件管理系統,動態重編程技術。
整個系統仿照分布式文件系統,在基站端的用戶可以使用安裝在資源豐富的計算機上的殼調用來實現對已命名節點的識別、交互,以及重編程。網絡中的每個節點運行一個多線程的內核,其中有3個主要組件:一個調度器、一套系統調用和二進制安裝器。內核的系統調用,使遠程用戶可以訪問和管理本地文件和目錄。本地文件分為傳感器數據、設備驅動程序和應用程序二進制文件。在系統內的層次結構中,一個節點是一個無指定的組件。
圖3.10說明了LiteOS的系統架構。
?
圖3.10??LiteOS操作系統架構
(1).殼和系統調用
殼繼承了Linux操作系統的幾個特點。殼向一個距其有一跳距離的無線節點提供了一種安裝機制,使整個網絡可被視為一個分布式和分層文件系統。用戶可以像使用本地資源那樣訪問一個指定節點的資源。殼支持大量的可以在分布式文件系統上執行的Linux指令。
這樣,LiteOS給Linux用戶提供了一個熟悉的界面。
命令被分為五大類:文件命令、處理命令、調試命令、環境命令和設備命令。文件中的命令用于瀏覽分層文件系統,以及移動、復制、刪除文件和目錄。下面給出一個使用文件命令操作的例子。
$ pwd
Current directory is /snOl/node101/apps
$ cp /c/Blink.lhex Blink.lhex
Copy complete
$ exec Blink.lhex
File Blink.‘lhex successfully started
$ ps
Name State
Blink Sleep
在這個例子中,pwd命令在sn01節點中打印了工作目錄,這就是node101/apps。接下來,使用cp指令,Blink.lhex文件從資源豐富的計算機的根日錄被復制到指定節點的sn01目錄。然后,通過使用exec指令,文件就會被執行。ps指令報告進程狀態,在這種情況下表示一個休眠的線程。
該過程命令對管理、創建、暫停、終止線程是非常有用的。在LiteOS中可以同時使用多達8個線程,調適指令確保能建立調適環境來調適程序代碼。環境指令給管理操作系統環境提供了支持、顯示交互的歷史記錄,并提供命令手冊。后,設備命令提供對硬件設備(如傳感器和無線收發子系統)的直接訪問。
(2).LiteFS
LiteFS是一種分布式文件系統,它是LiteOS的本質特征。通過LiteFS,用戶可以直接訪問傳感器網絡,可以規劃和管理各個節點。類似于Linux中的文件,LiteOS中的文件代表數據、應用程序二進制和設各驅動程序。本地文件系統的組織結構如下:RAM包含被開放( opened)文件的列表以及內存分配和閃存EEPROM中的有關信息。文件系統的結構被存儲在EEPROM存儲器中,實際文件被存儲在閃存中,如圖3.11所示。
?
圖3.11??LiteFS的文件系統結構
在RAM中可同時打開多達8個文件,LiteFS使用兩位向量來跟蹤EEPROM和閃存分配。8B用于前者,32B用于后者,這相當于RAM的104B。在EEPROM中每個文件代表一個32B的控制塊,控制塊的可用空問被劃分為65塊。第一塊是根塊,它在文件系統格式化時都被初始化,其余的區塊是目錄塊(圖中的D)或文件塊(圖中的F)。文件控制塊多可尋址10個邏輯FLASH頁,每一頁包含2KB的數據(或8個物理FLASH頁)。當一個文件占用超過20KB時,LiteFS為這個文件分配另一個控制塊,并且在以前的控制塊中存儲一個新的控制塊的地址。
(3).動態重編程
LiteOS支持用戶應用程序的動態更換和重新編程,無論是否提供源代碼都可以完成。如果源代碼是提供給操作系統的,它將被一個新的內存設置重新編譯,同時所有引用和指向舊版本的指針將被重新定向。如果源代碼不是提供給操作系統的,LiteOS采用“差別修補( differential patching)”機制,以取代舊版本的二進制代碼。該方法是通過插入差別修補程序,并將差別修補程序連同二迸制映像文件一起分發,來直接將重定位信息編碼到二進制應用程序代碼中。
有一種描述差別修補的數學模型已經被提出,該模型具有3個參數。該模型的參數是閃存的二進制可執行文件的起始地址、RAM中已分配內存的起始地址、棧頂。堆棧屬于內存的一部分,只是在實際執行的過程中內存的某個區域被指定作為堆棧。當這些參數已知時,就有可能將更新的程序插入到舊的二進制映像中。模型參數是憑借經驗和節點架構的知識來獲得的,這限制了修補計劃的實用性。
(4).評價
與所有的排名一樣,對操作系統的性能進行排名是一個困難的任務,排名需要從一個合適的角度進行。在無線傳感器網絡中,有關于開發、部署、運行性能和代碼更新的若干問題。如果以設計為主題,可能存在以下的問題:由操作系統提供的用來訪問硬件設備的接口有多豐富?由操作系統支持的編程環境有多靈活和富有表現性?由操作系統支持的并有利于構建應用程序的模塊、組件和庫文件是否有多樣的選擇?操作系統便攜到什么程度?應用程序代碼的可管理性如何?
如果以部署為主題,主要的方面是動態代碼的安裝和動態代碼的傳送。在大量的節點上對代碼進行安裝和測試是一個繁重的任務。同樣,如果就代碼的更新而言,動態代碼的傳送和重編程是重要的因素。
如果以運行方式為主題,主要的方面是操作系統的效率,特別是緊湊性和功耗。
在這些方面,TinyOS在規模上是緊湊的,在資源利用上是高效的,因為管理分散體的開銷成為單一管理純二進制數,但更換或重新編程成本高。SOS、Contiki和LiteOS靈活地支持了動態重編程,因此非常適合應用程序可能進行頻繁的更新和升級過程。然而,圖像傳送的成本比較高。LiteOS被視為一個分布式文件系統網絡的方式很有趣,因為它為用戶提供了一個直觀的網絡瀏覽方式。然而,因為節點是無狀態的,所有的更新記錄應存儲在用戶觸手可及的地方,它會導致網絡上額外的流量被用于傳送命令和狀態信息。
通常,無線傳感器網絡是一種新的技術領域。操作環境以及應用要求可能變得更加緊湊和精致,但還存在一些后續的問題,如動態編程和代碼更換之間的平衡,另外還有代碼的執行效率與其他諸多因素的平衡。
????表3.1和表3.2提供了本章提出的4個操作系統的功能和非功能方面的摘要。
?
3.2當前操作系統非功能方面的比較
操作系統
|
小系統開銷
|
關注分離
|
動態重編程
|
可移植性
|
? TinyOs
|
? 332字節
|
操作系統和應用程序之間沒有明顯的區別,在編譯過程中,一個特定的配置生成了一個單片的可執行代碼
|
? 要求軟件支持
|
高 ?
|
? SOS
|
? Ca.116字節
|
可替代模塊被編譯生成一個可執行代碼,這在操作系統和應用程序之間沒有明顯的區別
|
? 支持
|
? 中等到低
|
? Contiki
|
? Ca.810字節
|
模塊被編譯生成一個可重編程和可執行的代碼,但這并不是應用程序和操作系統的分離
|
? 支持 ?
|
? 中等 ?
|
? LiteOS
|
? 不可用
|
應用程序被分割成若干實體:它們是獨立于操作系統開發的
|
? 支持
|
低 ?
|