OSAL主循環(huán)流程課件_第1頁(yè)
OSAL主循環(huán)流程課件_第2頁(yè)
OSAL主循環(huán)流程課件_第3頁(yè)
OSAL主循環(huán)流程課件_第4頁(yè)
OSAL主循環(huán)流程課件_第5頁(yè)
已閱讀5頁(yè),還剩3頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、OSAL主循環(huán)流程  2010-04-24 11:55:44|  分類: Zigbee|舉報(bào)|字號(hào) 訂閱我使用的協(xié)議棧版本及例子信息:ZigBee2006Texas InstrumentsZStack-1.4.3-1.2.1ProjectszstackSamplesSampleApp接上篇OSAL初始化流程.記錄下個(gè)人對(duì)OSAL主循環(huán)流程的學(xué)習(xí):/-/-OSAL系統(tǒng)主循環(huán)函數(shù):void osal_start_system( void )#if !defined ( ZBIT )  /不知道是什么東西  f

2、or(;)   / Forever Loop#endif      uint8 idx = 0;    Hal_ProcessPoll();  / This replaces MT_SerialPoll() and osal_check_timer().                   

3、;                  /輪詢TIMER與UART/-/執(zhí)行循環(huán)語(yǔ)句:tasksEventsidx是一個(gè)指針變量,指向存放任務(wù)idx的存儲(chǔ)空間,初始化時(shí)由/osal_memset()設(shè)為0,只要不為空類型NULL,/即有相對(duì)應(yīng)任務(wù)事件發(fā)生,就break跳出循環(huán)體,通過下面的程序進(jìn)行任務(wù)事件處理。/如果為空,執(zhí)行判斷語(yǔ)句,即idx自增,再返回輪詢有無(wú)各層的任務(wù)事件發(fā)生。如果/執(zhí)行完循環(huán)語(yǔ)句都沒有檢測(cè)到有事件發(fā)生,i

4、dx=7,進(jìn)入睡眠。(對(duì)于本例子來(lái)說(shuō),任務(wù)數(shù)組里只有七個(gè)任務(wù),tasksEvents0tasksEvents6,tasksEvents6就是用戶自已添加的任務(wù),idx隨著用戶添加任務(wù)的增多而增大)    do       if (tasksEventsidx)  / Task is highest priority that is ready.             

5、0;                      break;                        while (+idx < tasksCnt);

6、0;/tasksCnt=7(針對(duì)本例子,隨著用戶應(yīng)用任務(wù)增多而增大)/-    if (idx < tasksCnt)          uint16 events;      halIntState_t intState;  /中斷位狀態(tài)      HAL_ENTER_CRITICAL_SECTION(intState);  &#

7、160;/中斷臨界狀態(tài):保存先前中斷狀態(tài),然后關(guān)中斷      events = tasksEventsidx;  /uint16 events;對(duì)應(yīng)有事件發(fā)生的任務(wù)的數(shù)組      tasksEventsidx = 0;  / Clear the Events for this task.  NULL      HAL_EXIT_CRITICAL_SECTION(intState);&

8、#160; /跳出中斷臨界狀態(tài):恢復(fù)先前中斷狀態(tài)          events = (tasksArridx)( idx, events );   /調(diào)用相對(duì)應(yīng)的任務(wù)事件處理函數(shù)處理,各類事件處理函                     

9、0;                                                 

10、0;  /數(shù)M(task_id,event)返回的都是這個(gè)任務(wù)未被處理的事件      HAL_ENTER_CRITICAL_SECTION(intState);      tasksEventsidx |= events;    / Add back unprocessed events to the current task.         

11、                                           /把剛才返回未處理的任務(wù)事件添加加當(dāng)前任務(wù)中再進(jìn)行處理   &#

12、160;                                               /(跳出此if(idx < ta

13、sksCnt)循環(huán)再進(jìn)行if (tasksEventsidx)判斷并處理)      HAL_EXIT_CRITICAL_SECTION(intState);      #if defined( POWER_SAVING )    else   / Complete pass through all task events with no activity?      

14、0;   osal_pwrmgr_powerconserve();  / Put the processor/system into sleep    #endif    說(shuō)明:(1)OSAL調(diào)用Hal_ProcessPoll(); 來(lái)輪詢UART與TIMER,涉及HAL層,晚點(diǎn)總結(jié).(2)HAL_ENTER_CRITICAL_SECTION(intState);   與HAL_EXIT_CRITICAL_SECTION(intState); 

15、見1;(3)events = tasksEventsidx;   tasksEventsidx = 0; 見2;(4) events = (tasksArridx)( idx, events ); 見3;(5)tasksEventsidx |= events;  見4;/-/-1、HAL_ENTER_CRITICAL_SECTION(intState)與HAL_EXIT_CRITICAL_SECTION(intState)定義在hal_mcu.h中,如下:/* - *    

16、             Interrupt Macros * - */#define HAL_ENABLE_INTERRUPTS()         st( EA = 1; )  /開中斷#define HAL_DISABLE_INTERRUPTS()        st( EA = 0

17、; )  /關(guān)中斷#define HAL_INTERRUPTS_ARE_ENABLED()    (EA)typedef unsigned char halIntState_t;  /中斷位狀態(tài)/中斷臨界狀態(tài):把原先中斷狀態(tài)EA賦給X,然后關(guān)中斷;以便后面可以恢復(fù)原先的中斷狀態(tài)                     

18、     #define HAL_ENTER_CRITICAL_SECTION(x)   st( x = EA;  HAL_DISABLE_INTERRUPTS(); )/跳出上面的中斷臨界狀態(tài),恢復(fù)先前的中斷狀態(tài)                         

19、60;                                                 

20、60;             #define HAL_EXIT_CRITICAL_SECTION(x)    st( EA = x; )/中斷臨界狀態(tài)以及跳出臨界狀態(tài)的全過程:#define HAL_CRITICAL_STATEMENT(x)       st( halIntState_t s; HAL_ENTER_CRITICAL_SECTION(s); x; HAL_EX

21、IT_CRITICAL_SECTION(s); )st()函數(shù),定義在hal_defs.h中: *  This macro is for use by other macros to form a fully valid C statement. *  Without this, the if/else conditionals could show unexpected behavior.#define st(x)      do x while (_LINE_ = -1)/-/- 2、eve

22、nts = tasksEventsidx; tasksEventsidx = 0;       個(gè)人認(rèn)為,tasksEvents 是一個(gè)指針數(shù)組(但是在協(xié)議棧里對(duì)這個(gè)“數(shù)組”的定義我還沒有找到,只是在OSAL_SampleApp.c下有這么一個(gè)聲明:uint16 *tasksEvents;以及系統(tǒng)任務(wù)初始函數(shù)下對(duì)tasksEvents的定義),內(nèi)部各元素都是指向uint16類型變量的指針變量(對(duì)于本例子來(lái)說(shuō)內(nèi)部各元素即tasksEvents0tasksEvents6;tasksEvents0指向任務(wù)1的存儲(chǔ)空間),對(duì)even

23、ts的聲明也是 uint16 events;。這里把有事件發(fā)生的任務(wù)idx的存儲(chǔ)空間的地址賦給events。然后清除任務(wù)idx的事件 tasksEventsidx = 0,(指針變量值為NULL)./-/- 3、 events = (tasksArridx)( idx, events );  任務(wù)idx的事件處理函數(shù)- 首先看下對(duì)tasksArr 的定義:const pTaskEventHandlerFn tasksArr = /數(shù)組tasksArr 有7個(gè)元素(MT defined)  mac

24、EventLoop,   /MAC層任務(wù)事件處理函數(shù)  nwk_event_loop,  /NWK層任務(wù)事件處理函數(shù)  Hal_ProcessEvent,  /PHY層事件處理函數(shù)#if defined( MT_TASK )  MT_ProcessEvent, /MT任務(wù)事件處理函數(shù)#endif  APS_event_loop,  /APS層任務(wù)事件處理函數(shù)  ZDApp_event_loop,  /ZDO任務(wù)事件處理函數(shù)&#

25、160; SampleApp_ProcessEvent  /用戶應(yīng)用任務(wù)事件處理函數(shù);-再來(lái)看下對(duì)pTaskEventHandlerFn 的定義:(OSAL_Tasks.h中)typedef unsigned short (*pTaskEventHandlerFn)( unsigned char task_id, unsigned short event );/前面有個(gè)typedef,把pTaskEventHandlerFn聲明成一種函數(shù)指針類型的別名/這種函數(shù)指針指向M(task_id,event)這種類型的函數(shù)(即各任務(wù)的事件處理函數(shù))/如果用這個(gè)別名來(lái)生成一個(gè)指向函數(shù)

26、的指針X,則當(dāng)X獲得函數(shù)的地址后,就可以像調(diào)用/原來(lái)函數(shù)一樣來(lái)使用這個(gè)函數(shù)指針X(task_id,event),如上面的pTaskEventHandlerFn tasksArr /因此tasksArr 是一個(gè)指針數(shù)組,其內(nèi)部的各元素都是指針,從OSAL_SampleApp.c中對(duì)tasksArr /的定義我們可以知道m(xù)acEventLoop,nwk_event_loop一直到SampleApp_ProcessEvent這些元素都是/指針變量,最終都是指向M(task_id,event)這種類型的函數(shù),也就是各層的事件處理函數(shù)。/另外我覺得,就像 pTaskEventHandlerFn task

27、sArr ;之后可以通過tasksArr 直接/調(diào)用tasksArr (task_id,event),也可以通過tasksArr 里面的元素直接調(diào)用/macEventLoop(task_id,event).SampleApp_ProcessEvent(task_id,event),而這些任務(wù)事件處理/函數(shù)都是uint16類型的.因此osal_start_system()里可以events = (tasksArridx)( idx, events );events也是uint16類型的。語(yǔ)法上來(lái)解釋我自己都一團(tuán)霧水了,個(gè)人想法,不一定正確  /typedef unsigned

28、 short  uint16;/typedef unsigned char   uint8;-這里events = (tasksArridx)( idx, events ); 是因?yàn)槊恳粋€(gè)任務(wù)的事件處理函數(shù)返回的都是這個(gè)任務(wù)沒有被處理完成的事件。比如說(shuō)用戶應(yīng)用任務(wù)的事件處理函數(shù):SampleApp_ProcessEvent( uint8 task_id, uint16 events ),如下:每個(gè)任務(wù)都有不同的事件,因此在進(jìn)行事件的處理前要進(jìn)行判斷,對(duì)于SampleApp大事件1_接收系統(tǒng)消息:(a)_按鍵小事件(包含了組發(fā)送flash消息事件和進(jìn)組退組

29、事件)                                         (b)_接收數(shù)據(jù)小事件      

30、0;                                   (c)_設(shè)備網(wǎng)絡(luò)狀態(tài)變化小事件大事件2_向外發(fā)送消息:(a)_發(fā)送 periodic 消息  下面的SampleApp_ProcessEvent()就是通過上面的順序

31、對(duì)用戶添加的應(yīng)用任務(wù)進(jìn)行事件的輪詢:uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events )  afIncomingMSGPacket_t *MSGpkt;  /接收到的消息   /*如果大事件是接收系統(tǒng)消息*/   /則接收系統(tǒng)消息再進(jìn)行判斷  if ( events & SYS_EVENT_MSG )      MSGpkt = (afIncomingMSGPacket_t *)osal_

32、msg_receive( SampleApp_TaskID );  /接收屬于本應(yīng)用任務(wù)SampleApp的消息(SampleApp_TaskID標(biāo)記。    while ( MSGpkt )  /接收到                           &

33、#160;                                                 &

34、#160;                                        switch ( MSGpkt->hdr.event ) /系統(tǒng)消息的進(jìn)一步判斷   

35、;                   / Received when a key is pressed /*小事件:按鍵事件*/  如果一個(gè)OSAL任務(wù)已經(jīng)被登記注冊(cè),那么任何鍵盤事件都將接受一個(gè)KEY_CHANGE事件信息。        case KEY_CHANGE:    

36、60; /#define KEY_CHANGE  0xC0   -Key Events          SampleApp_HandleKeys( (keyChange_t *)MSGpkt)->state, (keyChange_t *)MSGpkt)->keys );          break;     &

37、#160;                                       /執(zhí)行具體的按鍵處理函數(shù),定義在sampleAPP.c中      &#

38、160;             / Received when a messages is received (OTA:over the air) for this endpoint                        

39、;      /*小事件:接收數(shù)據(jù)事件*/  接收數(shù)據(jù)事件,調(diào)用函數(shù)AF_DataRequest()接收數(shù)據(jù)        case AF_INCOMING_MSG_CMD: / #define AF_INCOMING_MSG_CMD  0x 1A  -Incoming MSG type message          SampleAp

40、p_MessageMSGCB( MSGpkt );  /調(diào)用回調(diào)函數(shù)對(duì)收到的數(shù)據(jù)進(jìn)行處理          break;                  / Received whenever the device changes state in the network  /*小事件:設(shè)備網(wǎng)絡(luò)狀

41、態(tài)變化事件*/  只要網(wǎng)絡(luò)狀態(tài)發(fā)生改變,就通過ZDO_STATE_CHANGE事件通知所有的任務(wù),注意,是所有任務(wù)都會(huì)收到這消息。        case ZDO_STATE_CHANGE:   /#define ZDO_STATE_CHANGE  0xD1  -ZDO has changed the device's network state          Sa

42、mpleApp_NwkState = (devStates_t)(MSGpkt->hdr.status);  /獲取設(shè)備當(dāng)前狀態(tài)          if ( (SampleApp_NwkState = DEV_ZB_COORD)              | (SampleApp_NwkState = DEV_ROUTER)  &#

43、160;           | (SampleApp_NwkState = DEV_END_DEVICE) )                       / Start sending the periodic message in a regular interval.&#

44、160;           /*按一定間隔啟動(dòng)定時(shí)器*/            /這個(gè)定時(shí)器是為發(fā)送周期信息設(shè)置的,我覺得因?yàn)樵谶@個(gè)例子中,用戶自己添加的任務(wù),只有兩個(gè)事件是用于向外發(fā)送消息的,一個(gè)是發(fā)送flash閃爍消息,屬于組尋址,而另一個(gè)是發(fā)送periodic周期消息,屬于廣播;這里是一個(gè)設(shè)備的網(wǎng)絡(luò)狀態(tài)發(fā)生了變化,必須要告訴同一網(wǎng)絡(luò)中的其它設(shè)備,因此要進(jìn)行廣播

45、通知其它設(shè)備發(fā)送的消息中應(yīng)該會(huì)包括本設(shè)備的類型。不知道這樣理解對(duì)不對(duì)管它的,以后會(huì)明白的/更新:這個(gè)定時(shí)器只是為發(fā)送周期信息開啟的,設(shè)備啟動(dòng)初始化后從這里開始觸發(fā)第一個(gè)周期信息的發(fā)送,然后周而復(fù)始下去.            osal_start_timerEx( SampleApp_TaskID,                

46、;              SAMPLEAPP_SEND_PERIODIC_MSG_EVT,                              SAMPLEAPP_SEN

47、D_PERIODIC_MSG_TIMEOUT );                    else                      / Device is no longer in the network

48、60;                   break;        default:          break;            / Release the

49、 memory      /以上把收到系統(tǒng)消息這個(gè)大事件處理完了,釋放消息占用的內(nèi)存      osal_msg_deallocate( (uint8 *)MSGpkt );      / Next - if one is available      /*指針指向下一個(gè)"已接收到的”程序在while ( MSGpkt )內(nèi)放在緩沖區(qū)的待處理的事件,與  &

50、#160;   / SampleApp_ProcessEvent處理多個(gè)事件相對(duì)應(yīng),返回while ( MSGpkt )重新處理事件,      /直到緩沖區(qū)沒有等待處理事件為止。*/      MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID );        / return unprocessed events    / 兩者相異或,返回未處理的事件,return到osal_start_system()下的events = (tasksArridx)( idx, events )語(yǔ)句中,重新在osal_start_system()下輪詢?cè)龠M(jìn)入此函數(shù)進(jìn)行處理。    return (events SYS_EVENT_MSG);    /-    / Send a message o

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論