當(dāng)前位置:首頁(yè) > 嵌入式 > 嵌入式軟件
[導(dǎo)讀]ucos ii介紹μC/OS-II由Micrium公司提供,是一個(gè)可移植、可固化的、可裁剪的、占先式多任務(wù)實(shí)時(shí)內(nèi)核,它適用于多種微處理器,微控制器和數(shù)字處理芯片(已經(jīng)移植到超過(guò)100種

ucos ii介紹

μC/OS-II由Micrium公司提供,是一個(gè)可移植、可固化的、可裁剪的、占先式多任務(wù)實(shí)時(shí)內(nèi)核,它適用于多種微處理器,微控制器和數(shù)字處理芯片(已經(jīng)移植到超過(guò)100種以上的微處理器應(yīng)用中)。同時(shí),該系統(tǒng)源代碼開(kāi)放、整潔、一致,注釋詳盡,適合系統(tǒng)開(kāi)發(fā)。

常用函數(shù)介紹:

OSInit()初始化函數(shù)

在uC/OS II的學(xué)習(xí)中,OSInit(OS_CORE.C )(函數(shù)原型位于);是一個(gè)重要的函數(shù),它在OS應(yīng)用中的main()函數(shù)中首先被調(diào)用,是OS運(yùn)行的第一個(gè)函數(shù),它完成各初始變量的初始化。主要工作:

OSInitHookBegin(); /* 調(diào)用用戶特定的初始化代碼(通過(guò)一個(gè)接口函數(shù)實(shí)現(xiàn)用戶要求的插件式進(jìn)入系統(tǒng)中)*/

OS_InitMisc(); /* 初始化變量*/

OS_InitRdyList(); /* 初始化就緒列表*/

OS_InitTCBList(); /* 初始化OS_TCB空閑列表*/

OS_InitEventList(); /* 初始化OS_EVENT空閑列表*/

OS_InitTaskIdle(); /創(chuàng)建空閑任務(wù)/

程序注釋詳解:

void OSInit (void)

{

#if OS_TASK_CREATE_EXT_EN > 0u

#if defined(OS_TLS_TBL_SIZE) && (OS_TLS_TBL_SIZE > 0u)

INT8U err;

#endif

#endif

OSInitHookBegin(); /* 調(diào)用用戶特定的初始化代碼(通過(guò)一個(gè)接口函數(shù)實(shí)現(xiàn)用戶要求的插件式進(jìn)入系統(tǒng)中)*/

OS_InitMisc(); /* 初始化變量*/ /* Initialize miscellaneous variables */

OS_InitRdyList(); /* 初始化就緒列表*/ /* Initialize the Ready List */

OS_InitTCBList(); /* 初始化OS_TCB空閑列表*/ /* Initialize the free list of OS_TCBs */

OS_InitEventList(); /* 初始化OS_EVENT空閑列表*/ /* Initialize the free list of OS_EVENTs */

#if (OS_FLAG_EN > 0u) && (OS_MAX_FLAGS > 0u)

OS_FlagInit(); /* 初始化事件標(biāo)志結(jié)構(gòu)*/ /* Initialize the event flag structures */

#endif

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

OS_MemInit(); /* 初始化內(nèi)存管理器*/ /* Initialize the memory manager */

#endif

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

OS_QInit(); /* 初始化消息隊(duì)列結(jié)構(gòu)*/ /* Initialize the message queue structures */

#endif

#if OS_TASK_CREATE_EXT_EN > 0u

#if defined(OS_TLS_TBL_SIZE) && (OS_TLS_TBL_SIZE > 0u)

OS_TLS_Init(&err); /* 創(chuàng)建任務(wù)前初始化TLS*/ /* Initialize TLS, before creating tasks */

if (err != OS_ERR_NONE) {

return;

}

#endif

#endif

OS_InitTaskIdle(); /* 創(chuàng)建空閑任務(wù)(無(wú)條件)Create the Idle Task */

#if OS_TASK_STAT_EN > 0u

OS_InitTaskStat(); /* 創(chuàng)建統(tǒng)計(jì)任務(wù)*/ /* Create the Statistic Task */

#endif

#if OS_TMR_EN > 0u

OSTmr_Init(); /* 初始化時(shí)間管理器*/ /* Initialize the Timer Manager */

#endif

OSInitHookEnd(); /*調(diào)用用戶特定的初始化代碼*/

#if OS_DEBUG_EN > 0u

OSDebugInit();

#endif

}

123456789101112131415161718192021222324252627282930313233343536373839404142

任務(wù)函數(shù)相關(guān):

OSTaskCreate()任務(wù)創(chuàng)建函數(shù)

1、主要作用:建立一個(gè)新任務(wù)。任務(wù)的建立可以在多任務(wù)環(huán)境啟動(dòng)之前,也可以在正在運(yùn)行的任務(wù)中建立。中斷處理程序中不能建立任務(wù);注意,ISR中禁止建立任務(wù),一個(gè)任務(wù)必須為無(wú)限循環(huán)結(jié)構(gòu)。

2、函數(shù)原型:INT8U OSTaskCreate(void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio);

3、參數(shù)說(shuō)明:

void (*task)(void *pd):指向任務(wù)代碼首地址的指針。

void *pdata:指向一個(gè)數(shù)據(jù)結(jié)構(gòu),該結(jié)構(gòu)用來(lái)在建立任務(wù)時(shí)向任務(wù)傳遞參數(shù)。

OS_STK *ptos: 指向堆棧任務(wù)棧頂?shù)闹羔?/p>

INT8U prio:任務(wù)優(yōu)先級(jí)

4、返回值介紹:

OS_NO_ERR:函數(shù)調(diào)用成功。

OS_PRIO_EXIST:具有該優(yōu)先級(jí)的任務(wù)已經(jīng)存在。

OS_PRIO_INVALID:參數(shù)指定的優(yōu)先級(jí)大于OS_LOWEST_PRIO。

OS_NO_MORE_TCB:系統(tǒng)中沒(méi)有OS_TCB可以分配給任務(wù)了。

5、函數(shù)主體在os_task.c中

OSTaskCreateExt

1、主要作用:建立一個(gè)新任務(wù)。與OSTaskCreate()不同的是,OSTaskCreateExt()允許用戶設(shè)置更多的細(xì)節(jié)內(nèi)容。任務(wù)的建立可以在多任務(wù)環(huán)境啟動(dòng)之前,也可以在正在運(yùn)行的任務(wù)中建立,但中斷處理程序中不能建立新任務(wù)。,且不

2、函數(shù)原型:NT8U OSTaskCreateExt (void (*task)(void *pd),void *pdata, OS_STK *ptos,INT8U prio ,INT16U id, OS_STK *pbos,INT32U stk_size,void *pext,INT16U opt)

3、參數(shù)說(shuō)明:

void (*task)(void *pd):指向任務(wù)代碼首地址的指針。

void *pdata:指向一個(gè)數(shù)據(jù)結(jié)構(gòu),該結(jié)構(gòu)用來(lái)在建立任務(wù)時(shí)向任務(wù)傳遞參數(shù)。

OS_STK *ptos: 指向堆棧任務(wù)棧頂?shù)闹羔?/p>

INT8U prio:任務(wù)優(yōu)先級(jí)

INT16U id: 任務(wù)ID,2.52版本,無(wú)實(shí)際作用,保留作為擴(kuò)展用

OS_STK *pbos: 指向堆棧底部的指針,用于OSTaskStkChk()函數(shù)

INT32U stk_size:指定任務(wù)堆棧的大小,由OS_STK類型決定

void *pext:定義數(shù)據(jù)結(jié)構(gòu)的指針,作為T(mén)CB的擴(kuò)展

INT16U opt) :存放于任務(wù)操作相關(guān)的信息,詳見(jiàn)uCOS-II.H

4、返回值說(shuō)明:

OS_NO_ERR:函數(shù)調(diào)用成功。

OS_PRIO_EXIST:具有該優(yōu)先級(jí)的任務(wù)已經(jīng)存在。

OS_PRIO_INVALID:參數(shù)指定的優(yōu)先級(jí)大于OS_LOWEST_PRIO。

OS_NO_MORE_TCB:系統(tǒng)中沒(méi)有OS_TCB可以分配給任務(wù)了。

5、函數(shù)主體在os_task.c中

OSTaskSuspend()任務(wù)掛起:

1、主要作用: 無(wú)條件掛起一個(gè)任務(wù)。調(diào)用此函數(shù)的任務(wù)也可以傳遞參數(shù) OS_PRIO_SELF,掛起調(diào)用任務(wù)本身。當(dāng)前任務(wù)掛起后,只有其他任務(wù)才能喚醒被掛起的任務(wù)。任務(wù)掛起后,系統(tǒng)會(huì)重新進(jìn)行任務(wù)調(diào)度,運(yùn)行下一個(gè)優(yōu)先級(jí)最高的就緒任務(wù)。喚醒掛起任務(wù)需要調(diào)用函數(shù)OSTaskResume()。任務(wù)的掛起是可以疊加到其他操作上的。例如,任務(wù)被掛起時(shí)正在進(jìn)行延時(shí)操作,那么任務(wù)的喚醒就需要兩個(gè)條件:延時(shí)的結(jié)束以及其他任務(wù)的喚醒操作。又如,任務(wù)被掛起時(shí)正在等待信號(hào)量,當(dāng)任務(wù)從信號(hào)量的等待對(duì)列中清除后也不能立即運(yùn)行,而必須等到被喚醒后。[!--empirenews.page--]

2、函數(shù)原型:INT8U OSTaskSuspend(INT8U prio);

3、參數(shù)說(shuō)明:prio為指定要獲取掛起的任務(wù)優(yōu)先級(jí),也可以指定參數(shù) OS_PRIO_SELF,掛起任務(wù)本身。此時(shí),下一個(gè)優(yōu)先級(jí)最高的就緒任務(wù)將運(yùn)行。

4、返回值說(shuō)明:

OS_NO_ERR:函數(shù)調(diào)用成功。

OS_TASK_SUSPEND_IDLE:試圖掛起μC/OS-II中的空閑任務(wù)(Idle task)。此為非法操作。

OS_PRIO_INVALID:參數(shù)指定的優(yōu)先級(jí)大于 OS_LOWEST_PRIO 或沒(méi)有設(shè)定 OS_PRIO_SELF 的值。

OS_TASK_SUSPEND_PRIO:要掛起的任務(wù)不存在。

5、函數(shù)主體在os_task.c中

OSTaskResume()喚醒任務(wù)

1、主要作用: 喚醒一個(gè)用 OSTaskSuspend() 函數(shù)掛起的任務(wù)。OSTaskResume() 也是唯一能“解掛”掛起任務(wù)的函數(shù)。

2、函數(shù)原型:INT8U OSTaskResume(INT8U prio);

3、參數(shù)說(shuō)明:prio指定要喚醒任務(wù)的優(yōu)先級(jí)。

4、返回值說(shuō)明:

OS_NO_ERR:函數(shù)調(diào)用成功。

OS_TASK_RESUME_PRIO:要喚醒的任務(wù)不存在

OS_TASK_NOT_SUSPENDED:要喚醒的任務(wù)不在掛起狀態(tài)。

OS_PRIO_INVALID:參數(shù)指定的優(yōu)先級(jí)大于或等于OS_LOWEST_PRIO。

5、函數(shù)主體在os_task.c中

時(shí)間相關(guān)的函數(shù)

OSTimeDly()延時(shí)節(jié)拍函數(shù)

1、主要作用:調(diào)用該函數(shù)的任務(wù)將自己延時(shí)一段時(shí)間并執(zhí)行一次任務(wù)調(diào)度,一旦規(guī)定的延時(shí)時(shí)間完成或有其它的任務(wù)通過(guò)調(diào)用OSTimeDlyResume()取消了延時(shí),調(diào)用OSTimeDly()函數(shù)的任務(wù)馬上進(jìn)入就緒狀態(tài)(前提是先將任務(wù)調(diào)度后執(zhí)行的任務(wù)執(zhí)行到程序尾,且調(diào)用OSTimeDly的任務(wù)此時(shí)優(yōu)先級(jí)最高)。

2、函數(shù)原型:void OSTimeDly (INT16U ticks);

3、參數(shù)說(shuō)明:ticks為需要延時(shí)的時(shí)鐘節(jié)拍數(shù);

4、返回值:無(wú)

5、函數(shù)主體在os_time.c中

OSTimeDlyHMSM()系統(tǒng)延時(shí)函數(shù)

1、主要作用:函數(shù)是以小時(shí)(H)、分(M)、秒(S)和毫秒(m)四個(gè)參數(shù)來(lái)定義延時(shí)時(shí)間的,函數(shù)在內(nèi)部把這些參數(shù)轉(zhuǎn)換為時(shí)鐘節(jié)拍,再通過(guò)單次或多次調(diào)用OSTimeDly()進(jìn)行延時(shí)和任務(wù)調(diào)度,所以延時(shí)原理和調(diào)用延時(shí)函數(shù)OSTimeDly()是一樣的。調(diào)用 OSTimeDlyHMSM() 后,如果延時(shí)時(shí)間不為0,系統(tǒng)將立即進(jìn)行任務(wù)調(diào)度。

2、函數(shù)原型:INT8U OSTimeDlyHMSM (INT8U hours,INT8U minutes,INT8U seconds,INT16U milli);

3、參數(shù)說(shuō)明:

hours 為延時(shí)小時(shí)數(shù),范圍從0-255。

minutes 為延時(shí)分鐘數(shù),范圍從0-59

seconds 為延時(shí)秒數(shù),范圍從0-59

milli 為延時(shí)毫秒數(shù),范圍從0-999

4、返回值說(shuō)明:

OS_NO_ERR:函數(shù)調(diào)用成功。

OS_TIME_INVALID_MINUTES:參數(shù)錯(cuò)誤,分鐘數(shù)大于59。

OS_TIME_INVALID_SECONDS:參數(shù)錯(cuò)誤,秒數(shù)大于59。

OS_TIME_INVALID_MILLI:參數(shù)錯(cuò)誤,毫秒數(shù)大于999。

OS_TIME_ZERO_DLY:四個(gè)參數(shù)全為0。

5、函數(shù)主體在os_time.c中

OSTimeDlyResume()延時(shí)恢復(fù)函數(shù)

1、主要作用:任務(wù)在延時(shí)之后,進(jìn)入阻塞態(tài)。當(dāng)延時(shí)時(shí)間到了就從阻塞態(tài)恢復(fù)到就緒態(tài),可以被操作系統(tǒng)調(diào)度執(zhí)行。但是,并非回到就緒態(tài)就只有這么一種可能,因?yàn)榧幢闳蝿?wù)的延時(shí)時(shí)間沒(méi)到,還是可以通過(guò)函數(shù)OSTimeDlyResume恢復(fù)該任務(wù)到就緒態(tài)的。另外,OSTimeDlyResume也不僅僅能恢復(fù)使用OSTimeDly或OSTimeDlyHMSM而延時(shí)的任務(wù)。對(duì)于因等待事件發(fā)生而阻塞的,并且設(shè)置了超時(shí)(timeout)時(shí)間的任務(wù),也可以使用OSTimeDlyResume來(lái)恢復(fù)。對(duì)這些任務(wù)使用了OSTimeDlyResume,就好像已經(jīng)等待超時(shí)了一樣。但是,對(duì)于采用OSTaskSuspend掛起的任務(wù),是不允許采用OSTimeDlyResume來(lái)恢復(fù)的。

2、函數(shù)原型:INT8U OSTimeDlyResume (INT8U prio)

3.參數(shù)說(shuō)明:prio 被恢復(fù)任務(wù)的優(yōu)先級(jí)

4、返回值:

OS_ERR_TASK_NOT_EXIST:任務(wù)優(yōu)先級(jí)指針表中沒(méi)有此任務(wù)

OS_NO_ERR:函數(shù)調(diào)用成功。

OS_ERR_PRIO_INVALID:參數(shù)指定的優(yōu)先級(jí)大于或等于OS_LOWEST_PRIO。

OS_ERR_TIME_NOT_DLY:任務(wù)沒(méi)有被延時(shí)阻塞

5、函數(shù)主體在os_time.c中

信號(hào)量相關(guān)函數(shù):

如果我們想對(duì)一個(gè)公共資源進(jìn)行互斥訪問(wèn),例如:如果我們想讓兩個(gè)任務(wù)Task1和Task2都可以調(diào)用Fun()函數(shù),但不能同時(shí)調(diào)用,最好定義信號(hào)量:Semp = OSSemCreate(1),同理在各自的任務(wù)中都需要調(diào)用OSSemPend(Semp,0,&err)請(qǐng)求此信號(hào)量,如果可用,則調(diào)用Fun(),然后再用OSSemPost(Semp)釋放該信號(hào)量。這里就實(shí)現(xiàn)了一個(gè)資源的互斥訪問(wèn)。

(注:初始化OSSemCreate(1),那么一個(gè)任務(wù)中有OSSemPend,那么可以執(zhí)行,執(zhí)行之后cnt==0,其他任務(wù)的OSSemPend無(wú)法獲得sem,只能等待,除非任務(wù)一有OSSemPost,使其cnt++,這樣其他任務(wù)的Pend可以執(zhí)行。)

同理,如果一個(gè)任務(wù)要等待n個(gè)事件發(fā)生后才能執(zhí)行,則應(yīng)定義為Semp = OSSemCreate(n)。然后在這n個(gè)任務(wù)分別運(yùn)行時(shí)調(diào)用OSSemPost(Semp),直到這n個(gè)事件均發(fā)生后,這個(gè)任務(wù)才能運(yùn)行。

OSSemCreate(cnt)賦初始值cnt,OSSemPend一次,cnt– 一次,OSSemPost一次,cnt++一次。

下面對(duì)信號(hào)量函數(shù)做簡(jiǎn)要介紹:

OSSemCreate()建立信號(hào)量函數(shù)

1、主要作用:該函數(shù)建立并初始化一個(gè)信號(hào)量,信號(hào)量的作用如下:

允許一個(gè)任務(wù)和其他任務(wù)或者中斷同步

取得設(shè)備的使用權(quán)

標(biāo)志事件的發(fā)生

2、函數(shù)原型:OS_EVENT *OSSemCreate(INT16U value);

3、參數(shù)說(shuō)明:value 參數(shù)是所建立的信號(hào)量的初始值,可以取0到65535之間的任何值。

4、返回值:OSSemCreate() 函數(shù)返回指向分配給所建立的信號(hào)量的控制塊的指針。如果沒(méi)有可用的控制塊,OSSemCreate() 函數(shù)返回空指針。

5、函數(shù)主體在os_sem.c中

OSSemPend()取得使用權(quán)函數(shù)

1、主要作用: 該函數(shù)用于任務(wù)試圖取得設(shè)備的使用權(quán)、任務(wù)需要和其他任務(wù)或中斷同步、任務(wù)需要等待特定事件的發(fā)生的場(chǎng)合。如果任務(wù)調(diào)用OSSemPend() 函數(shù)時(shí),信號(hào)量的值大于零,OSSemPend() 函數(shù)遞減該值。如果調(diào)用時(shí)信號(hào)量值等于零,OSSemPend() 函數(shù)將任務(wù)加入該信號(hào)量的等待隊(duì)列。OSSemPend() 函數(shù)掛起當(dāng)前任務(wù)直到其他的任務(wù)或中斷設(shè)置信號(hào)量或超出等待的預(yù)期時(shí)間。如果在預(yù)期的時(shí)鐘節(jié)拍內(nèi)信號(hào)量被設(shè)置,μC/OS-Ⅱ默認(rèn)讓最高優(yōu)先級(jí)的任務(wù)取得信號(hào)量并回到就緒狀態(tài)。一個(gè)被OSTaskSuspend() 函數(shù)掛起的任務(wù)也可以接受信號(hào)量,但這個(gè)任務(wù)將一直保持掛起狀態(tài)直到通過(guò)調(diào)用OSTaskResume() 函數(shù)恢復(fù)該任務(wù)的運(yùn)行。[!--empirenews.page--]

2、函數(shù)原型:void OSSemPend ( OS_EVNNT *pevent, INT16U timeout, int8u *err );

3、參數(shù)說(shuō)明:

pevent 是指向信號(hào)量的指針。該指針的值在建立該信號(hào)量時(shí)可以得到。(參考OSSemCreate() 函數(shù))。

timeout 允許一個(gè)任務(wù)在經(jīng)過(guò)了指定數(shù)目的時(shí)鐘節(jié)拍后還沒(méi)有得到需要的信號(hào)量時(shí)恢復(fù)就緒狀態(tài)。如果該值為零表示任務(wù)將持續(xù)地等待信號(hào)量,最大的等待時(shí)間為65535個(gè)時(shí)鐘節(jié)拍。這個(gè)時(shí)間長(zhǎng)度并不是非常嚴(yán)格的,可能存在一個(gè)時(shí)鐘節(jié)拍的誤差。

err 是指向包含錯(cuò)誤碼的變量的指針,返回的錯(cuò)誤碼可能為下述幾種:

OS_NO_ERR :信號(hào)量不為零。

OS_TIMEOUT :信號(hào)量沒(méi)有在指定數(shù)目的時(shí)鐘周期內(nèi)被設(shè)置。

OS_ERR_PEND_ISR :從中斷調(diào)用該函數(shù)。雖然規(guī)定了不允許從中斷調(diào)用該函數(shù),但μC/OS-Ⅱ仍然包含了檢測(cè)這種情況的功能。

OS_ERR_EVENT_TYPE :pevent 不是指向信號(hào)量的指針。

4、返回值:無(wú)

5、函數(shù)主體在os_sem.c中

OSSemPost()使用權(quán)放棄函數(shù)

1、主要作用: 該函數(shù)用于設(shè)置指定的信號(hào)量。如果指定的信號(hào)量是零或大于零,OSSemPost() 函數(shù)遞增該信號(hào)量的值并返回。如果有任何任務(wù)在等待該信號(hào)量,則最高優(yōu)先級(jí)的任務(wù)將得到信號(hào)量并進(jìn)入就緒狀態(tài)。任務(wù)調(diào)度函數(shù)將進(jìn)行任務(wù)調(diào)度,決定當(dāng)前運(yùn)行的任務(wù)是否仍然為最高優(yōu)先級(jí)的就緒任務(wù)。

2、函數(shù)原型:INT8U OSSemPost(OS_EVENT *pevent);

3、參數(shù)說(shuō)明:pevent 是指向信號(hào)量的指針。該指針的值在建立該信號(hào)量時(shí)可以得到。(參考OSSemCreate() 函數(shù))。

4、返回值:

OS_NO_ERR :信號(hào)量被成功地設(shè)置

OS_SEM_OVF :信號(hào)量的值溢出

OS_ERR_EVENT_TYPE :pevent 不是指向信號(hào)量的指針

5、函數(shù)主體在os_sem.c中

消息隊(duì)列函數(shù)

消息隊(duì)列是µC/OS-II中另一種通訊機(jī)制,它可以使一個(gè)任務(wù)或者中斷服務(wù)子程序向另一個(gè)任務(wù)發(fā)送以指針?lè)绞蕉x的變量。因具體的應(yīng)用有所不同,每個(gè)指針指向的數(shù)據(jù)結(jié)構(gòu)變量也有所不同。為了使用µC/OS-II的消息隊(duì)列功能,需要在OS_CFG.H 文件中,將OS_Q_EN常數(shù)設(shè)置為1,并且通過(guò)常數(shù)OS_MAX_QS來(lái)決定µC/OS-II支持的最多消息隊(duì)列數(shù)。

12

OSQCreate()建立消息隊(duì)列函數(shù)

1、主要作用:該函數(shù)用于建立一個(gè)消息隊(duì)列。任務(wù)或中斷可以通過(guò)消息隊(duì)列向一個(gè)或多個(gè)任務(wù)發(fā)送消息。消息的含義是和具體的應(yīng)用密切相關(guān)的。

2、函數(shù)原型:OS_EVENT *OSQCreate (void **start, INT8U size);

3、參數(shù)說(shuō)明:start 是消息內(nèi)存區(qū)的首地址,消息內(nèi)存區(qū)是一個(gè)指針數(shù)組

size 是消息內(nèi)存區(qū)的大小。

4、返回值說(shuō)明:OSQCreate() 函數(shù)返回一個(gè)指向消息隊(duì)列控制塊的指針。如果沒(méi)有空閑的控制塊,OSQCreate() 函數(shù)返回空指針

5、函數(shù)主體在os_q.c中

OSQPend()任務(wù)等待消息函數(shù)

1、主要作用: 該函數(shù)用于任務(wù)等待消息。消息通過(guò)中斷或任務(wù)發(fā)送給需要的任務(wù)。消息是一個(gè)指針變量,在不同的應(yīng)用中消息的具體含義不同。如果調(diào)用 OSQPend() 函數(shù)時(shí)隊(duì)列中已經(jīng)存在消息,那么該消息被返回給 OSQPend() 函數(shù)的調(diào)用者,該消息同時(shí)從隊(duì)列中清除。如果調(diào)用 OSQPend() 函數(shù)時(shí)隊(duì)列中沒(méi)有消息,OSQPend() 函數(shù)掛起調(diào)用任務(wù)直到得到消息或超出定義的超時(shí)時(shí)間。如果同時(shí)有多個(gè)任務(wù)等待同一個(gè)消息,μC/OS-Ⅱ默認(rèn)最高優(yōu)先級(jí)的任務(wù)取得消息。一個(gè)由 OSTaskSuspend() 函數(shù)掛起的任務(wù)也可以接受消息,但這個(gè)任務(wù)將一直保持掛起狀態(tài)直到通過(guò)調(diào)用 OSTaskResume() 函數(shù)恢復(fù)任務(wù)的運(yùn)行。

2、函數(shù)原型:void *OSQPend (OS_EVENT *pevent, INT16U timeout, INT8U *err);

3、參數(shù)說(shuō)明:pevent 是指向消息隊(duì)列的指針,該指針的值在建立該隊(duì)列時(shí)可以得到。(參考 OSQCreate() 函數(shù))。 timeout 允許一個(gè)任務(wù)以指定數(shù)目的時(shí)鐘節(jié)拍等待消息。超時(shí)后如果還沒(méi)有得到消息則恢復(fù)成就緒狀態(tài)。如果該值設(shè)置成零則表示任務(wù)將持續(xù)地等待消息,最大的等待時(shí)間為65535個(gè)時(shí)鐘節(jié)拍。這個(gè)時(shí)間長(zhǎng)度并不是非常嚴(yán)格的,可能存在一個(gè)時(shí)鐘節(jié)拍的誤差。

err 是指向包含錯(cuò)誤碼的變量的指針。OSQPend() 函數(shù)返回的錯(cuò)誤碼可能為下述幾種:

* OS_NO_ERR :消息被正確地接受。

* OS_TIMEOUT :消息沒(méi)有在指定的時(shí)鐘周期數(shù)內(nèi)接收到消息。

* OS_ERR_PEND_ISR :從中斷調(diào)用該函數(shù)。雖然規(guī)定了不允許從中斷中調(diào)用該函數(shù),但μC/OS-Ⅱ仍然包含了檢測(cè)這種情況的功能。

* OS_ERR_EVENT_TYPE :pevent 不是指向消息隊(duì)列的指針。

12345678

4、返回值說(shuō)明:OSQPend() 函數(shù)返回取得的消息并將 *err 置為 OS_NO_ERR。如果沒(méi)有在指定數(shù)目的時(shí)鐘節(jié)拍內(nèi)接受到消息,OSQPend() 函數(shù)返回空指針并將 *err 設(shè)置為 OS_TIMEOUT。

5、函數(shù)主體在os_q.c中

其他的消息函數(shù)

INT8U OSQPost (OS_EVENT *pevent, void *msg)

發(fā)送一個(gè)消息到消息隊(duì)列 FIFO模式

INT8U OSQPostFront (OS_EVENT *pevent, void *msg)

發(fā)送一個(gè)消息到消息隊(duì)列 FIFO模式

void *OSQAccept (OS_EVENT *pevent)

無(wú)等待地從消息隊(duì)列中得到一個(gè)消息

INT8U OSQFlush (OS_EVENT *pevent)

清空一個(gè)消息隊(duì)列

INT8U OSQQuery (OS_EVENT *pevent, OS_Q_DATA *pdata)

查詢一個(gè)消息隊(duì)列的當(dāng)前狀態(tài)

使用消息隊(duì)列的通常步驟為:

1)定義指針: OS_EVENT *proSQ

定義指針數(shù)組: void *start[4]

2) 在主程序中建立信號(hào)列隊(duì):*proSQ = OSQCreate(start,4);

3)在任務(wù)中等待消息列隊(duì)中得到消息或者給消息列隊(duì)發(fā)送消息

12345678910111213141516

內(nèi)存管理:參考于:μC/OS-II學(xué)習(xí)筆記四(內(nèi)存管理)注:以下都為轉(zhuǎn)載;

在ANSI C中可以用malloc()和free()兩個(gè)函數(shù)動(dòng)態(tài)地分配內(nèi)存和釋放內(nèi)存。但是,在嵌入式實(shí)時(shí)操作系統(tǒng)中,多次這樣做會(huì)把原來(lái)很大的一塊連續(xù)內(nèi)存區(qū)域,逐漸地分割成許多非常小而且彼此又不相鄰的內(nèi)存區(qū)域,也就是內(nèi)存碎片。由于這些碎片的大量存在,使得程序到后來(lái)連非常小的內(nèi)存也分配不到。另外,由于內(nèi)存管理算法的原因,malloc()和free()函數(shù)執(zhí)行時(shí)間是不確定的。[!--empirenews.page--]

在μC/OS-II中,操作系統(tǒng)把連續(xù)的大塊內(nèi)存按分區(qū)來(lái)管理。每個(gè)分區(qū)中包含有整數(shù)個(gè)大小相同的內(nèi)存塊。利用這種機(jī)制,μC/OS-II 對(duì)malloc()和free()函數(shù)進(jìn)行了改進(jìn),使得它們可以分配和釋放固定大小的內(nèi)存塊。這樣一來(lái),malloc()和free()函數(shù)的執(zhí)行時(shí)間也是固定的了。

在一個(gè)系統(tǒng)中可以有多個(gè)內(nèi)存分區(qū)。這樣,用戶的應(yīng)用程序就可以從不同的內(nèi)存分區(qū)中得到不同大小的內(nèi)存塊。但是,特定的內(nèi)存塊在釋放時(shí)必須重新放回它以前所屬于的內(nèi)存分區(qū)。顯然,采用這樣的內(nèi)存管理算法,上面的內(nèi)存碎片問(wèn)題就得到了解決。

內(nèi)存控制塊

為了便于內(nèi)存的管理,在μC/OS-II中使用內(nèi)存控制塊(memory control blocks)的數(shù)據(jù)結(jié)構(gòu)來(lái)跟蹤每一個(gè)內(nèi)存分區(qū),系統(tǒng)中的每個(gè)內(nèi)存分區(qū)都有它自己的內(nèi)存控制塊。

內(nèi)存控制塊的定義如下:

typedef struct {

void *OSMemAddr; //指向內(nèi)存分區(qū)起始地址的指針

void *OSMemFreeList; //是指向下一個(gè)空閑內(nèi)存控制塊或者下一個(gè)空閑的內(nèi)存塊的指針

INT32U OSMemBlkSize; //是內(nèi)存分區(qū)中內(nèi)存塊的大小

INT32U OSMemNBlks; //內(nèi)存分區(qū)中總的內(nèi)存塊數(shù)量

INT32U OSMemNFree; //內(nèi)存分區(qū)中當(dāng)前可以得空閑內(nèi)存塊數(shù)量

} OS_MEM;

如果要在μC/OS-II中使用內(nèi)存管理,需要在OS_CFG.H文件中將開(kāi)關(guān)量OS_MEM_EN設(shè)置為1。這樣μC/OS-II 在啟動(dòng)時(shí)就會(huì)對(duì)內(nèi)存管理器進(jìn)行初始化[由OSInit()調(diào)用OSMemInit()實(shí)現(xiàn)]。常數(shù)OS_MAX_MEM_PART(見(jiàn)文件OS_CFG.H)定義了最大的內(nèi)存分區(qū)數(shù),該常數(shù)值最小應(yīng)為2。

OSMemCreate()內(nèi)存塊創(chuàng)建函數(shù)

1 主要作用: 該函數(shù)建立并初始化一個(gè)用于動(dòng)態(tài)內(nèi)存分配的區(qū)域,該內(nèi)存區(qū)域包含指定數(shù)目的、大小確定的內(nèi)存塊。應(yīng)用可以動(dòng)態(tài)申請(qǐng)這些內(nèi)存塊并在用完后將其釋放回這個(gè)內(nèi)存區(qū)域。該函數(shù)的返回值就是指向這個(gè)內(nèi)存區(qū)域控制塊的指針,并作為OSMemGet(),OSMemPut(),OSMemQuery() 等相關(guān)調(diào)用的參數(shù)。

2函數(shù)原型:OS_MEM *OSMemCreate( void *addr, INT32U nblks, INT32U blksize, INT8U *err );

3參數(shù)說(shuō)明:addr 建立的內(nèi)存區(qū)域的起始地址??梢允褂渺o態(tài)數(shù)組或在系統(tǒng)初始化時(shí)使用 malloc() 函數(shù)來(lái)分配這個(gè)區(qū)域的空間。

nblks 內(nèi)存塊的數(shù)目。每一個(gè)內(nèi)存區(qū)域最少需要定義兩個(gè)內(nèi)存塊。

blksize 每個(gè)內(nèi)存塊的大小,最小應(yīng)該能夠容納一個(gè)指針變量。

err 是指向包含錯(cuò)誤碼的變量的指針。Err可能是如下幾種情況:

OS_NO_ERR :成功建立內(nèi)存區(qū)域。

OS_MEM_INVALID_ADDR :非法地址,即地址為空指針。

OS_MEM_INVALID_PART :沒(méi)有空閑的內(nèi)存區(qū)域。

OS_MEM_INVALID_BLKS :沒(méi)有為內(nèi)存區(qū)域建立至少兩個(gè)內(nèi)存塊。

OS_MEM_INVALID_SIZE :內(nèi)存塊大小不足以容納一個(gè)指針變量。

4返回值:

OSMemCreate() 函數(shù)返回指向所創(chuàng)建的內(nèi)存區(qū)域控制塊的指針。如果創(chuàng)建失敗,函數(shù)返回空指針。

OSMemGet()函數(shù)

1 主要作用: 該函數(shù)用于從內(nèi)存區(qū)域分配一個(gè)內(nèi)存塊。用戶程序必須知道所建立的內(nèi)存塊的大小,并必須在使用完內(nèi)存塊后釋放它??梢远啻握{(diào)用 OSMemGet() 函數(shù)。它的返回值就是指向所分配內(nèi)存塊的指針,并作為 OSMemPut() 函數(shù)的參數(shù)。

2函數(shù)原型:void *OSMemGet(OS_MEM *pmem, INT8U *err);

3參數(shù)說(shuō)明:pmem 是指向內(nèi)存區(qū)域控制塊的指針,可以從 OSMemCreate() 函數(shù)的返回值中得到。

err 是指向包含錯(cuò)誤碼的變量的指針。Err可能是如下情況:

OS_NO_ERR :成功得到一個(gè)內(nèi)存塊。

OS_MEM_NO_FREE_BLKS :內(nèi)存區(qū)域中已經(jīng)沒(méi)有足夠的內(nèi)存塊。

4返回值:

OSMemGet() 函數(shù)返回指向所分配內(nèi)存塊的指針。如果沒(méi)有可分配的內(nèi)存塊,OSMemGet() 函數(shù)返回空指針。

OSMemPut()

1 主要作用:該函數(shù)用于釋放一個(gè)內(nèi)存塊,內(nèi)存塊必須釋放回它原先所在的內(nèi)存區(qū)域,否則會(huì)造成系統(tǒng)錯(cuò)誤。

2函數(shù)原型:INT8U OSMemPut (OS_MEM *pmem, void *pblk);

3參數(shù)說(shuō)明:pmem 是指向內(nèi)存區(qū)域控制塊的指針,可以從 OSMemCreate() 函數(shù)的返回值中得到。

pblk 是指向?qū)⒈会尫诺膬?nèi)存塊的指針。

4返回值:

OSMemPut() 函數(shù)的返回值為下述之一:

OS_NO_ERR :成功釋放內(nèi)存塊

OS_MEM_FULL :內(nèi)存區(qū)域已滿,不能再接受更多釋放的內(nèi)存塊。這種情況說(shuō)明用戶程序出現(xiàn)了錯(cuò)誤,釋放了多于用 OSMemGet() 函數(shù)得到的內(nèi)存塊。

OSMemQuery()

1 主要作用:該函數(shù)用于得到內(nèi)存區(qū)域的信息。

2函數(shù)原型:INT8U OSMemQuery(OS_MEM *pmem, OS_MEM_DATA *pdata);

3參數(shù)說(shuō)明:pmem 是指向內(nèi)存區(qū)域控制塊的指針,可以從 OSMemCreate() 函數(shù)的返回值中得到。

pdata 是一個(gè)指向 OS_MEM_DATA 數(shù)據(jù)結(jié)構(gòu)的指針,該數(shù)據(jù)結(jié)構(gòu)包含了以下的域:

void OSAddr; /* 指向內(nèi)存區(qū)域起始地址的指針 */

void OSFreeList; /* 指向空閑內(nèi)存塊列表起始地址的指針 */

INT32U OSBlkSize; /* 每個(gè)內(nèi)存塊的大小 */

INT32U OSNBlks; /* 該內(nèi)存區(qū)域中的內(nèi)存塊總數(shù) */

INT32U OSNFree; /* 空閑的內(nèi)存塊數(shù)目 */

INT32U OSNUsed; /* 已使用的內(nèi)存塊數(shù)目 */

參考文章:

1、 uC/OS II 函數(shù)說(shuō)明 之–OSTaskCreate()與OSTaskCreateExt()

2、uC-OS-II_中文手冊(cè)

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開(kāi)發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開(kāi)幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉