作業系統任務排程的原理(個人總結):
建立兩個任務A、B
任務A的優先級>任務B的優先級(計算機根據任務的優先級大小讓誰先執行)
A運作->任務A運作完->調用void OSTimeDly (INT32U ticks);函數,交出CPU的使用權,作用是讓任務A運作态轉換成等待狀态,引發一次任務排程,任務排程函數void OS_Sched (void);作用是查找處于就緒狀态優先級最高的任務B->進行任務切換OS_TASK_SW();切換到任務B工作->任務B運作完成->B由運作态轉換成等待狀态->計算機查找處于就緒狀态優先級最高的任務->沒有任務待運作->計算機進入到空閑任務(計算機是不能停下來的),前提條件是沒有任務再運作了->這時任務A産生定時時間到,即任務A控制塊裡的ptcb->OSTCBDly減到0(計算機會産生一個硬體定時器中斷,進入中斷服務函數void OSTimeTick (void);該中斷服務函數的作用是每個中斷來臨,把任務A和任務B控制塊裡面的ptcb->OSTCBDly--;操作,其中ptcb->OSTCBDly最初的值是void OSTimeDly (INT32U ticks)函數傳進去的tick的值)->任務A由等待狀态轉換成就緒狀态->再次任務排程void OS_Sched (void);查找優先級最高的就緒狀态的任務A->進行任務切換OS_TASK_SW();->再次讓任務A運作起來。循環往複。以上就是作業系統任務排程的原理。
第二章
作業系統是一種管理軟體,程式控制塊就是對各個任務管理的結構體。
這個結構體是通過連結清單連結,為了提高查找速度,再加上一個數組,數組的各個元素存儲了連結清單成員的指針。
Typedef struct tcb{
Char*code_name;
Intp;
Intv_number;
Void(*fun)(void);//函數指針,指向各個任務
}
第三章 uc/OS-ii中的任務
任務之間的切換狀态狀态圖。
1、任務分類:系統任務包括(空閑任務+統計任務)和使用者任務
2、任務的優先級:最多可以建立64個任務,0-63,數字越小,任務優先級越高
3、任務的堆棧、以及任務堆棧的初始化
4、任務控制塊連結清單及其任務控制塊的初始化
5、任務就緒表和任務排程,計算機每時每刻讓優先級最高的就緒任務處于運作狀态
6、任務的建立OSTaskCreate();函數
7、任務的挂起OSTaskSuspend(INTU8prio);函數,如果參數是OS_PRIO_SELF,挂起任務本身,則删除任務在任務就緒表中的就緒标志。恢複任務用OSTaskResume()函數。
8、任務的删除。MyTask優先級0,YouTask優先級2,MyTask作為提出删除方,要删除任務YouTask,MyTask調用OSTaskDelReq(2)函數(優先級作為參數),YouTask任務調用OSTaskDelReq(OS_PRIO_SELF)删除自己。
9、uc/osii初始化 OSInit()函數和任務啟動函數OSStart()函數。
第四章 uc/OS-ii的中斷和時鐘
1、中斷的原理:uc/osii是一種可被剝奪性的核心,發生中斷,系統進入中斷服務函數,中斷服務函數運作結束以後,會再次發生一次任務排程去運作優先級最高的就緒任務。void OSIntExit (void);中斷服務函數,任務級的切換函數是OSCtxSw(),中斷級的任務切換函數OSIntCtxSw(),
2、臨界段的概念
3、系統時鐘,系統會産生周期性的硬體中斷,中斷調用中斷服務程式OSTickISR中斷調用中斷服務函數OSTimeTick();函數,該函數是時鐘節拍函數,作用是讓每個控制塊裡的tcb->OSTCBDly--,簡單說了解每任務的延時狀态,其中到了延時時限的非挂起的任務處于就緒狀态。
4、任務延時,任務延時的目的是讓其他任務優先級别較低的任務獲得CPU使用權的機會,函數OSTimeTick()作用是取消目前任務的就緒狀态,引發一次任務排程。OSTimeTickResume()函數的作用是取消延時,進入就緒狀态,如果任務比正在運作的任務優先級高,立即引發一次任務排程。
第五章 任務的同步與通信
信号量,互斥量、消息郵箱、消息隊列4個概念,解決的問題是多任務對共享資源的通路引發的問題,包括(1)互斥問題不能同時通路,(2)同步問題先後通路,(3)任務之間的通信,消息郵箱、消息隊列
1、 事件控制塊
typedef struct os_event {
INT8U OSEventType;
void *OSEventPtr;
INT16U OSEventCnt;
OS_PRIO OSEventGrp;
OS_PRIO OSEventTbl[OS_EVENT_TBL_SIZE];
INT8U *OSEventName;
} OS_EVENT;
OSEventType事件類型,包括OS_EVEVT_TYPE_MUTEX, OS_EVEVT_TYPE_MBOX, OS_EVEVT_TYPE_Q,OS_EVEVT_TYPE_SEM,4種類型。OSEventCnt信号量計數器。OSEventGrp各任務組中是否有任務。OSEventTbl[OS_EVENT_TBL_SIZE]檢視任務組中的等待任務清單。
事件控制塊函數OS_EventWaitListWait()作用是OSEventGrp和任務等待表中OSEventTbl[OS_EVENT_TBL_SIZE]全部清0,在
OS×××CREATE()函數中調用,×××表示4中類型。
OS_EventTaskWait()函數的作用是把一個任務處于等待狀态,OS×××Pend()函數中調用。
OS_EventTaskRdy()函數的作用是把一個任務處于就緒狀态,OS×××Post()函數中調用。
2、信号量Sem。OSSemCreate(1);建立信号量初值為1。OSSemPend()請求信号量,OSEventCnt>1信号量有效,可以執行下面的代碼,OSEventCnt并減1操作。OSSemPost()對OSEventCnt加1操作。信号量同樣可以解決同步和互斥的問題。
3、互斥信号量Mutex。會出現優先級反轉的問題,出現的原因是:當高優先級别的任務A和低優先級的任務C使用同一個信号量,低優先級的任務C先獲得信号量,A打斷C的運作,C沒有釋放信号量,A隻好等待。系統中還存在中等優先級的任務B時,任務B沒有使用同一個信号量,B會打斷任務C的運作,同時C沒有釋放信号量,B運作完之後,C運作,C釋放信号量,A運作。造成中等優先級的B先于A運作,優先級反轉。解決方法:信号量任務的優先級别在使用共享資源的時候暫時提升到所有任務最高優先級别的高一級别上。
4、互斥信号量的建立OSMutexCreate(),請求OSMutexPend(),發送OSMutexPost()。
5、消息郵箱的建立OSMboxCreate(),請求OSMboxPend(),發送OSMboxPost()。消息郵箱的作用是,任務之間傳遞資訊。
6、消息隊列的建立OSQCreate()建立,請求OSQPend(),OSQPost()。
消息隊列的作用是,任務之間通信。OSQPost()或者OSQPostFront()都是想消息隊列發送消息,OSQPost()先進先出OSQPostFront()後進先出的方式組織消息隊列。
第6章 信号量集
例子:建立3個任務,MyTask、YouTask、HerTask,要求用一個信号量集來控制MyTask的運作,即任務YouTask發送一個信号,任務herTask發送一個信号,當這兩個任務都發送了信号之後,MyTask 任務才運作。
定義全局變量
INTU8 err;
OS_FLAG_GRP *Sem_F;
在StartTask()中建立三個任務MyTask、YouTask、HerTask,優先級分别為3,4,5。
MyTask請求信号量集OSFlagPend(Sem_F,(OS_FLAGS)3,OS_FLAG_WAIT_ALL,0,&err),其中數字3表示請求第0位和第1位信号。
YouTask發送信号量集OSFlagPost(Sem_F,(OS_FLAGS)2,OS_FLAG_SET,0,&err),其中數字2表示給第1位發送信号。
HerTask發送信号量集OSFlagPost(Sem_F,(OS_FLAGS)1,OS_FLAG_SET,0,&err),其中數字1表示給第0位發送信号。
總結:隻有任務YouTask和任務HerTask都發送完信号,任務Myask才會運作。