分析源碼: 得先學會讀文檔, 函數前邊的 note ;是瞭解該程序員的思想的途徑。不得不重視 代碼前邊的 Notes,瞭解思想後,而後在分析代碼時看他是如何具體實現的。
一、 ucosii/source/ucosii.h
全局變量(GLOBAL VARIABLES)的定義:
OS_EXT INT32U OSCtxSwCtr /* Counter of number of context switches記錄操做系統切換上下文的次數*/
OSEventFreeList; event空閒鏈表
OSEventTbl[OS_MAX_EVENTS]; 全局event數組
OSCPUUsage; cpu使用率。
OSIdleCtrMax; 1秒鐘以內空閒計數。
OSIdleCtrRun; 1秒內空閒任務空閒計數器
OSTime; /**/操做系統的當前時間
OSStatRdy Flag變量(標誌位)指示當前任務是否rdy。
OSTaskStatStk[OS_TASK_STAT_STK_SIZE]; 統計任務的任務棧,(給統計任務規定的任務棧。)
OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE] 空閒任務的任務棧,(給空閒任務規定的任務棧。)
OSIntNesting /*Interrupt nesting level*/ 中斷嵌套級別。做用:判斷是否處於中斷
OSLockNesting /*Multitasking lock nesting level*/ 鎖嵌套級別,
OSPrioCur /*Priority of current task*/ 當前正在運行的任務的優先級
OSPrioHighRdy /* Priority of highest priority task*/ 最高優先級任務的優先級。
OSRdyGrp; /* Ready list group */
OSRdyTbl[OS_RDY_TBL_SIZE] /* Table of tasks which are ready to run */
OSUnMapTbl[256] 常數數組表和計算當前的OSPrioHighRdy有關。
OSRunning /*Flag indicating that kernel is running*/ OS若是沒有完成初始化就爲0,初始化ok能夠開始調度任務了,就設置爲1。
INT8U OSTaskCtr /* Number of tasks created */ //當前一共有幾個任務。
OSIdleCtr /* Idle counter */ // 空閒計數
OSTCBCur /*Pointer to currently running TCB*/ // 指向當前任務的TCB的指針
OSTCBFreeList /* Pointer to doubly linked list of TCBs*/指向當前空閒TCB的數組的指針
也就是說咱們系統有一個鏈表專門把處於空閒狀態的tcb內存用數組連起來。
OSTCBHighRdy /*Pointer to highest priority TCB R-to-R*/
OSTCBList /*Pointer to doubly linked list of TCBs*/
OSTCBTbl[OS_MAX_TASKS + OS_N_SYS_TASKS] /* /** OS_N_SYS_TASKS**系統建立的任務/ Table of TCBs */
//數組
OSMemFreeList; /*Pointer to free list of memory partitions */
OSMemTbl[OS_MAX_MEM_PART]; /* Storage for memory partition manager*/
OS_EXT OS_TCB OSTCBTbl[OS_MAX_TASKS + OS_N_SYS_TASKS]; /* Table of TCBs*/
OS_EXT OS_TCB *OSTCBFreeList; /* Pointer to list of free TCBs*/
二、 ucosii/source/os_time.c
OSTimeDly () //任務執行時遇到的延時時,這個函數會把當前任務設置成非就緒態(操做就緒表),就是把當前任務掛起。
OSTimeDlyResume(INT8U prio) //恢復任務
ptcb->OSTCBDly = 0; //將任務中的ptcb->OSTCBDly = 0;
PEND和SUSPEND的區別:
PEND和(PEND_TO、PEND_OK)等相對應。pend關注的是當前任務在等待某個event(sem、mutex、等)
SUSPEND和咱們的RDY對應,用來描述任務當前的狀態,RDY表示任務處於就緒態,SUSPEND表示任務處於非就緒態(掛起態)。
DIY只能本身DIY本身,
三、 ucosii/source/os_task.c
一、INT8U OSTaskChangePrio (INT8U oldprio, INT8U newprio)
OS_EVENT_EN //只有一個事件
OS_EVENT_MULTI_EN //包含多個事件標誌
#if (OS_EVENT_EN)
pevent = ptcb->OSTCBEventPtr; //只有一個事件
if (pevent != (OS_EVENT *)0)
{
pevent->OSEventTbl[y_old] &= ~bitx_old; /* Remove old task prio from wait list */
if (pevent->OSEventTbl[y_old] == 0)
{
pevent->OSEventGrp &= ~bity_old;
}
pevent->OSEventGrp |= bity_new; /* Add new task prio to wait list */
pevent->OSEventTbl[y_new] |= bitx_new;
}
#if (OS_EVENT_MULTI_EN > 0) // 包含多個事件標誌
if (ptcb->OSTCBEventMultiPtr != (OS_EVENT **)0)
{
pevents = ptcb->OSTCBEventMultiPtr;
pevent = *pevents;
while (pevent != (OS_EVENT *)0)
{
pevent->OSEventTbl[y_old] &= ~bitx_old; /* Remove old task prio from wait lists */
if (pevent->OSEventTbl[y_old] == 0)
{
pevent->OSEventGrp &= ~bity_old;
}
pevent->OSEventGrp |= bity_new; /* Add new task prio to wait lists */
pevent->OSEventTbl[y_new] |= bitx_new;
pevents++;
pevent = *pevents;
}
二、INT8U OSTaskCreate (void (*task)(void *p_arg), void *p_arg, OS_STK *ptos, INT8U prio)
{
}
ucosii/source/os_core.c
INT8U OS_TCBInit (INT8U prio, OS_STK *ptos, OS_STK *pbos, INT16U id, INT32U stk_size, void *pext, INT16U opt)程序員
{
ptcb = OSTCBFreeList; //ptcb指針指向 FreeList 空,在freelist中早就開闢了任務塊的大小。
//剛開始是指向第一個,再建立的話OSTCBFreeList加1;
}
節點間經過全局變量OSTCBList指針來掛接。OSTCBList指向一個雙向鏈表,這個雙向鏈表中的每個元素都是一個已經被建立了個任務的TCB結構體, OSTCBList 永遠指向最新建立的任務。 任務的插入的時候,直接用OSTCBList 。而雙向鏈表的新元素插入方式是頭插入。OSTCBList指向全部任務雙鏈表的鏈表頭,數組
三、OSTaskCreateExt()
四、INT8U OSTaskDel (INT8U prio) //刪除任務,並非真的刪除這個任務,由於任務的TCB結構體是一個數組,數組是
//是事先定義好的,OSTCBFreeList 指針 只能日後移,不能往前移。一個任務一旦被建立,這個任務對應的內存格子就被佔用了,當前任務的內存沒法釋放,讓別的數據結構來使用。
ucosii任務狀態:運行態(活動態)、就緒態、掛起態(等待一個event,好比調用diy函數,或者等待一個信號量)、休眠態(刪除任務) 重視函數的 Notes 按照此思路分析源碼。
ptcb->OSTCBDly = 0; /* Prevent OSTimeTick() from updating */
ptcb->OSTCBStat = OS_STAT_RDY; /* Prevent task from being resumed ucosii中就緒表是最重要的*/
ptcb->OSTCBStatPend = OS_STAT_PEND_OK;
五、 此時將 ptcb->OSTCBDly = 0;
void OS_CPU_SysTickHandler (void)中 有 任務切換。待會截圖。
INT8U OSTaskCreate (void (*task)(void *p_arg), void *p_arg, OS_STK *ptos, INT8U prio)數據結構
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
七、 ptcb->OSTCBNext = OSTCBFreeList; /* Return TCB to free TCB list */
OSTCBFreeList = ptcb; //刪除的節點能夠回收,指針會掛接
OSTCBFreeList 以後在畫圖分析。 太累了。先回寢室了。
八、#if OS_TASK_DEL_EN > 0 //配置宏,若是不須要刪除任務,能夠將此配置宏配置爲0;
INT8U OSTaskDelReq (INT8U prio)
(1)//讓任務A申請去刪除有資源未釋放的任務B,他不能用於一個任務刪除自身,
(2)這個函數工做時在任務A和B中都須要被調用,實現就是圍繞 ptcb->OSTCBDelReq 是否與OS_ERR_TASK_DEL_REQ 相等 。 在任務A中給這個元素賦值,在任務B中經過查這個元素的值來決定是否要刪除本身。
九、INT8U OSTaskResume (INT8U prio) //恢復掛起的的任務,
十、OSTaskSuspend (INT8U prio)
SUSPEND A TASK//和OSTaskResume (INT8U prio)函數配套使用//恢復掛起的的任務,
十一、OSTaskQuery (INT8U prio, OS_TCB *p_task_data) // //獲得一個任務的TCB的一份的拷貝,
十二、OS_TaskStkClr (OS_STK *pbos, INT32U size, INT16U opt) //清除棧內存,