關(guān)于ucos中os_tmr.c中的代碼分析
我本身也是個(gè)初學(xué)者,喜歡嵌入式而自學(xué)ucos系統,ucos是個(gè)開(kāi)源的代碼,短小而又簡(jiǎn)單,這是我學(xué)習的筆記,希望能對喜歡ucos的人有一點(diǎn)幫助,因本人也是初學(xué)者,如有錯誤迎指點(diǎn)。一般的書(shū)多是2.5版本,沒(méi)有os_tmr.c,所以我寫(xiě)了關(guān)于這部分代碼的分析。
我讀ucos.中的os_tmr.c:
我想這個(gè)文件里就是為了寫(xiě)一個(gè)建立在操作系統的定時(shí)器,原來(lái)我們學(xué)的時(shí)鐘節拍就像cpu總線(xiàn)時(shí)鐘脈沖一樣。我們建立的是定時(shí)器結構體,在os_tmr.c中有一個(gè)函數OSTmr_Task()這個(gè)函數對定時(shí)器結構體的信息進(jìn)行處理,在定時(shí)時(shí)間到了時(shí)候,該定時(shí)器中的一個(gè)指向回調函數的指針就調用這個(gè)回調節器函數進(jìn)行工作,當然,你要寫(xiě)回調函數,不然就什么也不做,以前做過(guò)ucos移植的人知道要寫(xiě)一個(gè)硬件定時(shí)器中斷函數,這回要加個(gè)OSTmrSignal()這里有個(gè)發(fā)送信號。我們學(xué)硬件時(shí)知道,用到硬件定時(shí)器時(shí)要給它一個(gè)計算脈沖。這個(gè)軟件定時(shí)器也要一個(gè)計算脈沖。我們建立的定時(shí)器結構體都會(huì )掛到OSTmrWheelTbl[OS_TMR_CFG_WHEEL_SIZE]上面,OS_TMR_CFG_WHEEL+SIZE是要自己定義的,至于掛到OSTmrWheelTbl[0] 到OSTmrWheelTbl[OS_TMR_CFG_WHEEL_SIZE-1]哪一個(gè)上,只要看一下OSTmr_Link (OS_TMR *ptmr, INT8U type)就明白了,而且一個(gè)OSTmrWheelTbl[n]上可以?huà)旌芏鄠€(gè)定時(shí)器結構體。
一、定時(shí)器的建立:
定時(shí)器是在我們的應用程序中建立的,
OS_TMR *OSTmrCreate (INT32U dly,
INT32U period,
INT8U opt,
OS_TMR_CALLBACK callback,
void *callback_arg,
INT8U *pname,
INT8U *perr)
想使用定時(shí)器那些函數要在os_cfg.h中定義 OS_TMR_EN。
返回值是os_tmr結構體(定義在ucos_ii.h中)。
typedef struct os_tmr {
INT8U OSTmrType;
OS_TMR_CALLBACK OSTmrCallback;
void *OSTmrCallbackArg;
void *OSTmrNext;
void *OSTmrPrev;
INT32U OSTmrMatch; 當 OSTmrTime == OSTmrMatch 定時(shí)器到時(shí)間了。
INT32U OSTmrDly;
INT32U OSTmrPeriod;
#if OS_TMR_CFG_NAME_EN > 0u
INT8U *OSTmrName;
#endif
INT8U OSTmrOpt;
INT8U OSTmrState;
} OS_TMR;
OSTmrType類(lèi)型定義在ucos_ii.h中:OS_TMR_TYPE
OS_ARG_CHK_EN要在os_cfg.h中定義一下,來(lái)確定要不要一些功能。
OS_TMR_CFG_NAME_EN要你自己在os_cfg.h中定義,來(lái)控制要不要用OSTmrName
OSTmrState在ucos_ii.h中有以下幾種類(lèi)型:
OS_TMR_STATE_UNUSED 不存在這個(gè)定時(shí)器
OS_TMR_STATE_RUNNING 這個(gè)定時(shí)器正在運行
OS_TMR_STATE_COMPLETED這個(gè)定時(shí)器已經(jīng)跑完了
OS_TMR_STATE_STOPPED 這個(gè)定時(shí)器停止了
參數:
我讀ucos.中的os_tmr.c:
一、定時(shí)器的建立:
OS_TMR
想使用定時(shí)器那些函數要在os_cfg.h中定義 OS_TMR_EN。
返回值是os_tmr結構體(定義在ucos_ii.h中)。
typedef
INT8U
OS_TMR_CALLBACK
void
void
INT32U
INT32U
INT32U
#if OS_TMR_CFG_NAME_EN > 0u
INT8U
#endif
INT8U
INT8U
} OS_TMR;
OSTmrType類(lèi)型定義在ucos_ii.h中:OS_TMR_TYPE
OS_ARG_CHK_EN要在os_cfg.h中定義一下,來(lái)確定要不要一些功能。
OS_TMR_CFG_NAME_EN要你自己在os_cfg.h中定義,來(lái)控制要不要用OSTmrName
OSTmrState在ucos_ii.h中有以下幾種類(lèi)型:
參數:
- Dly
定時(shí)時(shí)間,如果是這個(gè)定時(shí)器只用一次,那么就用這個(gè),如果定時(shí)器要反復用那么它是第一次時(shí)用,以后用period。 - Period
定時(shí)器從復用時(shí)會(huì )用到這個(gè)作定時(shí)時(shí)間。 - Opt
這里有兩種選項,告訴我們是只用一次還是反復使用。只用一次OS_TMR_OPT_ONE_SHOT,反復使用OS_TMR_OPT_PERIODIC。這些定義在ucos_ii.h中。
定時(shí)器選項有五種
#define OS_TMR_OPT_NONE 0u 沒(méi)有選擇
#define OS_TMR_OPT_ONE_SHOT 1u 定時(shí)器不會(huì )自動(dòng)重復使用
#define OS_TMR_OPT_PERIODIC 2u 定時(shí)器會(huì )自動(dòng)重裝
#define OS_TMR_OPT_CALLBACK 3u OSTmrStop()中使用,調用回調函數,但不帶參數
#define OS_TMR_OPT_CALLBACK_ARG 4u 也是OSTmrStop()中使用,調用回調函數,但有參數。
#define
#define
#define
#define
#define
- Callback
指向回調函數的指針,這個(gè)函數這樣聲明,void mycallback(OS_TMR *ptmr, void p_arg ); - Callback_arg
參數給callback的。 - Pname
定時(shí)器的名字 - Perr
錯誤指針* OS_ERR_NONE 沒(méi)有錯誤
用到的函數OSTmr_Alloc()得到一個(gè)定時(shí)器結構體。
二、刪除一個(gè)定時(shí)器,也是在我們的功能函數中使用,返回為是否成功刪除。
BOOLEAN
- Ptmr
指向定時(shí)器結構體。 - Perr
指向錯誤的指針。
三、得到定時(shí)器名字的函數,返回名字的長(cháng)度。
INT8U
四、定時(shí)器還有多長(cháng)時(shí)間溢出。返回還有多長(cháng)時(shí)間溢出。
INT32U
五、獲得定時(shí)器狀態(tài)的函數,返回狀態(tài)。
INT8U
六、啟動(dòng)你的定時(shí)器,返回是否成功啟動(dòng)。
BOOLEAN
七、停止定時(shí)器,返回是否成功停止。
BOOLEAN
回調函數在這里使用,callback()。
Opt 為OS_TMR_OPT_NONE不使用回調函數。
OS_TMR_OPT_CALLBACK使用回調函數不用參數。
OS_TMR_OPT_CALLBACK_ARG要使用參數。
八、發(fā)送信號,這個(gè)是在timer tick中使用要您寫(xiě)到ISR中
INT8U
九、從定時(shí)器池中得到一個(gè)結構體。在建構函數中用
static
十、釋放定時(shí)器,中刪除函數中用
static
十一、OSTmr_Init(void),在OSInit()中用。
十二、static
十三、OSTmr_Task()這個(gè)是調度你建立的定時(shí)器用的,一但定時(shí)時(shí)間到就調用回調函數。
我們建立的定時(shí)器都進(jìn)入定時(shí)器輪盤(pán)里OSTmrWheelTbl[],
十四、static
Ptmr->OSTmrMatch的確定方法
if (type == OS_TMR_LINK_PERIODIC) {
掛載定時(shí)器時(shí)spoke
pspoke = &OSTmrWheelTbl[spoke];這樣確定的置位,當OSTmrTime加到和OSTmrMatch相等時(shí)一定會(huì )來(lái)以這個(gè)spoke為下標的數組里找該定時(shí)器。至于定義一個(gè)OSTmrWheelTbl[]而不是把你所有建立的定時(shí)器串成一串是怕一起處理浪費時(shí)間吧,這樣可以一次少處理幾個(gè)定時(shí)器。
我想看了OSTmr_Task (void *p_arg)這個(gè)函數的人可能會(huì )好奇為什么用那種方法掛載定時(shí)器,當定時(shí)時(shí)間到了時(shí)會(huì )找到OSTmrWheelTbl[]正確的下標,并在那個(gè)OSTmrWheelTbl[ok]里找到該定時(shí)器吧。其實(shí)你可以算一下,定義OS_TMR_CFG_WHEEL_SIZE=8,然后在OSTmrTime=6時(shí)建立一個(gè)定時(shí)器(假如定時(shí)器只工作一次),OSTmrDly=12,那個(gè)這個(gè)定時(shí)器會(huì )掛到OSTmrWheelTbl[2]中,當OSTmrTime加到18時(shí)它就會(huì )去
OSTmrWheelTbl[2]找該定時(shí)器。
十五、static
評論