色婷婷AⅤ一区二区三区|亚洲精品第一国产综合亚AV|久久精品官方网视频|日本28视频香蕉

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 關(guān)于ucos中os_tmr.c中的代碼分析

          關(guān)于ucos中os_tmr.c中的代碼分析

          作者: 時(shí)間:2016-11-24 來(lái)源:網(wǎng)絡(luò) 收藏
          我本身也是個(gè)初學(xué)者,喜歡嵌入式而自學(xué)ucos系統(tǒng),ucos是個(gè)開源的代碼,短小而又簡(jiǎn)單,這是我學(xué)習(xí)的筆記,希望能對(duì)喜歡ucos的人有一點(diǎn)幫助,因本人也是初學(xué)者,如有錯(cuò)誤迎指點(diǎn)。一般的書多是2.5版本,沒有os_tmr.c,所以我寫了關(guān)于這部分代碼的分析。
          我讀ucos.中的os_tmr.c:
          我想這個(gè)文件里就是為了寫一個(gè)建立在操作系統(tǒng)的定時(shí)器,原來(lái)我們學(xué)的時(shí)鐘節(jié)拍就像cpu總線時(shí)鐘脈沖一樣。我們建立的是定時(shí)器結(jié)構(gòu)體,在os_tmr.c中有一個(gè)函數(shù)OSTmr_Task()這個(gè)函數(shù)對(duì)定時(shí)器結(jié)構(gòu)體的信息進(jìn)行處理,在定時(shí)時(shí)間到了時(shí)候,該定時(shí)器中的一個(gè)指向回調(diào)函數(shù)的指針就調(diào)用這個(gè)回調(diào)節(jié)器函數(shù)進(jìn)行工作,當(dāng)然,你要寫回調(diào)函數(shù),不然就什么也不做,以前做過ucos移植的人知道要寫一個(gè)硬件定時(shí)器中斷函數(shù),這回要加個(gè)OSTmrSignal()這里有個(gè)發(fā)送信號(hào)。我們學(xué)硬件時(shí)知道,用到硬件定時(shí)器時(shí)要給它一個(gè)計(jì)算脈沖。這個(gè)軟件定時(shí)器也要一個(gè)計(jì)算脈沖。我們建立的定時(shí)器結(jié)構(gòu)體都會(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]上可以掛很多個(gè)定時(shí)器結(jié)構(gòu)體。
          一、定時(shí)器的建立:
          定時(shí)器是在我們的應(yīng)用程序中建立的,
          OS_TMR *OSTmrCreate (INT32U dly,
          INT32U period,
          INT8U opt,
          OS_TMR_CALLBACK callback,
          void *callback_arg,
          INT8U *pname,
          INT8U *perr)
          想使用定時(shí)器那些函數(shù)要在os_cfg.h中定義 OS_TMR_EN。
          返回值是os_tmr結(jié)構(gòu)體(定義在ucos_ii.h中)。
          typedef struct os_tmr {
          INT8U OSTmrType;
          OS_TMR_CALLBACK OSTmrCallback;
          void *OSTmrCallbackArg;
          void *OSTmrNext;
          void *OSTmrPrev;
          INT32U OSTmrMatch; 當(dāng) 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類型定義在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中有以下幾種類型:
          OS_TMR_STATE_UNUSED 不存在這個(gè)定時(shí)器
          OS_TMR_STATE_RUNNING 這個(gè)定時(shí)器正在運(yùn)行
          OS_TMR_STATE_COMPLETED這個(gè)定時(shí)器已經(jīng)跑完了
          OS_TMR_STATE_STOPPED 這個(gè)定時(shí)器停止了
          參數(shù):
          1. Dly 定時(shí)時(shí)間,如果是這個(gè)定時(shí)器只用一次,那么就用這個(gè),如果定時(shí)器要反復(fù)用那么它是第一次時(shí)用,以后用period。
          2. Period 定時(shí)器從復(fù)用時(shí)會(huì)用到這個(gè)作定時(shí)時(shí)間。
          3. Opt 這里有兩種選項(xiàng),告訴我們是只用一次還是反復(fù)使用。只用一次OS_TMR_OPT_ONE_SHOT,反復(fù)使用OS_TMR_OPT_PERIODIC。這些定義在ucos_ii.h中。
          定時(shí)器選項(xiàng)有五種
          #define OS_TMR_OPT_NONE 0u 沒有選擇
          #define OS_TMR_OPT_ONE_SHOT 1u 定時(shí)器不會(huì)自動(dòng)重復(fù)使用
          #define OS_TMR_OPT_PERIODIC 2u 定時(shí)器會(huì)自動(dòng)重裝
          #define OS_TMR_OPT_CALLBACK 3u OSTmrStop()中使用,調(diào)用回調(diào)函數(shù),但不帶參數(shù)
          #define OS_TMR_OPT_CALLBACK_ARG 4u 也是OSTmrStop()中使用,調(diào)用回調(diào)函數(shù),但有參數(shù)。
          1. Callback 指向回調(diào)函數(shù)的指針,這個(gè)函數(shù)這樣聲明,void mycallback(OS_TMR *ptmr, void p_arg );
          2. Callback_arg 參數(shù)給callback的。
          3. Pname 定時(shí)器的名字
          4. Perr 錯(cuò)誤指針* OS_ERR_NONE 沒有錯(cuò)誤
          OS_ERR_TMR_INVALID_DLY 無(wú)效的定時(shí)時(shí)間
          OS_ERR_TMR_INVALID_PERIOD 無(wú)效的周期
          OS_ERR_TMR_INVALID_OPT 無(wú)效的選項(xiàng)
          OS_ERR_TMR_ISR 在中斷中調(diào)用
          OS_ERR_TMR_NON_AVAIL 空的定時(shí)器用光了,這個(gè)和task一樣意思。
          用到的函數(shù)OSTmr_Alloc()得到一個(gè)定時(shí)器結(jié)構(gòu)體。
          二、刪除一個(gè)定時(shí)器,也是在我們的功能函數(shù)中使用,返回為是否成功刪除。
          BOOLEAN OSTmrDel (OS_TMR *ptmr,
          INT8U *perr)
          1. Ptmr 指向定時(shí)器結(jié)構(gòu)體。
          2. Perr 指向錯(cuò)誤的指針。
          這里用到這兩個(gè)函數(shù)OSTmr_Unlink(ptmr); 如果是定時(shí)器在工作時(shí),要用它解除 OSTmrState= OS_TMR_STATE_STOPPED。
          OSTmr_Free(ptmr); 釋放這個(gè)定時(shí)器結(jié)構(gòu)體。
          三、得到定時(shí)器名字的函數(shù),返回名字的長(zhǎng)度。
          INT8U OSTmrNameGet (OS_TMR *ptmr,
          INT8U **pdest, 指向了一個(gè)指向定時(shí)器名字地址指針的指針。
          INT8U *perr)
          四、定時(shí)器還有多長(zhǎng)時(shí)間溢出。返回還有多長(zhǎng)時(shí)間溢出。
          INT32U OSTmrRemainGet (OS_TMR *ptmr,
          INT8U *perr)
          五、獲得定時(shí)器狀態(tài)的函數(shù),返回狀態(tài)。
          INT8U OSTmrStateGet (OS_TMR *ptmr,
          INT8U *perr)
          六、啟動(dòng)你的定時(shí)器,返回是否成功啟動(dòng)。 你的應(yīng)用程序使用它
          BOOLEAN OSTmrStart (OS_TMR *ptmr, 要用到OSTmr_Unlink()和OSTmr_Link()先
          INT8U *perr)散 解除,再重新用這個(gè)定時(shí)器
          七、停止定時(shí)器,返回是否成功停止。 你的應(yīng)用程序使用它
          BOOLEAN OSTmrStop (OS_TMR *ptmr,
          INT8U opt,
          void *callback_arg, 這個(gè)也是個(gè)函數(shù)
          INT8U *perr)
          回調(diào)函數(shù)在這里使用,callback()。
          Opt 為OS_TMR_OPT_NONE不使用回調(diào)函數(shù)。
          OS_TMR_OPT_CALLBACK使用回調(diào)函數(shù)不用參數(shù)。
          OS_TMR_OPT_CALLBACK_ARG要使用參數(shù)。
          八、發(fā)送信號(hào),這個(gè)是在timer tick中使用要您寫到ISR中
          INT8U OSTmrSignal (void)返回信號(hào)量。
          九、從定時(shí)器池中得到一個(gè)結(jié)構(gòu)體。在建構(gòu)函數(shù)中用
          static OS_TMR *OSTmr_Alloc (void);
          十、釋放定時(shí)器,中刪除函數(shù)中用
          static void OSTmr_Free (OS_TMR *ptmr)
          十一、OSTmr_Init(void),在OSInit()中用。
          十二、static void OSTmr_InitTask (void)在OSTmr_Init中使用。用來(lái)建立一個(gè)任務(wù)OSTmr_Task()
          十三、OSTmr_Task()這個(gè)是調(diào)度你建立的定時(shí)器用的,一但定時(shí)時(shí)間到就調(diào)用回調(diào)函數(shù)。
          我們建立的定時(shí)器都進(jìn)入定時(shí)器輪盤里OSTmrWheelTbl[],
          十四、static void OSTmr_Link (OS_TMR *ptmr, //OSTmrState = OS_TMR_STATE_RUNNING
          INT8U type)
          Ptmr->OSTmrMatch的確定方法
          if (type == OS_TMR_LINK_PERIODIC) {
          ptmr->OSTmrMatch = ptmr->OSTmrPeriod + OSTmrTime;
          } else {
          if (ptmr->OSTmrDly == 0) {
          ptmr->OSTmrMatch = ptmr->OSTmrPeriod + OSTmrTime;
          } else {
          ptmr->OSTmrMatch = ptmr->OSTmrDly + OSTmrTime;
          }
          }
          掛載定時(shí)器時(shí)spoke = (INT16U)(ptmr->OSTmrMatch % OS_TMR_CFG_WHEEL_SIZE);
          pspoke = &OSTmrWheelTbl[spoke];這樣確定的置位,當(dāng)OSTmrTime加到和OSTmrMatch相等時(shí)一定會(huì)來(lái)以這個(gè)spoke為下標(biāo)的數(shù)組里找該定時(shí)器。至于定義一個(gè)OSTmrWheelTbl[]而不是把你所有建立的定時(shí)器串成一串是怕一起處理浪費(fèi)時(shí)間吧,這樣可以一次少處理幾個(gè)定時(shí)器。
          我想看了OSTmr_Task (void *p_arg)這個(gè)函數(shù)的人可能會(huì)好奇為什么用那種方法掛載定時(shí)器,當(dāng)定時(shí)時(shí)間到了時(shí)會(huì)找到OSTmrWheelTbl[]正確的下標(biāo),并在那個(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]中,當(dāng)OSTmrTime加到18時(shí)它就會(huì)去
          OSTmrWheelTbl[2]找該定時(shí)器。
          十五、static void OSTmr_Unlink (OS_TMR *ptmr)釋放定時(shí)器結(jié)構(gòu)體用它把該定時(shí)器從定時(shí)器輪中卸下。


          關(guān)鍵詞: ucosos_tmrc代碼分

          評(píng)論


          技術(shù)專區(qū)

          關(guān)閉