生活随笔
收集整理的這篇文章主要介紹了
同优先级时间片运行
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
1 同優先級時間片運行
1.1 設計目標
構建一個允許多任務具備相同優先級,且同優先級任務按時間片占用CPU運行的系統。
1.2 設計原理
當前設計:每個優先級只允許一個任務。
新的設計:
1.3 設計實現
配置優先級列表:
任務鏈接結點:
修改獲取最高優先級任務的方式:
時鐘節拍處理:增加時間片輪轉。
主要代碼實現如下:
#include "tinyOS.h"
#include "ARMCM3.h"
tTask
* currentTask
;
tTask
* nextTask
;
tTask
* idleTask
;
tBitmap taskPrioBitmap
;
tList taskTable
[TINYOS_PRO_COUNT
];
uint8_t schedLockCount
;
tList tTaskDelayedList
;
void tTaskInit
(tTask
* task
, void (*entry
)(void *), void *param
, uint32_t prio
, uint32_t
* stack
)
{*(--stack
) = (unsigned long)(1<<24); *(--stack
) = (unsigned long)entry
; *(--stack
) = (unsigned long)0x14; *(--stack
) = (unsigned long)0x12; *(--stack
) = (unsigned long)0x3; *(--stack
) = (unsigned long)0x2; *(--stack
) = (unsigned long)0x1; *(--stack
) = (unsigned long)param
; *(--stack
) = (unsigned long)0x11; *(--stack
) = (unsigned long)0x10; *(--stack
) = (unsigned long)0x9; *(--stack
) = (unsigned long)0x8; *(--stack
) = (unsigned long)0x7; *(--stack
) = (unsigned long)0x6; *(--stack
) = (unsigned long)0x5; *(--stack
) = (unsigned long)0x4; task
->slice
= TINYOS_SLICE_MAX
; task
->stack
= stack
; task
->delayTicks
= 0;task
->prio
= prio
; task
->state
= TINYOS_TASK_STATE_RDY
; tNodeInit(&(task
->delayNode
)); tNodeInit(&(task
->linkNode
)); tListAddLast(&taskTable
[prio
], &(task
->linkNode
)); tBitmapSet(&taskPrioBitmap
, prio
);
}
tTask
* tTaskHighestReady
(void)
{uint32_t highestPrio
= tBitmapGetFirstSet(&taskPrioBitmap
);tNode
* node
= tListFirst(&taskTable
[highestPrio
]);return (tTask
*)tNodeParent(node
, tTask
, linkNode
);
}
void tTaskSchedInit
(void)
{int i
= 0;schedLockCount
= 0;tBitmapInit(&taskPrioBitmap
);for (i
= 0; i
< TINYOS_PRO_COUNT
; i
++){tListInit(&taskTable
[i
]);}
}
void tTaskSchedDisable
(void)
{uint32_t status
= tTaskEnterCritical();if (schedLockCount
< 255) {schedLockCount
++;}tTaskExitCritical(status
);
}
void tTaskSchedEnable
(void)
{uint32_t status
= tTaskEnterCritical();if (schedLockCount
> 0) {if (--schedLockCount
== 0) {tTaskSched(); }}tTaskExitCritical(status
);
}
void tTaskSchedRdy
(tTask
* task
)
{tListAddLast(&taskTable
[task
->prio
], &(task
->linkNode
));tBitmapSet(&taskPrioBitmap
, task
->prio
);
}
void tTaskSchedUnRdy
(tTask
* task
)
{tListRemove(&taskTable
[task
->prio
], &(task
->linkNode
));if (tListCount(&taskTable
[task
->prio
]) == 0){tBitmapClear(&taskPrioBitmap
, task
->prio
);}
}
void tTaskSched
(void)
{ tTask
* tempTask
;uint32_t status
= tTaskEnterCritical();if (schedLockCount
> 0) {tTaskExitCritical(status
);return;}tempTask
= tTaskHighestReady();if (tempTask
!= currentTask
) {nextTask
= tempTask
;tTaskSwitch(); }tTaskExitCritical(status
);
}
void tTaskDelayedInit
(void)
{tListInit(&tTaskDelayedList
);
}
void tTimeTaskWait
(tTask
* task
, uint32_t ticks
)
{task
->delayTicks
= ticks
;tListAddLast(&tTaskDelayedList
, &(task
->delayNode
)); task
->state
|= TINYOS_TASK_STATE_DELAYED
;
}
void tTimeTaskWakeUp
(tTask
* task
)
{tListRemove(&tTaskDelayedList
, &(task
->delayNode
));task
->state
&= ~TINYOS_TASK_STATE_DELAYED
;
}
void tTaskSystemTickHandler
(void)
{tNode
* node
;uint32_t status
= tTaskEnterCritical();for (node
= tTaskDelayedList
.headNode
.nextNode
; node
!= &(tTaskDelayedList
.headNode
); node
= node
->nextNode
){tTask
* task
= tNodeParent(node
, tTask
, delayNode
);if (--task
->delayTicks
== 0) {tTimeTaskWakeUp(task
);tTaskSchedRdy(task
); }}if (--currentTask
->slice
== 0){if (tListCount(&taskTable
[currentTask
->prio
]) > 0){tListRemoveFirst(&taskTable
[currentTask
->prio
]);tListAddLast(&taskTable
[currentTask
->prio
], &(currentTask
->linkNode
));currentTask
->slice
= TINYOS_SLICE_MAX
;}}tTaskExitCritical(status
); tTaskSched();
}
void tTaskDelay
(uint32_t delay
) {uint32_t status
= tTaskEnterCritical();tTimeTaskWait(currentTask
, delay
);tTaskSchedUnRdy(currentTask
);tTaskSched();tTaskExitCritical(status
);
}
void tSetSysTickPeriod(uint32_t ms
)
{SysTick
->LOAD
= ms
* SystemCoreClock
/ 1000 - 1; NVIC_SetPriority
(SysTick_IRQn
, (1<<__NVIC_PRIO_BITS
) - 1);SysTick
->VAL
= 0; SysTick
->CTRL
= SysTick_CTRL_CLKSOURCE_Msk
|SysTick_CTRL_TICKINT_Msk
|SysTick_CTRL_ENABLE_Msk
;
}
void SysTick_Handler
()
{tTaskSystemTickHandler();
}
int task1Flag
;
void task1Entry
(void * param
)
{tSetSysTickPeriod(10);for (;;) {task1Flag
= 1;tTaskDelay(1);task1Flag
= 0;tTaskDelay(1);}
}void delay
()
{int i
;for (i
= 0; i
< 0xFF; i
++) {}
}int task2Flag
;
void task2Entry
(void * param
)
{for (;;) {task2Flag
= 1;delay();task2Flag
= 0;delay();}
}int task3Flag
;
void task3Entry
(void * param
)
{for (;;){task3Flag
= 1;delay();task3Flag
= 0;delay();}
}
tTask tTask1
;
tTask tTask2
;
tTask tTask3
;
tTaskStack task1Env
[1024];
tTaskStack task2Env
[1024];
tTaskStack task3Env
[1024];
tTask tTaskIdle
;
tTaskStack idleTaskEnv
[1024];void idleTaskEntry
(void * param
) {for (;;){}
}int main
()
{tTaskSchedInit();tTaskDelayedInit();tTaskInit(&tTask1
, task1Entry
, (void *)0x11111111, 0, &task1Env
[1024]);tTaskInit(&tTask2
, task2Entry
, (void *)0x22222222, 1, &task2Env
[1024]);tTaskInit(&tTask3
, task3Entry
, (void *)0x33333333, 1, &task3Env
[1024]);tTaskInit(&tTaskIdle
, idleTaskEntry
, (void *)0, TINYOS_PRO_COUNT
- 1, &idleTaskEnv
[1024]);nextTask
= tTaskHighestReady();tTaskRunFirst();return 0;
}
參考資料:
【李述銅】從0到1自己動手寫嵌入式操作系統
總結
以上是生活随笔為你收集整理的同优先级时间片运行的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。