OS_CORE.C(10)
今天看os_core.c文件中的各種初始化函數(shù)。
OS_EventWaitListInit(OS_EVENT *pevent)初始化事件控制塊的等待列表:
/*$PAGE*/ /*2018/2/8 ********************************************************************************************************* * INITIALIZE EVENT CONTROL BLOCK'S WAIT LIST * 初始化事件控制塊的等待列表 * Description: This function is called by other uC/OS-II services to initialize the event wait list. *描述:該功能被其他uc/os-ii服務(wù)調(diào)用,用來初始化事件的等待列表。 * Arguments : pevent is a pointer to the event control block allocated to the event. *參數(shù): --pevent是一個指向事件控制塊的指針 * Returns : none *返回值:無 * Note : This function is INTERNAL to uC/OS-II and your application should not call it. 注釋:該功能是內(nèi)部函數(shù),你的應(yīng)用程序不能調(diào)用 ********************************************************************************************************* */ #if (OS_EVENT_EN) /*允許生成事件*/ void OS_EventWaitListInit(OS_EVENT *pevent) /*調(diào)用初始化事件等待列表函數(shù)*/ {INT8U i;pevent->OSEventGrp = 0u; /*將事件組初始化為0*/for (i = 0u; i < OS_EVENT_TBL_SIZE; i++) {pevent->OSEventTbl[i] = 0u; /*將事件表全部初始化為0*/} } #endif
OS_InitEventList(void)初始化事件控制塊的空閑列表:
/*$PAGE*/ /*2018/2/8 ********************************************************************************************************* * INITIALIZATION * INITIALIZE THE FREE LIST OF EVENT CONTROL BLOCKS * 初始化事件控制塊的空閑列表 * Description: This function is called by OSInit() to initialize the free list of event control blocks. *描述:該功能被初始化函數(shù) OSInit()調(diào)用,用來初始化事件控制塊的空閑列表 * Arguments : none *參數(shù):無 * Returns : none 返回值:無 ********************************************************************************************************* */static void OS_InitEventList(void) { #if (OS_EVENT_EN) && (OS_MAX_EVENTS > 0u) #if (OS_MAX_EVENTS > 1u) /*最大事件數(shù)不止1個,用循環(huán)處理*/INT16U ix;INT16U ix_next;OS_EVENT *pevent1; /*第一個指向事件控制塊的指針*/OS_EVENT *pevent2; /*第二個指向事件控制塊的指針*/OS_MemClr((INT8U *)&OSEventTbl[0], sizeof(OSEventTbl)); /* Clear the event table 將事件表從內(nèi)存中清理掉*/for (ix = 0u; ix < (OS_MAX_EVENTS - 1u); ix++) /* Init. list of free EVENT control blocks初始化事件控制塊的空閑列表*/{ ix_next = ix + 1u; pevent1 = &OSEventTbl[ix]; /*pevent1指向ix個ECB*/pevent2 = &OSEventTbl[ix_next]; /*pevent2指向下一個ECB*/pevent1->OSEventType = OS_EVENT_TYPE_UNUSED; /*將事件的類型設(shè)置為無使用類型*/pevent1->OSEventPtr = pevent2; /*將OSEvenPtr指向下一個元素(ECB)*/#if OS_EVENT_NAME_EN > 0u /*如果事件控制塊被命名,設(shè)置為未命名*/pevent1->OSEventName = (INT8U *)(void *)"?"; /*未命名就用“?”表示*/#endif}pevent1 = &OSEventTbl[ix]; /*對數(shù)組的最后一個進行處理*/pevent1->OSEventType = OS_EVENT_TYPE_UNUSED; pevent1->OSEventPtr = (OS_EVENT *)0; /*最后的OSEventPtr指針指向0,作為結(jié)束*/#if OS_EVENT_NAME_EN > 0u /*如果最后一個事件也有名稱,設(shè)置為未命名*/pevent1->OSEventName = (INT8U *)(void *)"?"; #endifOSEventFreeList = &OSEventTbl[0]; /*最后事件空閑列表的指針指向事件表的首地址*/ #elseOSEventFreeList = &OSEventTbl[0]; /*如果只有一個事件控制塊,就不需要循環(huán)了,直接進行處理*/OSEventFreeList->OSEventType = OS_EVENT_TYPE_UNUSED;OSEventFreeList->OSEventPtr = (OS_EVENT *)0; #if OS_EVENT_NAME_EN > 0uOSEventFreeList->OSEventName = (INT8U *)"?"; #endif #endif #endif }
其中:在循環(huán)體內(nèi)使用兩個指針,如下所示:
ix_next = ix + 1u; pevent1 = &OSEventTbl[ix]; /*pevent1指向ix個ECB*/pevent2 = &OSEventTbl[ix_next]; /*pevent2指向下一個ECB*/pevent1->OSEventType = OS_EVENT_TYPE_UNUSED; /*將事件的類型設(shè)置為無使用類型*/pevent1->OSEventPtr = pevent2; /*將OSEvenPtr指向下一個元素(ECB)*/
個人認為是想通過EventPtr指針將所有的事件控制塊鏈接起來。
這個函數(shù),最主要的是設(shè)置時間的類型 (初始化為UNUSED)。
此外,
OS_MemClr((INT8U *)&OSEventTbl[0], sizeof(OSEventTbl)); /* Clear the event table 將事件表從內(nèi)存中清理掉*/for (ix = 0u; ix < (OS_MAX_EVENTS - 1u); ix++) /* Init. list of free EVENT control blocks初始化事件控制塊的空閑列表*/{ ix_next = ix + 1u; pevent1 = &OSEventTbl[ix]; /*pevent1指向ix個ECB*/pevent2 = &OSEventTbl[ix_next]; /*pevent2指向下一個ECB*/pevent1->OSEventType = OS_EVENT_TYPE_UNUSED; /*將事件的類型設(shè)置為無使用類型*/pevent1->OSEventPtr = pevent2; /*將OSEvenPtr指向下一個元素(ECB)*/#if OS_EVENT_NAME_EN > 0u /*如果事件控制塊被命名,設(shè)置為未命名*/pevent1->OSEventName = (INT8U *)(void *)"?"; /*未命名就用“?”表示*/#endif}
剛開始對這幾行語句有些疑問:內(nèi)存已經(jīng)把OSEventTb1清理掉了,怎么后面for循環(huán)中還能用?
后來認為是內(nèi)存清理的是具體的數(shù)據(jù),但是地址還保留著。下面是對地址進行的相關(guān)操作。主要是設(shè)置了事件的類型,改了名字,并且重新建立了表的鏈接。
OS_InitMisc(void)初始化各種變量:
/*$PAGE*/ /*2018/2/8 ********************************************************************************************************* * INITIALIZATION * INITIALIZE MISCELLANEOUS VARIABLES * 初始化各種變量 * Description: This function is called by OSInit() to initialize miscellaneous variables. *描述:該功能被OSInit()調(diào)用,用來初始化各種變量 * Arguments : none *參數(shù):無 * Returns : none 返回值:無 ********************************************************************************************************* */static void OS_InitMisc(void) { #if OS_TIME_GET_SET_EN > 0u /*如果可以生成OS_TIME_GET_SET()函數(shù)*/OSTime = 0uL; /* Clear the 32-bit system clock將時鐘設(shè)為0。清除32位系統(tǒng)時鐘*/ #endifOSIntNesting = 0u; /* Clear the interrupt nesting counter將中斷嵌套數(shù)初始化為0*/OSLockNesting = 0u; /* Clear the scheduling lock counter將調(diào)度鎖數(shù)目初始化為0*/OSTaskCtr = 0u; /* Clear the number of tasks將任務(wù)的數(shù)目初始化為0*/OSRunning = OS_FALSE; /* Indicate that multitasking not started將OSRunning設(shè)置為false,說明多任務(wù)沒有開始*/OSCtxSwCtr = 0u; /* Clear the context switch counter將上下文切換次數(shù)初始化為0*/OSIdleCtr = 0uL; /* Clear the 32-bit idle counter將空閑節(jié)拍計數(shù)值初始化為0*/#if OS_TASK_STAT_EN > 0u /*如果有任務(wù)統(tǒng)計*/OSIdleCtrRun = 0uL; /*將已運轉(zhuǎn)的空閑數(shù)初始化為0*/OSIdleCtrMax = 0uL; /*將空閑節(jié)拍最大值初始化為0*/OSStatRdy = OS_FALSE; /* Statistic task is not ready將統(tǒng)計任務(wù)的狀態(tài)設(shè)置為為準(zhǔn)備好(false)*/ #endif#ifdef OS_SAFETY_CRITICAL_IEC61508OSSafetyCriticalStartFlag = OS_FALSE; /* Still allow creation of objects */ #endif }
OS_InitRdyList(void)初始化就緒列表:
/*$PAGE*/ /*2018/2/8 ********************************************************************************************************* * INITIALIZATION * INITIALIZE THE READY LIST * 初始化就緒列表 * Description: This function is called by OSInit() to initialize the Ready List. *描述:該功能被OSInit()調(diào)用,用來初始化就緒列表 * Arguments : none *參數(shù):無 * Returns : none 返回值:無 ********************************************************************************************************* */ static void OS_InitRdyList(void) /*初始化就緒列表*/ {INT8U i;OSRdyGrp = 0u; /*將就緒列表組清除為0*/for (i = 0u; i < OS_RDY_TBL_SIZE; i++) {OSRdyTbl[i] = 0u; /*將就緒表初始化為0*/} OSPrioCur = 0u; /*將當(dāng)前任務(wù)的優(yōu)先級設(shè)置為0*/OSPrioHighRdy = 0u; /*最高優(yōu)先級任務(wù)的優(yōu)先級設(shè)置為0*/OSTCBHighRdy = (OS_TCB *)0; /*就緒列表中,指向最高優(yōu)先級TCB的指針設(shè)置為0*/OSTCBCur = (OS_TCB *)0; /*指向當(dāng)前任務(wù)控制塊的指針設(shè)置為0*/ }
這個函數(shù)中,個人認為很需要搞清楚各個變量代表的含義究竟是什么。不然后面會出現(xiàn)混亂和誤用。
OS_InitTCBList(void)初始化任務(wù)控制塊的空閑列表:
初始化空閑列表和初始化就緒列表很相似。不贅述。
以上是CORE.C文件中有關(guān)初始化的內(nèi)容。總結(jié)為下圖:
OS_MemClr(INT8U ?*pdest,INT16U ?size)清理內(nèi)存:
/*$PAGE*/ /*2018/2/8 ********************************************************************************************************* * CLEAR A SECTION OF MEMORY * 清理內(nèi)存某些部分 * Description: This function is called by other uC/OS-II services to clear a contiguous block of RAM. *描寫:該功能被其他服務(wù)調(diào)用,用來清除RAM中一段連續(xù)塊。 * Arguments : pdest is the start of the RAM to clear (i.e. write 0x00 to) *參數(shù): --pdest是RAM中要清除的塊的開始地址 * size is the number of bytes to clear. * --size是要清除的大小。 * Returns : none *返回值:無 * Notes : 1) This function is INTERNAL to uC/OS-II and your application should not call it. * 2) Note that we can only clear up to 64K bytes of RAM. This is not an issue because none * of the uses of this function gets close to this limit. * 3) The clear is done one byte at a time since this will work on any processor irrespective * of the alignment of the destination.注釋: 1)該功能為內(nèi)部函數(shù),你的應(yīng)用程序不能調(diào)用。2)需要注意我們只能清理RAM中的64KB。其他部分不能清理。不過這也不是什么問題,因為一般不會鄰近這個限制區(qū)。3)清理的時候一次只能清理一個字節(jié)。因為這樣的話不用考慮目標(biāo)的排列方式,與處理器無關(guān),移植性更高。 ********************************************************************************************************* */void OS_MemClr(INT8U *pdest, /*清理內(nèi)存*/INT16U size) {while (size > 0u) {*pdest++ = (INT8U)0; /*指針置為0*/size--; /*大小最后也置為0*/} }
關(guān)于內(nèi)存的管理,這里總結(jié)介紹一下:https://wenku.baidu.com/view/51e6f4f7a417866fb94a8e4b.html
OS_MemClr()函數(shù):
- 用于對指定內(nèi)存中的數(shù)據(jù)進行清零操作。
- 最大只允許清除內(nèi)存中64KB的字節(jié)的數(shù)據(jù)。用戶不必擔(dān)心數(shù)據(jù)量不滿足要求的問題,因為這個功能的應(yīng)用沒有一個能接近這個限制。
- 該功能一個時間點只能清除一個字節(jié)的數(shù)據(jù),這是為了在任何程序上移植該程序時都能對準(zhǔn)內(nèi)存位置。當(dāng)然,如果確定了處理器類型,可以修改該函數(shù),提高代碼的效率。
第三個圖也可以和上文TCB的空閑列表函數(shù)很好的聯(lián)系起來。都是類似的。
其他相關(guān)的內(nèi)存管理沒有介紹。因為還沒有涉及到相關(guān)函數(shù)。涉及到再說。
?OS_MemCopy(INT8U ?*pdest,INT8U ?*psrc,INT16U ?size)內(nèi)存復(fù)制函數(shù):
/*$PAGE*/ /*2018/2/8 ********************************************************************************************************* * COPY A BLOCK OF MEMORY * 復(fù)制內(nèi)存塊 * Description: This function is called by other uC/OS-II services to copy a block of memory from one * location to another. *描述:該功能被其他服務(wù)調(diào)用,用來將內(nèi)存塊從某個位置復(fù)制到另一個位置。 * Arguments : pdest is a pointer to the 'destination' memory block *參數(shù): --pdest指向目的內(nèi)存塊的指針 * psrc is a pointer to the 'source' memory block * --psrc指向源內(nèi)存塊的指針 * size is the number of bytes to copy. * --size:要復(fù)制的內(nèi)容的大小 * Returns : none *返回值:無 * Notes : 1) This function is INTERNAL to uC/OS-II and your application should not call it. There is * no provision to handle overlapping memory copy. However, that's not a problem since this * is not a situation that will happen. * 2) Note that we can only copy up to 64K bytes of RAM * 3) The copy is done one byte at a time since this will work on any processor irrespective * of the alignment of the source and destination.注釋: 1)該功能為內(nèi)部函數(shù),你的應(yīng)用程序不能調(diào)用。沒有提供處理重復(fù)內(nèi)存復(fù)制的方法。不過沒什么問題,因為這種情況不會發(fā)生。2)我們只能復(fù)制RAM的64KB。3)我們一個時間點只能復(fù)制一個字節(jié)。 ********************************************************************************************************* */void OS_MemCopy(INT8U *pdest,INT8U *psrc,INT16U size) {while (size > 0u) {*pdest++ = *psrc++; /*從源內(nèi)存塊復(fù)制到目標(biāo)內(nèi)存塊*/size--;} }
總結(jié)
以上是生活随笔為你收集整理的OS_CORE.C(10)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OS_CORE.C(9)
- 下一篇: OS_CORE.C(11)