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

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

1、OSAL主循環(huán)流程  2010-04-24 11:55:44|  分類: Zigbee|舉報|字號 訂閱我使用的協(xié)議棧版本及例子信息:ZigBee2006Texas InstrumentsZStack-1.4.3-1.2.1ProjectszstackSamplesSampleApp接上篇OSAL初始化流程.記錄下個人對OSAL主循環(huán)流程的學習:/-/-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)語句:tasksEventsidx是一個指針變量,指向存放任務idx的存儲空間,初始化時由/osal_memset()設為0,只要不為空類型NULL,/即有相對應任務事件發(fā)生,就break跳出循環(huán)體,通過下面的程序進行任務事件處理。/如果為空,執(zhí)行判斷語句,即idx自增,再返回輪詢有無各層的任務事件發(fā)生。如果/執(zhí)行完循環(huán)語句都沒有檢測到有事件發(fā)生,i

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

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

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

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

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

9、0;                                                 

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

11、                                           /把剛才返回未處理的任務事件添加加當前任務中再進行處理   &#

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

13、sksCnt)循環(huá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    說明:(1)OSAL調(diào)用Hal_ProcessPoll(); 來輪詢UART與TIMER,涉及HAL層,晚點總結.(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、; )  /關中斷#define HAL_INTERRUPTS_ARE_ENABLED()    (EA)typedef unsigned char halIntState_t;  /中斷位狀態(tài)/中斷臨界狀態(tài):把原先中斷狀態(tài)EA賦給X,然后關中斷;以便后面可以恢復原先的中斷狀態(tài)                     

18、     #define HAL_ENTER_CRITICAL_SECTION(x)   st( x = EA;  HAL_DISABLE_INTERRUPTS(); )/跳出上面的中斷臨界狀態(tài),恢復先前的中斷狀態(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;       個人認為,tasksEvents 是一個指針數(shù)組(但是在協(xié)議棧里對這個“數(shù)組”的定義我還沒有找到,只是在OSAL_SampleApp.c下有這么一個聲明:uint16 *tasksEvents;以及系統(tǒng)任務初始函數(shù)下對tasksEvents的定義),內(nèi)部各元素都是指向uint16類型變量的指針變量(對于本例子來說內(nèi)部各元素即tasksEvents0tasksEvents6;tasksEvents0指向任務1的存儲空間),對even

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

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

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

26、的指針X,則當X獲得函數(shù)的地址后,就可以像調(diào)用/原來函數(shù)一樣來使用這個函數(shù)指針X(task_id,event),如上面的pTaskEventHandlerFn tasksArr /因此tasksArr 是一個指針數(shù)組,其內(nèi)部的各元素都是指針,從OSAL_SampleApp.c中對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),而這些任務事件處理/函數(shù)都是uint16類型的.因此osal_start_system()里可以events = (tasksArridx)( idx, events );events也是uint16類型的。語法上來解釋我自己都一團霧水了,個人想法,不一定正確  /typedef unsigned

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

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

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

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

32、msg_receive( SampleApp_TaskID );  /接收屬于本應用任務SampleApp的消息(SampleApp_TaskID標記。    while ( MSGpkt )  /接收到                           &

33、#160;                                                 &

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

35、;                   / Received when a key is pressed /*小事件:按鍵事件*/  如果一個OSAL任務已經(jīng)被登記注冊,那么任何鍵盤事件都將接受一個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ù)對收到的數(shù)據(jù)進行處理          break;                  / Received whenever the device changes state in the network  /*小事件:設備網(wǎng)絡狀

41、態(tài)變化事件*/  只要網(wǎng)絡狀態(tài)發(fā)生改變,就通過ZDO_STATE_CHANGE事件通知所有的任務,注意,是所有任務都會收到這消息。        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);  /獲取設備當前狀態(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;           /*按一定間隔啟動定時器*/            /這個定時器是為發(fā)送周期信息設置的,我覺得因為在這個例子中,用戶自己添加的任務,只有兩個事件是用于向外發(fā)送消息的,一個是發(fā)送flash閃爍消息,屬于組尋址,而另一個是發(fā)送periodic周期消息,屬于廣播;這里是一個設備的網(wǎng)絡狀態(tài)發(fā)生了變化,必須要告訴同一網(wǎng)絡中的其它設備,因此要進行廣播

45、通知其它設備發(fā)送的消息中應該會包括本設備的類型。不知道這樣理解對不對管它的,以后會明白的/更新:這個定時器只是為發(fā)送周期信息開啟的,設備啟動初始化后從這里開始觸發(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)消息這個大事件處理完了,釋放消息占用的內(nèi)存      osal_msg_deallocate( (uint8 *)MSGpkt );      / Next - if one is available      /*指針指向下一個"已接收到的”程序在while ( MSGpkt )內(nèi)放在緩沖區(qū)的待處理的事件,與  &

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

溫馨提示

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

評論

0/150

提交評論