久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 24401|回復(fù): 0
收起左側(cè)

uC/OS-II學(xué)習(xí)筆記—任務(wù)的調(diào)度和多任務(wù)的啟動(dòng)

[復(fù)制鏈接]
ID:51773 發(fā)表于 2013-7-19 01:56 | 顯示全部樓層 |閱讀模式
  uC/OS-II操作系統(tǒng)是實(shí)時(shí)操作系統(tǒng),而且是基于優(yōu)先級(jí)調(diào)度的實(shí)時(shí)操作系統(tǒng),因此在啟動(dòng)多任務(wù)以后,每個(gè)時(shí)鐘中斷都要執(zhí)行任務(wù)的調(diào)度。至于如何實(shí)現(xiàn)時(shí)鐘中斷,對(duì)于不同硬件環(huán)境是不同的。如果時(shí)間片是20ms,那么每20ms執(zhí)行一次任務(wù)調(diào)度。這個(gè)任務(wù)調(diào)度的函數(shù)就是OSTimeTick。OSTimeTick是與硬件無(wú)關(guān)的,代碼如下所示:

001642hpw9c0pd9bpizbpp.png

001643b4v4649474mk4nj9.png
001644qw8w5w1dppf1kfp8.png

從操作系統(tǒng)的初始化函數(shù)OSInit來(lái)看,我們創(chuàng)建的第一個(gè)任務(wù)是空閑任務(wù)。然后每次創(chuàng)建的新任務(wù)都是將該任務(wù)的TCB插入到就緒鏈表的表頭,而空閑任務(wù)不允許被刪除。因此,在就緒鏈表中,最后一個(gè)TCB永遠(yuǎn)是空閑任務(wù)的。所以,while循環(huán)從就緒鏈表的表頭開(kāi)始,一直到空閑任務(wù)為止,遍歷了除空閑任務(wù)之外的所有任務(wù)。
OSTCBStat中的各個(gè)位的意義如下所示:
001645efbkq7kfdkef6dfr.png

在這里,看到了我們熟悉的掛起,在從低到高的第4位,如果從0位開(kāi)始算,是位3。
相關(guān)的宏定義如下所示:

001645bbdehboobicd4w3l.png
因此

001646gczvrnv5rtcubqqs.png
很明顯,只要任務(wù)在等待任何一個(gè)事件發(fā)生,那么OS_STAT_PEND_ANY的值都不會(huì)是OS_STAT_RDY。因此,這個(gè)條件判斷語(yǔ)句的含義就是,如果任務(wù)在等待任何一個(gè)事件的發(fā)生(信號(hào)量、郵箱、隊(duì)列、互斥信號(hào)量、標(biāo)志),就執(zhí)行下面的操作,判斷是否延遲結(jié)束等。 任務(wù)可能因?yàn)榈却录幱谧枞麘B(tài),但是阻塞態(tài)的任務(wù)的控制塊仍然在就緒鏈表中,而并非由一個(gè)阻塞鏈表。任務(wù)等待事件發(fā)生的時(shí)候,可以設(shè)定或不設(shè)定超時(shí)時(shí)間。如果設(shè)定了超時(shí)時(shí)間,那么時(shí)間到了就算事件仍沒(méi)有發(fā)生,也不再等待了,這樣可以避免死等。
因此,結(jié)合帶啊,調(diào)度器遍歷每個(gè)任務(wù),如果任務(wù)被設(shè)置了時(shí)間延時(shí),那么就將延時(shí)時(shí)間減1.不論是等待事件發(fā)生的任務(wù),還是單純等待一段時(shí)間的任務(wù),只要不是被掛起的任務(wù),延時(shí)時(shí)間到了就要使任務(wù)進(jìn)入就緒態(tài)。使任務(wù)進(jìn)入就緒態(tài)的方法也就是就緒組和就緒表的操作。
OSTimeTick在每個(gè)時(shí)間片開(kāi)始的時(shí)候有規(guī)律地被操作系統(tǒng)調(diào)用,將對(duì)延時(shí)的任務(wù)修改延時(shí)時(shí)間,然后設(shè)置哪些任務(wù)就緒,但是還沒(méi)有真正進(jìn)入任務(wù)的切換。
就緒的任務(wù)獲得CPU才能運(yùn)行。任務(wù)切換函數(shù)就是執(zhí)行這樣的操作系統(tǒng)服務(wù)功能:如果正在運(yùn)行的任務(wù)不是優(yōu)先級(jí)最高的或即將被阻塞,需要選擇一個(gè)優(yōu)先級(jí)最高的就緒的任務(wù)運(yùn)行。該過(guò)程中非常重要的一點(diǎn)是,要保留正在運(yùn)行的上下文,也就是運(yùn)行環(huán)境,如cPU寄存器的值,以便在任務(wù)重新開(kāi)始運(yùn)行之前能恢復(fù)CPU寄存器的值。當(dāng)然還要將要運(yùn)行任務(wù)的上下文恢復(fù)到CPU寄存器。
因此,任務(wù)切換函數(shù)式設(shè)計(jì)硬件操作,是和CPU類型密切相關(guān)的,因此對(duì)不同的系統(tǒng),實(shí)現(xiàn)的代碼必然不同。任務(wù)切換函數(shù)是OS_Sched,在OS_Sched中還要調(diào)用與CPU無(wú)關(guān)的函數(shù)OS_SchedNew和與CPU密切相關(guān)的代碼OS_TASK_SW。OS_Sched與OS_SchedNew寫(xiě)在os_core.c中,與CPU密切相關(guān)的代碼OS_TASK_SW則寫(xiě)在os_cpu.c中。
首先來(lái)看一下OS_SchedNew,這個(gè)函數(shù)被其他uC/OS-II系統(tǒng)服務(wù)調(diào)用,用來(lái)確定最高優(yōu)先級(jí)的就緒任務(wù)。該函數(shù)運(yùn)行的結(jié)果就是給全局變量OSPrioHighRdy賦值。顯然,OSPrioHighRdy是最高的優(yōu)先級(jí)任務(wù)。
代碼如下所示:
001647gvivvzjgksekk2k1.png
代碼很簡(jiǎn)單,找到優(yōu)先級(jí)最高的就緒任務(wù),將該任務(wù)的優(yōu)先級(jí)賦值給OSPrioHighRdy。
在OS_Sched代碼中將調(diào)用OS_SchedNew來(lái)找到最高優(yōu)先級(jí)的任務(wù)。
代碼如下所示:

001648r5uzgupf0c4my49a.png
可見(jiàn),OS_Sched首先判斷是否可以進(jìn)行任務(wù)切換,如果中斷服務(wù)程序沒(méi)有完成,或者是調(diào)度器被上鎖,或當(dāng)前運(yùn)行的任務(wù)正是優(yōu)先級(jí)最高的,那么都不會(huì)進(jìn)行任務(wù)切換。當(dāng)需要進(jìn)行任務(wù)切換時(shí),OS_Sched首先增加將要被換入CPU的任務(wù)的被調(diào)用次數(shù)OSTCBCtxSwCtr,然后是整個(gè)操作系統(tǒng)的任務(wù)切換的次數(shù)OSCtxSwCtr。最后調(diào)用OS_TASK_SW完成任務(wù)切換。從中可以看出,OS_TASK_SW應(yīng)該是真正進(jìn)行任務(wù)切換的地方。
一切都準(zhǔn)備好了,將進(jìn)行任務(wù)的最終切換,OS_TASK_SW首先將CPU寄存器中的內(nèi)容壓入被換出的任務(wù)的堆棧中,然后將被換入的任務(wù)的堆棧中的內(nèi)容彈出到CPU寄存器。需要知道的是,這些寄存器是任務(wù)運(yùn)行的環(huán)境,在任務(wù)被換出,再換回繼續(xù)執(zhí)行的時(shí)候,寄存器的值不能發(fā)生變化,否則程序的運(yùn)行會(huì)產(chǎn)生錯(cuò)誤的結(jié)果,有些結(jié)果甚至是災(zāi)難性的。
OS_TASK_SW的代碼實(shí)現(xiàn)如下所示:

001649ykq3i0tq0k96hhet.png
可以看到OS_TASK_SW()等同于OSCtxSw()。OSCtxSw的定義如下所示:

001829zi82i2pnioorpzpt.png
可以看出這是一段匯編代碼,執(zhí)行的主要操作是觸發(fā)PendSV中斷,那接下來(lái)看一下PendSV中斷的服務(wù)程序:

001831g22jjj3i729uffcz.png
PendSV中首先關(guān)閉中斷,然后判斷PSP的值是不是0,如不是0就將沒(méi)有自動(dòng)保存的寄存器r4~r11壓入到堆棧中,然后將PSP的值更新到OSTCBCur->OSTCBStkPtr中。如果是0就說(shuō)明之前沒(méi)有任務(wù)運(yùn)行,所以不要保存。然后調(diào)用OSTaskSwHook()。然后執(zhí)行OSPrioCur = OSPrioHighRdy;然后執(zhí)行OSTCBCur  = OSTCBHighRdy; 然后取得最高優(yōu)先級(jí)任務(wù)的TCB,進(jìn)而得到它的堆棧地址。然后把R4~R11的值從堆棧中恢復(fù)。然后,更新PSP的值。然后將LR的bit3置位,然后使能中斷,最后中斷返回。
uC/OS-II作為實(shí)時(shí)多任務(wù)操作系統(tǒng),在每個(gè)時(shí)鐘滴答進(jìn)入時(shí)鐘中斷服務(wù)程序,如果有比目前運(yùn)行的任務(wù)更高優(yōu)先級(jí)的任務(wù)就緒,在需要的時(shí)候進(jìn)行一次任務(wù)調(diào)度。這個(gè)任務(wù)調(diào)度函數(shù)并不是前面的OS_Sched,而是OSIntExit。
在時(shí)鐘中斷的時(shí)候,緊接著OSTimeTick,操作系統(tǒng)調(diào)用OSIntExit實(shí)現(xiàn)任務(wù)的切換,程序如下所示:

001832hauuy9lt55507y0y.png
可見(jiàn),OSIntCtxSw()才是真正在中斷程序中進(jìn)行實(shí)際的任務(wù)切換的地方,OSIntExit與OSSched類似,進(jìn)行了全局變量的配置,決定是否進(jìn)行任務(wù)切換。那么OSIntCtxSw很明顯也將在os_cpu.c中實(shí)現(xiàn),原因是也要進(jìn)行與CPU密切相關(guān)的操作,相關(guān)程序如下所示:

001833eftiwnavpf7akt8s.png
可見(jiàn),在中斷處理過(guò)程中的任務(wù)切換和普通的任務(wù)切換時(shí)相同的。
多任務(wù)啟動(dòng)的代碼是內(nèi)核中的OSStart函數(shù),在運(yùn)行OSStart之前,必須已經(jīng)執(zhí)行了操作系統(tǒng)初始化函數(shù)OSInit,并且至少創(chuàng)建了1個(gè)以上的任務(wù)。OSStart的代碼如下所示:

001834jbhh8b0891x6yi6b.png
可見(jiàn),OSStart先找到優(yōu)先級(jí)最高的就緒任務(wù),然后對(duì)OSPrioCur賦值為該任務(wù)的優(yōu)先級(jí),將OSTCBHighRdy及OSTCBCur賦值為該任務(wù)的TCB地址,之后就調(diào)用OSStartHighRdy來(lái)啟動(dòng)多任務(wù)。因此,核心的代碼還在OSStartHighRdy。OSStartHighRdy啟動(dòng)多任務(wù)又是和硬件有關(guān)的,因此該代碼在os_cpu.c中,對(duì)于不同的硬件平臺(tái),該代碼必然不同。

001836q3l7yyl0fd0l5vk5.png
匯編的代碼和恢復(fù)任務(wù)的時(shí)候如初一輒,從堆棧中取出任務(wù)的地址運(yùn)行任務(wù)!而任務(wù)的地址在創(chuàng)建任務(wù)時(shí)的堆棧初始化的時(shí)候已經(jīng)準(zhǔn)備好了。啟動(dòng)任務(wù)就是先將設(shè)置PendSV,然后將PSP清零,然后將OSRunning設(shè)置為真表示進(jìn)入多任務(wù),然后觸發(fā)PendSV,然后由PendSV中斷服務(wù)程序來(lái)執(zhí)行相關(guān)的任務(wù)切換。

回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 一级片在线观看视频 | 国产一区二区三区久久久久久久久 | 一级黄色绿像片 | 亚洲嫩草| 羞羞涩涩在线观看 | 国产你懂的在线观看 | 国产一区| 青青久久 | 欧美中文字幕在线观看 | 国产精品久久久久永久免费观看 | 免费亚洲视频 | 日韩精品一区二区三区在线观看 | 九九导航 | 在线免费观看欧美 | 久久精品91久久久久久再现 | 男女黄网站 | 最新国产精品视频 | 国产成人精品一区二区三区网站观看 | 女人一区 | 一本久久a久久精品亚洲 | 精品国产乱码久久久久久蜜柚 | 成人欧美一区二区三区在线播放 | 日韩在线第一 | 国产精品一区二区三区久久 | 人人干人人草 | 欧美一区二区三区电影 | 国产成人精品久久二区二区 | 久久久久国产一区二区三区 | 欧美激情久久久 | 一区二区视频免费观看 | 99精品一区二区三区 | 亚洲综合色 | 亚洲精品片 | 久久一二 | 欧美九九 | 亚洲精品一区二区三区在线 | 久久精点视频 | 欧美日韩电影一区二区 | 99精品视频在线 | 成人久久18免费网站 | 久久精品色欧美aⅴ一区二区 |