【STM32F429】第12章 ThreadX任務優先順序修改及其分配方案
論壇原始地址(持續更新):http://www.armbbs.cn/forum.php?mod=viewthread&tid=99514
第12章 ThreadX任務優先順序修改及其分配方案
本章節主要為大家講解ThreadX任務優先順序設定的注意事項、任務優先順序的分配方案及其相關的一個例子,內容相對比較簡單。
12.1 任務優先順序說明
12.2 任務優先順序分配方案
12.3 中斷優先順序和任務優先順序的區別
12.4 任務優先順序修改函式tx_thread_priority_change
12.5 任務優先順序獲取函式tx_thread_info_get
12.6 實驗例程說明
12.7 總結
12.1 任務優先順序說明
下面對ThreadX優先順序相關的幾個重要知識點進行下說明,這些知識點在以後的使用中務必要掌握牢固。
1、 ThreadX中任務的最大優先順序數值是通過tx_port.h檔案中的TX_MAX_PRIORITIES進行配置的,使用者實際可以使用的優先順序範圍是0到configMAX_PRIORITIES – 1。比如我們配置此巨集定義為32,那麼使用者可以使用的優先順序號是0到31,不包含32,對於這一點,初學者要特別的注意。並且TX_MAX_PRIORITIES的巨集定義設定的數值必須是32的整數倍:
#define TX_MAX_PRIORITIES 32
2、 使用者配置任務的優先順序數值越小,那麼此任務的優先順序越低(0是最高優先順序任務),ThreadX沒有空閒任務,如果大家建立空閒任務,需要將其設定為最低優先順序。
3、 建議使用者配置巨集定義TX_MAX_PRIORITIES的最大值不要超過32,即使用者任務可以使用的優先順序範圍是0到31。
- 因為對於CM核心的移植檔案,有專用的彙編指令CLZ(Count Leading Zeros),通過這些指令可以加速演算法執行速度。
- 比通用方式高效。
- ThreadX查詢最高優先順序任務是通過定義的32bit陣列,ULONG _tx_thread_preempted_maps[TX_MAX_PRIORITIES/32];
如果TX_MAX_PRIORITIES設定為32,那麼僅需一個32bit變數就可以方便記錄32不同優先順序任務,程式執行時查詢最高優先順序任務也方便。
4、 ThreadX中處於執行狀態的任務永遠是當前能夠執行的最高優先順序任務。下一章節講解排程器,大家會對這個知識點有一個全面的認識。
12.2 任務優先順序分配方案
對於初學者,有時候會糾結任務優先順序設定為多少合適,因為任務優先順序設定多少是沒有標準的。對於這個問題,我們這裡為大家推薦一個標準,任務優先順序設定推薦方式如下圖所示:
- IRQ任務:IRQ任務是指通過中斷服務程式進行觸發的任務,此類任務應該設定為所有任務裡面優先順序最高的。
- 高優先順序後臺任務:比如按鍵檢測,觸控檢測,USB訊息處理,串列埠訊息處理等,都可以歸為這一類任務。
- 低優先順序的時間片排程任務:比如GUI的介面顯示,LED數碼管的顯示等不需要實時執行的都可以歸為這一類任務。實際應用中使用者不必拘泥於將這些任務都設定為優先順序1的同優先順序任務,可以設定多個優先順序,只需注意這類任務不需要高實時性。
- 空閒任務:空閒任務是系統任務。
- 特別注意:IRQ任務和高優先順序任務必須設定為阻塞式(呼叫訊息等待或者延遲等函式即可),只有這樣,高優先順序任務才會釋放CPU的使用權,,從而低優先順序任務才有機會得到執行。
這裡的優先順序分配方案是我們推薦的一種方式,實際專案也可以不採用這種方法。調試出適合專案需求的才是最好的。
12.3 中斷優先順序和任務優先順序區別
部分初學者也容易在這兩個概念上面出現問題。簡單的說,這兩個之間沒有任何關係,不管中斷的優先順序是多少,中斷的優先順序永遠高於任何任務的優先順序,即任務在執行的過程中,中斷來了就開始執行中斷服務程式。
另外對於STM32來說,中斷優先順序的數值越小,優先順序越高。同樣,ThreadX的任務優先順序也是任務優先順序數值越小,任務優先順序越高。
12.4 任務優先順序修改函式tx_thread_priority_change
函式原型:
UINT tx_thread_priority_change( TX_THREAD *thread_ptr, UINT new_priority, UINT *old_priority);
函式描述:
函式tx_thread_priority_change用於實現ThreadX任務優先順序的修改。
- 第1個引數thread_ptr是任務控制代碼,用於區分不同的任務。
- 第2個引數new_priority是新任務優先順序(0 至 (TX_MAX_PRIORITIES-1))。0表示最高優先順序。
- 第3個引數old_priority是任務之前的優先順序。
注意事項:
- 允許在任務和定時器組裡面呼叫。
- 指定任務的搶佔閾值自動設定為新的優先順序。如果需要新的閾值,則必須在此呼叫之後使用函式tx_thread_preemption_change。
- 第二個引數數值不可大於等於tx_port.h檔案中的巨集定義:#define TX_MAX_PRIORITIES 配置的數值。
使用舉例:
TX_THREAD AppTaskUserIFTCB; UINT OldPriority; /*優先順序將其設定為6 */ tx_thread_priority_change(&AppTaskUserIFTCB, 6, &OldPriority);
12.5 任務優先順序獲取函式tx_thread_info_get
函式原型:
UINT tx_thread_info_get( TX_THREAD *thread_ptr, CHAR **name, UINT *state, ULONG *run_count, UINT *priority, UINT *preemption_threshold, ULONG *time_slice, TX_THREAD **next_thread, TX_THREAD **suspended_thread);
函式描述:
函式tx_thread_info_get不僅僅可用於獲取ThreadX任務優先順序。還可以獲取其它相關資訊。
1、 第1個引數thread_ptr是任務控制代碼,用於區分不同的任務。
2、 第2個引數name用於獲取任務名。
3、 第3個引數state用於獲取任務狀態,可能的值如下所示。
- TX_READY (0x00)
- TX_COMPLETED (0x01)
- TX_TERMINATED (0x02)
- TX_SUSPENDED (0x03)
- TX_SLEEP (0x04)
- TX_QUEUE_SUSP (0x05)
- TX_SEMAPHORE_SUSP (0x06)
- TX_EVENT_FLAG (0x07)
- TX_BLOCK_MEMORY (0x08)
- TX_BYTE_MEMORY (0x09)
- TX_MUTEX_SUSP (0x0D)
4、 第4個引數run_count用於獲取任務執行計數。
5、 第5個引數priority用於獲取任務優先順序。
6、 第6個引數preemption_threshold用於獲取搶佔閥值。
7、 第7個引數time_slice用於獲取時間片。
8、 第8個引數next_thread指向下一個建立的任務控制代碼。
9、 第9個引數suspended_thread指向掛起列表中下一個任務控制代碼。
10、 返回值
- TX_SUCCESS:(0X00) 成功檢索任務資訊。
- TX_THREAD_ERROR:(0x0E) 任務控制指標無效。
注意事項:
- 可以在初始化階段,任務,定時器組和中斷服務程式裡面呼叫。
使用舉例:
TX_THREAD AppTaskUserIFTCB; CHAR *name; UINT state; ULONG run_count; UINT priority; UINT preemption_threshold; UINT time_slice; TX_THREAD *next_thread; TX_THREAD *suspended_thread; UINT status; status = tx_thread_info_get(&AppTaskUserIFTCB, &name, &state, &run_count, &priority, &preemption_threshold, &time_slice, &next_thread, &suspended_thread);
12.6 實驗例程
配套例子:
V6-3007_ThreadX Task Priority Change
實驗目的:
- 學習ThreadX任務優先順序修改。
實驗內容:
1、共建立瞭如下幾個任務,通過按下按鍵K1可以通過串列埠或者RTT列印任務堆疊使用情況
===================================================
OS CPU Usage = 1.94%
=======================================================
Prio StackSize CurStack MaxStack Taskname
2 4092 383 391 App Task Start
3 4092 543 659 App Msp Pro
4 4092 391 391 App Task UserIF
5 4092 543 659 App Task COM
30 1020 519 519 App Task STAT
31 1020 143 71 App Task IDLE
0 1020 391 391 System Timer Thread
串列埠軟體可以使用SecureCRT或者H7-TOOL RTT檢視列印資訊。
App Task Start任務 :啟動任務,這裡用作BSP驅動包處理。
App Task MspPro任務 :訊息處理,這裡未使用。
App Task UserIF任務 :按鍵訊息處理。
App Task COM任務 :這裡用作LED閃爍。
App Task STAT任務 :統計任務
App Task IDLE任務 :空閒任務
System Timer Thread任務:系統定時器任務
2、(1) 凡是用到printf函式的全部通過函式App_Printf實現。
(2) App_Printf函式做了訊號量的互斥操作,解決資源共享問題。
3、預設上電是通過串列埠列印資訊,如果使用RTT列印資訊
(1) MDK AC5,MDK AC6或IAR通過使能bsp.h檔案中的巨集定義為1即可
#define Enable_RTTViewer 1
(2) Embedded Studio繼續使用此巨集定義為0, 因為Embedded Studio僅製作了除錯狀態RTT方式檢視。
實驗操作:
- K1按鍵按下列印任務執行情況,按下K2和K3設定優先順序後,可以按K1檢視任務最新優先順序是否設定成功。
- K2按鍵按下,設定任務App Task UserIF的優先順序為6。
- K3按鍵按下,設定任務App Task UserIF的優先順序為4。
串列埠列印資訊方式(AC5,AC6和IAR):
波特率 115200,資料位 8,奇偶校驗位無,停止位 1
RTT列印資訊方式(AC5,AC6和IAR):
Embedded Studio僅支援除錯狀態RTT列印:
由於Embedded Studio不支援中文,所以中文部分顯示亂碼,不用管。
程式執行框圖:
12.7 總結
本章節內容相對比較容易,重點是學習任務優先順序分配方案,隨著後面的學習,初學者需要慢慢積累這方面的經驗。