《VxWorks7編程指南》筆記(二)——多任務

目錄

 

1.任務與多任務

2.VxWorks系統任務

3.任務擁有權與繼承屬性

4.任務狀態和轉換

5.任務調度

6.任務創建與激活

7.任務名稱與ID

8.任務選項

9.任務棧

10.任務信息

11.任務執行控制

12.任務調度控制

13.任務刪除及刪除保護

14.任務擴展:使用鉤子函數

15.任務錯誤狀態:errno

16.任務異常處理

17.共享代碼與重入

18.內核任務環境變量


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的環境變量功能。具體函數結果如下:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章