日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

uC/OS-II源码分析(总体思路一)(

發布時間:2023/12/15 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 uC/OS-II源码分析(总体思路一)( 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

首先從main函數開始,下面是uC/OS-II main函數的大致流程:

main(){

?OSInit();

?TaskCreate(...);

?OSStart();

}

首先是調用OSInit進行初始化,然后使用TaskCreate創建幾個進程/Task,最后調用OSStart,操作系統就開始運行了。

?

OSInit

?

最先看看OSInit完成哪些初始化:

void? OSInit (void)

{

#if OS_VERSION >= 204

??? OSInitHookBegin();??????????????????????????????????????????

#endif

??? OS_InitMisc();??????????????????????????????????????????????

??? OS_InitRdyList();???????????????????????????????????????????

??? OS_InitTCBList();???????????????????????????????????????????

??? OS_InitEventList();?????????????????????????????????????????

#if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)

??? OS_FlagInit();??????????????????????????????????????????????

#endif

#if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0)

??? OS_MemInit();???????????????????????????????????????????????

#endif

#if (OS_Q_EN > 0) && (OS_MAX_QS > 0)

??? OS_QInit();?????????????????????????????????????????????????

#endif

??? OS_InitTaskIdle();??????????????????????????????????????????

#if OS_TASK_STAT_EN > 0

??? OS_InitTaskStat();??????????????????????????????????????????

#endif

#if OS_VERSION >= 204

??? OSInitHookEnd();????????????????????????????????????????????

#endif

#if OS_VERSION >= 270 && OS_DEBUG_EN > 0

??? OSDebugInit();

#endif

}

OS_InitMisc()完成的是一些其其他他的變量的初始化:

??? OSIntNesting? = 0;????????????????????????????????????

??? OSLockNesting = 0;????????????????????????????????????

??? OSTaskCtr???? = 0;????????????????????????????????????

??? OSRunning???? = FALSE;????????????????????????????????

???

??? OSCtxSwCtr??? = 0;????????????????????????????????????

??? OSIdleCtr???? = 0L;???????????????????????????????????

其中包括:中斷嵌套標志OSIntNesting,調度鎖定標志OSLockNesting,OS標志OSRunning等。OSRunning在這里設置為FALSE,在后面OSStartHighRdy中會被設置為TRUE表示OS開始工作。

OS_InitRdyList()初始化就緒Task列表:

static? void? OS_InitRdyList (void)

{

??? INT8U??? i;

??? INT8U?? *prdytbl;

??? OSRdyGrp????? = 0x00;?????????????????????????????????

??? prdytbl?????? = &OSRdyTbl[0];

??? for (i = 0; i < OS_RDY_TBL_SIZE; i++) {

??????? *prdytbl++ = 0x00;

??? }

??? OSPrioCur???? = 0;

??? OSPrioHighRdy = 0;

??? OSTCBHighRdy? = (OS_TCB *)0;????????????????????????????????

??? OSTCBCur????? = (OS_TCB *)0;

}

首先將OSRdyTbl[]數組中全部初始化0,同時將OSPrioCur/OSTCBCur初始化為0,OSPrioHighRdy/OSTCBHighRdy也初始化為0,這幾個變量將在第一個OSSchedule中被賦予正確的值。

OS_InitTCBList()這個函數看名稱我們就知道是初始化TCB列表。

static? void? OS_InitTCBList (void)

{

??? INT8U??? i;

??? OS_TCB? *ptcb1;

??? OS_TCB? *ptcb2;

??? OS_MemClr((INT8U *)&OSTCBTbl[0],???? sizeof(OSTCBTbl));?????

??? OS_MemClr((INT8U *)&OSTCBPrioTbl[0], sizeof(OSTCBPrioTbl));?

??? ptcb1 = &OSTCBTbl[0];

??? ptcb2 = &OSTCBTbl[1];

??? for (i = 0; i < (OS_MAX_TASKS + OS_N_SYS_TASKS - 1); i++) {?

??????? ptcb1->OSTCBNext = ptcb2;

#if OS_TASK_NAME_SIZE > 1

??????? ptcb1->OSTCBTaskName[0] = '?';??????????????????????????

??????? ptcb1->OSTCBTaskName[1] = OS_ASCII_NUL;

#endif

??????? ptcb1++;

??????? ptcb2++;

??? }

??? ptcb1->OSTCBNext = (OS_TCB *)0;?????????????????????????????

#if OS_TASK_NAME_SIZE > 1

??? ptcb1->OSTCBTaskName[0] = '?';??????????????????????????????

??? ptcb1->OSTCBTaskName[1] = OS_ASCII_NUL;

#endif

??? OSTCBList?????????????? = (OS_TCB *)0;??????????????????????

??? OSTCBFreeList?????????? = &OSTCBTbl[0];

}

這里完成的工作很簡單,首先把整個數組使用OSTCBNext指針連接成鏈表鏈起來,然后將OSTCBList初始化為0,也就是還沒有TCB,因為還沒有Task產生,OSTCBFreeList指向OSTCBTbl[]數組的第一個表示所有TCB都處于Free狀態。

OS_InitEventList()初始化Event列表。

static? void? OS_InitEventList (void)

{

#if OS_EVENT_EN && (OS_MAX_EVENTS > 0)

#if (OS_MAX_EVENTS > 1)

??? INT16U???? i;

??? OS_EVENT? *pevent1;

??? OS_EVENT? *pevent2;

??? OS_MemClr((INT8U *)&OSEventTbl[0], sizeof(OSEventTbl));

??? pevent1 = &OSEventTbl[0];

??? pevent2 = &OSEventTbl[1];

??? for (i = 0; i < (OS_MAX_EVENTS - 1); i++) {????????????

??????? pevent1->OSEventType??? = OS_EVENT_TYPE_UNUSED;

??????? pevent1->OSEventPtr???? = pevent2;

#if OS_EVENT_NAME_SIZE > 1

??????? pevent1->OSEventName[0] = '?';?????????????????????

??????? pevent1->OSEventName[1] = OS_ASCII_NUL;

#endif

??????? pevent1++;

??????? pevent2++;

??? }

??? pevent1->OSEventType??????????? = OS_EVENT_TYPE_UNUSED;

??? pevent1->OSEventPtr???????????? = (OS_EVENT *)0;

#if OS_EVENT_NAME_SIZE > 1

??? pevent1->OSEventName[0]???????? = '?';?????????????????

??? pevent1->OSEventName[1]???????? = OS_ASCII_NUL;

#endif

??? OSEventFreeList???????????????? = &OSEventTbl[0];

#else

??? OSEventFreeList???????????????? = &OSEventTbl[0];??????

??? OSEventFreeList->OSEventType??? = OS_EVENT_TYPE_UNUSED;

??? OSEventFreeList->OSEventPtr???? = (OS_EVENT *)0;

#if OS_EVENT_NAME_SIZE > 1

??? OSEventFreeList->OSEventName[0] = '?';?????????????????

??? OSEventFreeList->OSEventName[1] = OS_ASCII_NUL;

#endif

#endif

#endif

}

同樣將EventTbl[]數組中的OSEventType都初始化為OS_EVENT_TYPE_UNUSED。

OS_InitTaskIdle(),中間我們跳過其他的如Mem等的初始化,看看Idle Task的初始化。

??? (void)OSTaskCreateExt(OS_TaskIdle,

????????????????????????? (void *)0,????????????????????????????????

????????????????????????? &OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1],

????????????????????????? OS_IDLE_PRIO,?????????????????????????????

????????????????????????? OS_TASK_IDLE_ID,

????????????????????????? &OSTaskIdleStk[0],????????????????????????

????????????????????????? OS_TASK_IDLE_STK_SIZE,

????????????????????????? (void *)0,????????????????????????????????

????????????????????????? OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);

其實Idle Task的初始化很簡單就是調用OSTaskCrete系列的函數創建一個Task, OSTaskCreate我們后面再做進一步分析。

初始化State Task也是類似調用OSTaskCreate系列函數創建Stat Task。這里只是創建了該Task的各個結構還沒有真正運行該Task,直到OSStart中才依據優先級調度運行。

OK,到這里OSInit算高一個段落了,我們接著回到main往下看。

總結

以上是生活随笔為你收集整理的uC/OS-II源码分析(总体思路一)(的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。