目錄
1.任務與多任務
多任務環境允許實時應用程序由一系列獨立的任務構成,這些任務擁有自己的執行與系統資源。
2.VxWorks系統任務
根據具體的配置,VxWorks在啓動時將運行各種系統任務,其中有些任務會一直運行。
VxWorks基礎任務如下:
可選組件任務如下:
3.任務擁有權與繼承屬性
根用戶是所有任務和RTP的默認擁有者。可以使用如下函數了解任務擁有權與繼承屬性:
- getuid()
- getgid()
- setuid()
- setgid()
- taskShow()
- ps -l (用於RTP)
4.任務狀態和轉換
下表描述了在開發工具中課件的任務狀態和狀態符號。需要注意的是,任務狀態是可以累加的,同一時刻一個任務可能處於多個狀態下。
Shell命令行中的任務狀態示例
基本的任務狀態轉換圖示
下圖展示了基本的任務狀態轉換關係。爲了簡化關係,圖中沒有展示上述的疊加狀態,也沒有展示STOP狀態。
注意:taskSpawn()函數將創建一個任務,並使之進入Ready狀態;taskCreate()函數將創建一個任務,並使之進入suspend狀態。
5.任務調度
多任務環境需要任務調度器將CPU分配給處於ready狀態的任務。VxWorks提供了多種調度器選項:
- 傳統VxWorks調度器,提供基於優先級的搶佔調度,具備round-robin擴展;
- VxWorks POSIX線程調度器,用於運行進程中的線程(RTP)
- RTP分時調度器,允許按照時間片調度RTP;
- 自定義調度器框架,允許自定義開發調度器;
任務優先級
任務優先級在創建時指定,任務調度器依賴於優先級進行調度。VxWorks內核提供了256個優先級,最高優先級爲0,最低優先級爲255。
內核應用程序優先級
所有應用程序應該運行在優先級100~255。
注意:網絡應用程序任務的優先級可能需要運行在低於100的優先級下。
驅動程序的任務優先級
驅動任務優先級範圍爲51~99。
任務倒置:將一個內核任務移動到優先級隊列的隊尾
可使用函數taskRotate()實現該功能,結合該函數可以間接實現round-robin機制。
6.任務創建與激活
taskLib庫中提供了創建、控制任務的函數,也提供了獲取任務信息的函數。如下所示:
7.任務名稱與ID
taskLib中提供的任務名稱和ID函數如下所示:
8.任務選項
略
9.任務棧
任務的棧空間是在任務創建時定義的。可以使用guard zone使任務棧不可執行,從而對任務棧進行保護。
想要確切知道一個任務需要多大棧空間是很困難的。爲了避免棧溢出與崩潰,可以在分配任務棧時分配一個比預期大小更大的空間。之後可以使用checkStack()函數或ti()函數週期性地檢查任務棧。當確認了具體的使用情況後,可以調整棧大小以適應測試或系統部署的要求。
任務棧保護
可以使用guard zone通過將任務棧設置爲不可執行,來實現任務棧保護。
任務棧guard zone
通過配置INCLUDE_PROTECT_TASK_STACK組件,可以爲任務使能guard zone保護功能。如果對系統內存要求比較嚴格,後續在進行最終測試或系統部署時可以移除該組件。
在任務執行時,一個對上的guard zone可以確保任務棧不超過其預定義的大小上限,以免搞崩其他數據或任務棧;一個對下的guard zone可以確保對任務棧的訪問不低於其棧底空間,以免於由緩衝區移除導致的內存崩潰。
10.任務信息
任務信息是動態的,除非任務掛起,否則任務信息所反饋的信息可能不是最新的。可以使用如下函數獲取任務信息。
11.任務執行控制
以下函數可用於控制任務的執行狀態:
如果需要將任務延遲半秒,可以使用如下方式:
taskDelay(sysClkRateGet()/2)
其中,sysClkRateGet()函數返回了每秒的系統時鐘數。使用taskDelay(0),可以直接將CPU使用權讓給其他任務,使自己掛起並讓同優先級 的其他任務繼續執行。
12.任務調度控制
可使用如下函數實現任務調度控制。
13.任務刪除及刪除保護
任務可以被動態地刪除,也可以通過保護措施避免被其他任務刪除。具體函數如下:
刪除保護
任務在執行關鍵代碼時,爲了避免被刪除,可以通過增加其刪除保護計數器來實現任務保護。具體方法包括:
- 調用taskSafe();
- 獲取使用了SEM_DELETE_SAFE選項的互斥信號量。
對於使用SEM_DELETE_SAFE選項的信號量,在使用semTake()獲取它時,效果類似於調用taskSafe();在使用semGive()釋放它時,效果類似於調用taskUnsafe()。
當任務執行完關鍵代碼後,爲了允許被其他函數刪除,需要減少其刪除保護計數器。具體方法包括:
- 調用taskUnsafe();
- 釋放具有刪除保護屬性的互斥信號量。
14.任務擴展:使用鉤子函數
VxWorks提供鉤子函數管理API,用於註冊在創建、刪除或任務切換時所需觸發的鉤子函數。具體函數接口如下:
15.任務錯誤狀態:errno
C函數庫中使用了一個全局整型變量errno,用於反饋函數執行錯誤時的具體錯誤碼。此由ANSI C標準中所規定。
注意:當前描述的內容主要針對VxWorks,對於SMP需要另外考慮。
errno的分層定義
在VxWorks內核中,同時使用了兩種方法定義errno:
- ANSI C全局變量errno;
- errno.h中定義的一個宏errno,該宏定義調用一個函數__errno()。該函數返回全局變量errno的地址。使用該方法的好處是:因爲__errno()是一個函數,所以可以在調試時爲其添加斷點,從而確定是否有錯誤發生。
每個任務具有獨立的errno值
爲了在多任務環境下使用errno,VxWorks爲每個任務保留了相應的errno。因此,在每次進行任務切換時,內核將errno作爲任務棧的一部分保存在任務棧中。
16.任務異常處理
信號(signal)可以用於標識軟件或硬件異常。
17.共享代碼與重入
供多個任務執行的一份代碼被稱爲共享代碼,共享代碼必須是可重入的。
18.內核任務環境變量
默認情況下,內核任務共享相同的環境變量。但是如果一個任務在創建時使用了VX_PRIVATE_ENV選項,那麼它就可以擁有私有的環境變量。
envLib環境變量API
envLib庫提供了兼容Unix的環境變量功能。具體函數結果如下: