本文和大家分享的主要是ucos
任務(wù)調(diào)度機制相關(guān)內(nèi)容,一起來看看吧,希望對大家
學(xué)習(xí)ucos有所幫助。
一個操作系統(tǒng)內(nèi)核提供的最核心的功能就是任務(wù)的調(diào)度機制,操作系統(tǒng)的內(nèi)核調(diào)度機制有大體有兩種,一種是時間片輪番調(diào)度,就是將一個系統(tǒng)周期分為好幾段,第一段時間執(zhí)行第一個任務(wù),第二段時間執(zhí)行第二個任務(wù)....
每一段時間都執(zhí)行相應(yīng)的任務(wù)。一種就是搶占式實時內(nèi)核,即優(yōu)先級最高的任務(wù)優(yōu)先運行,不論什么時候,只要就緒的任務(wù)中有比當(dāng)前正在執(zhí)行的任務(wù)優(yōu)先級更高的任務(wù),就暫停當(dāng)前的任務(wù)去執(zhí)行優(yōu)先級最高的任務(wù)。
UCOS_II
就是搶占式的實時內(nèi)核。
UCOS
中跟任務(wù)調(diào)度相關(guān)的變量如下:
OS_EXT INT8U OSRdyGrp;
OS_EXT INT8U OSRdyTbl[64];
UCOS
一共支持
64
個任務(wù),任務(wù)的優(yōu)先級的書越低優(yōu)先級越高。我們將
64
個任務(wù)分為
8
組,每組
8
個優(yōu)先級。
優(yōu)先級 0 ->7
為優(yōu)先級組
0
優(yōu)先級 8 ->15
為優(yōu)先級組
1
優(yōu)先級 16->23
為優(yōu)先級組
2
優(yōu)先級 24 ->31
為優(yōu)先級組
3
優(yōu)先級 32 ->39
為優(yōu)先級組
4
優(yōu)先級 40->47
為優(yōu)先級組
5
優(yōu)先級 48 ->55
為優(yōu)先級組
6
優(yōu)先級 56->63
為優(yōu)先級組
7
OSRdyGrp
是
INT8U
類型的,
OSRdyGrp
中的每一位代表每一組中是否有任務(wù)進入了就緒態(tài)。
如果第0
組任何一個任務(wù)進入就緒態(tài)
-------->OSRdyGrp |= 00000001;
如果第1
組任何一個任務(wù)進入就緒態(tài)
-------->OSRdyGrp |= 00000010;
如果第2
組任何一個任務(wù)進入就緒態(tài)
-------->OSRdyGrp |= 00000100;
如果第3
組任何一個任務(wù)進入就緒態(tài)
-------->OSRdyGrp |= 00001000;
如果第4
組任何一個任務(wù)進入就緒態(tài)
-------->OSRdyGrp |= 00010000;
如果第5
組任何一個任務(wù)進入就緒態(tài)
-------->OSRdyGrp |= 00100000;
如果第6
組任何一個任務(wù)進入就緒態(tài)
-------->OSRdyGrp |= 01000000;
如果第7
組任何一個任務(wù)進入就緒態(tài)
-------->OSRdyGrp |= 10000000;
總結(jié)規(guī)律即: OSRdyGrp |= 1<<(
組
);
OSRdyTbl[8]
是一個數(shù)組,
OSRdyTbl[n]
中的每一位代表第
n
組中的第幾個任務(wù)進入了就緒態(tài)。
如果第0
組的第一個任務(wù)進入了就緒態(tài)
-------> OSRdyTbl[0] |= 00000001
如果第0
組的第七個任務(wù)進入了就緒態(tài)
-------> OSRdyTbl[0] |= 10000000
如果第2
組的第三個任務(wù)進入了就緒態(tài)
-------> OSRdyTbl[2] |= 00001000
如果第7
組的第六個任務(wù)進入了就緒態(tài)
-------> OSRdyTbl[7] |= 01000000
即 OSRdyTbl[
組
] |=1<< (
任務(wù)的優(yōu)先級
&0X07)
這里難懂的原因就是數(shù)組的下表是0->7,
所以
prio/8
得到的優(yōu)先級組的范圍是
0->7,
但是一個對INT8U
進行逐位操作的時候卻是第一位到第八位,要進行轉(zhuǎn)換所以使這里比較難懂
所以使一個任務(wù)進入就緒態(tài)的過程為(prio
為任務(wù)的優(yōu)先級
)
:
x = piro & 0X07; //
任務(wù)在優(yōu)先級組中的位置
0----->7
y = p >> 3 ; //
任務(wù)所處的優(yōu)先級組
0----->7
bitX = 1<<x;
bitY = 1<<y;
OSRdyGrp |= bitY; //
相應(yīng)的優(yōu)先級組的位置
1
OSRdyTbl[y] |= bitX; //
把相應(yīng)的優(yōu)先機組中相應(yīng)的位置
1
以優(yōu)先級22
的任務(wù)為例:
x = 22 & 0X07 = 6;
y = 22 >>3 = 2;
bitX = 1<<6; //01000000
bitY = 1<<2; //00000100
OSRdyGrp |= 00000100 ; //
第
2
個優(yōu)先級組中有任務(wù)處于就緒態(tài)
OSRdyTbl[2] |= 01000000; //
第
2
個優(yōu)先級組中第
7
個任務(wù)處于就緒態(tài)
與上面相反,使一個任務(wù)脫離就緒態(tài)的過程如下:
OSRdyTbl[y] &= ~bixX;
if(OSRdyTbl[y]==0)
{
OSRdyGrp &= ~bitY;
}
OSRdyGrp
一共有
8
位,所以一共有
256
中組合,假定
OSRdyGrp = 11011000
,此時的
OSRdyGrp
代表的意思是:優(yōu)先級組
3,4,6,7
中都有任務(wù)進入就緒態(tài)了。因為我們只需要處理優(yōu)先級最高的任務(wù),所以我們只管
OSRdyGrp
中第一個二進制位
1
所在的位置,即當(dāng)前最高優(yōu)先級任務(wù)在第
3
組中。我們把這
256
中情況都做這樣的處理構(gòu)建出這樣一個表,直接查表即可的出當(dāng)前最高優(yōu)先級任務(wù)所在的組。
INT8U
const OSUnMapTbl[256] = {
0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x00 to 0x0F */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x10 to 0x1F */
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x20 to 0x2F */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x30 to 0x3F */
6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x40 to 0x4F */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x50 to 0x5F */
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x60 to 0x6F */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x70 to 0x7F */
7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x80 to 0x8F */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x90 to 0x9F */
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xA0 to 0xAF */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xB0 to 0xBF */
6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xC0 to 0xCF */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xD0 to 0xDF */
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xE0 to 0xEF */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 /* 0xF0 to 0xFF */
};
先查出最高優(yōu)先級任務(wù)所在的組,然后再查出改組中優(yōu)先級最高的任務(wù)(最先出現(xiàn)1
的二進制位),即可得出最高優(yōu)先級任務(wù)的優(yōu)先級:
y = OSUnMapTbl[OSRdyGrp]; //
得到最高優(yōu)先級任務(wù)所在的組
x = OSUnMapTbl[OSRdyTbl[y]]; //
該組中優(yōu)先級最高的位
prio = y<<3 + x; //
最高優(yōu)先級
跟任務(wù)調(diào)度相關(guān)的函數(shù)都在os_core.c
文件中調(diào)度的具體函數(shù)如下:
該函數(shù)的功能是找出就緒表中優(yōu)先級最高的任務(wù)
void OS_Sched (void)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0; //
為
CPU
狀態(tài)寄存器分配空間
#endif
OS_ENTER_CRITICAL();
if (OSIntNesting == 0) //
中斷服務(wù)程序中不能調(diào)度
{
if (OSLockNesting == 0) //
調(diào)度器上鎖時不能進行調(diào)度
{
OS_SchedNew(); //
找出就緒表中優(yōu)先級最高的任務(wù)
if (OSPrioHighRdy != OSPrioCur) //
最高優(yōu)先級任務(wù)不是當(dāng)前任務(wù)時才進行調(diào)度
{
OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
#if OS_TASK_PROFILE_EN > 0
OSTCBHighRdy->OSTCBCtxSwCtr++; //
統(tǒng)計該任務(wù)切換次數(shù)
#endif
OSCtxSwCtr++; //
統(tǒng)計系統(tǒng)所有任務(wù)切換次數(shù)
OS_TASK_SW(); //
執(zhí)行任務(wù)切換
}
}
}
OS_EXIT_CRITICAL();
}
來源:csdn