多优先级任务
文章目錄
- 1 多優先級任務
- 1.1 設計目標
- 1.2 優先級原理
- 1.3 設計實現
1 多優先級任務
1.1 設計目標
問題引入:
- 任務數量無限,而資源有限。當多個任務在等待同一資源/事件時,如果資源/事件不能在任務間共享,應該有哪個任務來處理?
1.2 優先級原理
在此我們只討論CPU占用的優先級:
- RTOS維護一個就緒表,每個表項對應一個任務,對應一種優先級。就緒表指明哪些優先級的任務等待占用CPU運行。
- 為便于快速找到優先級更高的任務運行,使用了就緒位置標記就緒,快速查找。
1.3 設計實現
添加優先級字段:
添加優先級位圖表:
添加獲取當前最高優先級任務的函數:
修改任務初始化函數:
/********************************************************************************************************** ** Function name : tTaskInit ** Descriptions : 初始化任務結構 ** parameters : task 要初始化的任務結構 ** parameters : entry 任務的入口函數 ** parameters : param 傳遞給任務的運行參數 ** Returned value : 無 ***********************************************************************************************************/ void tTaskInit (tTask * task, void (*entry)(void *), void *param, uint32_t prio, uint32_t * stack) {// 為了簡化代碼,tinyOS無論是在啟動時切換至第一個任務,還是在運行過程中在不同間任務切換// 所執行的操作都是先保存當前任務的運行環境參數(CPU寄存器值)的堆棧中(如果已經運行運行起來的話),然后再// 取出從下一個任務的堆棧中取出之前的運行環境參數,然后恢復到CPU寄存器// 對于切換至之前從沒有運行過的任務,我們為它配置一個“虛假的”保存現場,然后使用該現場恢復。// 注意以下兩點:// 1、不需要用到的寄存器,直接填了寄存器號,方便在IDE調試時查看效果;// 2、順序不能變,要結合PendSV_Handler以及CPU對異常的處理流程來理解*(--stack) = (unsigned long)(1<<24); // XPSR, 設置了Thumb模式,恢復到Thumb狀態而非ARM狀態運行*(--stack) = (unsigned long)entry; // 程序的入口地址*(--stack) = (unsigned long)0x14; // R14(LR), 任務不會通過return xxx結束自己,所以未用*(--stack) = (unsigned long)0x12; // R12, 未用*(--stack) = (unsigned long)0x3; // R3, 未用*(--stack) = (unsigned long)0x2; // R2, 未用*(--stack) = (unsigned long)0x1; // R1, 未用*(--stack) = (unsigned long)param; // R0 = param, 傳給任務的入口函數*(--stack) = (unsigned long)0x11; // R11, 未用*(--stack) = (unsigned long)0x10; // R10, 未用*(--stack) = (unsigned long)0x9; // R9, 未用*(--stack) = (unsigned long)0x8; // R8, 未用*(--stack) = (unsigned long)0x7; // R7, 未用*(--stack) = (unsigned long)0x6; // R6, 未用*(--stack) = (unsigned long)0x5; // R5, 未用*(--stack) = (unsigned long)0x4; // R4, 未用task->stack = stack; // 保存最終的值task->delayTicks = 0;task->prio = prio; // 設置任務的優先級taskTable[prio] = task; // 填入任務優先級表tBitmapSet(&taskPrioBitmap, prio); // 標記優先級位置中的相應位 }修改tTaskDelay函數:
/********************************************************************************************************** ** Function name : tTaskDelay ** Descriptions : 使當前任務進入延時狀態。 ** parameters : delay 延時多少個ticks ** Returned value : 無 ***********************************************************************************************************/ void tTaskDelay (uint32_t delay) {// 配置好當前要延時的ticks數uint32_t status = tTaskEnterCritical();currentTask->delayTicks = delay;tBitmapClear(&taskPrioBitmap, currentTask->prio);tTaskExitCritical(status);// 然后進行任務切換,切換至另一個任務,或者空閑任務// delayTikcs會在時鐘中斷中自動減1.當減至0時,會切換回來繼續運行。tTaskSched(); }修改tTaskSystemTickHandler函數:
/********************************************************************************************************** ** Function name : tTaskSystemTickHandler ** Descriptions : 系統時鐘節拍處理。 ** parameters : 無 ** Returned value : 無 ***********************************************************************************************************/ void tTaskSystemTickHandler () {// 檢查所有任務的delayTicks數,如果不0的話,減1。int i; uint32_t status = tTaskEnterCritical();for (i = 0; i < TINYOS_PRO_COUNT; i++) {if (taskTable[i]->delayTicks > 0){taskTable[i]->delayTicks--;}else {tBitmapSet(&taskPrioBitmap, i);}}tTaskExitCritical(status);// 這個過程中可能有任務延時完畢(delayTicks = 0),進行一次調度。tTaskSched(); }修改調度算法:
/********************************************************************************************************** ** Function name : tTaskSched ** Descriptions : 任務調度接口。tinyOS通過它來選擇下一個具體的任務,然后切換至該任務運行。 ** parameters : 無 ** Returned value : 無 ***********************************************************************************************************/ void tTaskSched (void) { tTask * tempTask;// 進入臨界區,以保護在整個任務調度與切換期間,不會因為發生中斷導致currentTask和nextTask可能更改uint32_t status = tTaskEnterCritical();// 如何調度器已經被上鎖,則不進行調度,直接退bmif (schedLockCount > 0) {tTaskExitCritical(status);return;}// 找到優先級最高的任務,如果其優先級比當前任務的還高,那么就切換到這個任務tempTask = tTaskHighestReady();if (tempTask != currentTask) {nextTask = tempTask;tTaskSwitch(); }// 退出臨界區tTaskExitCritical(status); }參考資料:
總結
- 上一篇: 一加哈苏合作 建立四大影像研发中心
- 下一篇: Qt中的QMap和QHash