ZigBee 协议栈的调度顺序代码分析
#if 0=====================================================================
?
1 ZigBee 協議棧的調度順序?(第一節)
????? man() -> osal_init_system() -> osalIntTasks() -> SampleApp_Init()
????? (1)man() 函數完成芯片級的初始化 然后使程序進入 osal_init_system()
????? (2) osal_init_system()? 系統運行準備? 主要是任務的初始化 osalInitTasks()
?????????? ?void osalInitTasks( void )
???????????????? {
???????????????? ? uint8 taskID = 0;
?
???????????????? ? // 分配內存,返回指向緩沖區的指針
???????????????? ? tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);
???????????????? ? // 設置所分配的內存空間單元值為0
???????????????? ? osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt));
?
???????????????? ? // 任務優先級由高向低依次排列,高優先級對應taskID 的值反而小
???????????????? ? macTaskInit( taskID++ );?//macTaskInit(0),用戶不需考慮
???????????????? ? nwk_init( taskID++ );????//nwk_init(1),用戶不需考慮
???????????????? ? Hal_Init( taskID++ );????//Hal_Init(2),用戶需考慮
???????????????? #if defined( MT_TASK)
???????????????? ? MT_TaskInit( taskID++ );
???????????????? #endif
???????????????? ? APS_Init( taskID++ );?????//APS_Init(3),用戶不需考慮
???????????????? #if defined (ZIGBEE_FRAGMENTATION )
???????????????? ? APSF_Init( taskID++ );
???????????????? #endif
???????????????? ? ZDApp_Init( taskID++ );???//ZDApp_Init(4),用戶需考慮
???????????????? #if defined (ZIGBEE_FREQ_AGILITY ) || defined ( ZIGBEE_PANID_CONFLICT )
???????????????? ? ZDNwkMgr_Init( taskID++ );
???????????????? #endif
???????????????? ? //用戶創建的任務
???????????????? ? SampleApp_Init( taskID );?//SampleApp_Init _Init(5) ,用戶需考慮
???????????????? ? //=====================需要特別注意======================
???????????????? }
(3)void osal_start_system( void )???? //掃描任務
????? void osal_start_system( void )
?????????? {
?????????? #if !defined ( ZBIT ) &&!defined ( UBIT )
?????????? ? for(;;)? // Forever Loop
?????????? #endif
?????????? ? {
???????????????? osal_run_system();
?????????? ? }
?????????? }
?
????? void osal_run_system( void )
????? {
????? ? uint8 idx = 0;
?
????? ? osalTimeUpdate();???//掃描那個事件發生了重置相應的標志位
????? ? Hal_ProcessPoll();??//輪詢TIME 和UART
?
????? ? do {
?????????? if (tasksEvents[idx])? // Task is highest priority that is ready.
?????????? {
?????????? ? break;?????????????? ? // 得到最高優先級的任務ID號
?????????? }
????? ? } while (++idx < tasksCnt);
?
????? ? if (idx < tasksCnt)
????? ? {
?????????? uint16 events;
?????????? halIntState_t intState;
?
?????????? HAL_ENTER_CRITICAL_SECTION(intState);? //進入臨界區,保護? ???????
?????????? events = tasksEvents[idx];?? //提取需要處理任務的事件
?????????? tasksEvents[idx] = 0;????? // Clear the Events for this task.自己翻譯
?????????? HAL_EXIT_CRITICAL_SECTION(intState);? // 退出臨界區
?
?????????? activeTaskID = idx;
?????????? events = (tasksArr[idx])( idx, events );//通過指針調用任務處理函數,===關鍵=====
?????????? activeTaskID = TASK_NO_TASK;
?
?????????? HAL_ENTER_CRITICAL_SECTION(intState);?? // 進入臨界區
?????????? tasksEvents[idx] |= events;? // Add back unprocessed events(保存未處理事件) to the current task.
?????????? HAL_EXIT_CRITICAL_SECTION(intState);??? //退出臨界區
????? ? }
????? #if defined( POWER_SAVING )
????? ? else? // Complete passthrough all task events with no activity?
????? ? {
?????????? osal_pwrmgr_powerconserve();? // Put the processor/system into sleep
????? ? }
????? #endif
?
????? ? /* Yield in case cooperative scheduling is beingused. */
????? #if defined (configUSE_PREEMPTION)&& (configUSE_PREEMPTION == 0)
????? ? {
?????????? osal_task_yield();
????? ? }
????? #endif
????? }
?? //tasksEvents與taskID 一一對應
#if 0=================================================================
(4) SampleApp_Init( taskID );?//SampleApp_Init _Init(5) ,用戶需考慮
#endif=================================================================
?????
? void SampleApp_Init( uint8 task_id )
?????????? {
?????????? ? SampleApp_TaskID = task_id;??//osal分配的任務ID隨著用戶添加任務的增多而改變
?????????? ? SampleApp_NwkState = DEV_INIT;//設備狀態設定為ZDO層中定義的初始化狀態
?????????? ? SampleApp_TransID = 0;??????? //消息發送ID(多消息時有順序之分)
?
?????????? ?#if defined ( BUILD_ALL_DEVICES )
?????????? ? if ( readCoordinatorJumper() )
???????????????? zgDeviceLogicalType =ZG_DEVICETYPE_COORDINATOR;
?????????? ? else
???????????????? zgDeviceLogicalType =ZG_DEVICETYPE_ROUTER;
?????????? #endif // BUILD_ALL_DEVICES
?
?????????? //該段的意思是,如果設置了HOLD_AUTO_START宏定義,將會在啟動芯片的時候會暫停啟動
?????????? //流程,只有外部觸發以后才會啟動芯片。其實就是需要一個按鈕觸發它的啟動流程。?
?????????? #if defined ( HOLD_AUTO_START )
?????????? ? ZDOInitDevice(0);
?????????? #endif
?????????? ? // Setup for the periodic message's destinationaddress 設置發送數據的方式和目的地址尋址模式
?????????? ? // Broadcast to everyone 發送模式:廣播發送
?????????? ? SampleApp_Periodic_DstAddr.addrMode = (afAddrMode_t)AddrBroadcast;//廣播
?????????? ? SampleApp_Periodic_DstAddr.endPoint = SAMPLEAPP_ENDPOINT; //指定端點號
?????????? ? SampleApp_Periodic_DstAddr.addr.shortAddr = 0xFFFF;//指定目的網絡地址為廣播地址
?
?????????? ? // Setup for the flash command's destinationaddress - Group 1 組播發送
?????????? ? SampleApp_Flash_DstAddr.addrMode = (afAddrMode_t)afAddrGroup; //組尋址
????? ????? ? SampleApp_Flash_DstAddr.endPoint = SAMPLEAPP_ENDPOINT; //指定端點號
?????????? ? SampleApp_Flash_DstAddr.addr.shortAddr =SAMPLEAPP_FLASH_GROUP;//組號0x0001
?
?????????? ? // Fill out the endpoint description. 定義本設備用來通信的APS層端點描述符
?????????? ? SampleApp_epDesc.endPoint = SAMPLEAPP_ENDPOINT; //指定端點號
?????????? ? SampleApp_epDesc.task_id = &SampleApp_TaskID;?? //SampleApp 描述符的任務ID
?????????? ? SampleApp_epDesc.simpleDesc
??????????????????????????? = (SimpleDescriptionFormat_t*)&SampleApp_SimpleDesc;//SampleApp簡單描述符
?????????? ? SampleApp_epDesc.latencyReq = noLatencyReqs;??? //延時策略
?
?????????? ? // Register the endpoint description with the AF
?????????? ? afRegister( &SampleApp_epDesc );??? //向AF層登記描述符
?
?????????? ? // Register for all key events - This app willhandle all key events
?????????? ? RegisterForKeys( SampleApp_TaskID ); // 登記所有的按鍵事件
?
?????????? ? // By default, all devices start out in Group 1
?????????? ? SampleApp_Group.ID = 0x0001;//組號
?????????? ? osal_memcpy( SampleApp_Group.name, "Group 1", 7? );//設定組名
?????????? ? aps_AddGroup( SAMPLEAPP_ENDPOINT, &SampleApp_Group );//把該組登記添加到APS中
?
?????????? #if defined ( LCD_SUPPORTED )
?????????? ? HalLcdWriteString( "SampleApp", HAL_LCD_LINE_1 ); //如果支持LCD,顯示提示信息
?????????? #endif
?????????? }
?????
#if 0=================================================================
(5)?SampleApp_ProcessEvent( uint8 task_id, uint16 events )
//用戶應用任務的事件處理函數
#endif=================================================================
????? uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events )
?????????? {
?????????? ? afIncomingMSGPacket_t *MSGpkt;
?????????? ? (void)task_id;? // Intentionallyunreferenced parameter
?
?????????? ? if ( events & SYS_EVENT_MSG ) //接收系統消息再進行判斷
?????????? ? {
???????????????? //接收屬于本應用任務SampleApp的消息,以SampleApp_TaskID標記
???????????????? MSGpkt = (afIncomingMSGPacket_t*)osal_msg_receive( SampleApp_TaskID );
???????????????? while ( MSGpkt )
???????????????? {
???????????????? ? switch ( MSGpkt->hdr.event )
???????????????? ? {
????????????????????? // Received when akey is pressed
????????????????????? case KEY_CHANGE://按鍵事件
????????????????????? ? SampleApp_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );
????????????????????? ? break;
?
????????????????????? // Received when amessages is received (OTA) for this endpoint
????????????????????? case AF_INCOMING_MSG_CMD://接收數據事件,調用函數AF_DataRequest()接收數據
????????????????????? ? SampleApp_MessageMSGCB( MSGpkt );//調用回調函數對收到的數據進行處理
????????????????????? ? break;
?
????????????????????? // Received wheneverthe device changes state in the network
????????????????????? case ZDO_STATE_CHANGE:
????????????????????? ? //只要網絡狀態發生改變,就通過ZDO_STATE_CHANGE事件通知所有的任務。
????????????????????? ? //同時完成對協調器,路由器,終端的設置
????????????????????? ? SampleApp_NwkState = (devStates_t)(MSGpkt->hdr.status);
????????????????????? ? //if ( (SampleApp_NwkState == DEV_ZB_COORD)//實驗中協調器只接收數據所以取消發送事件
????????????????????? ? if ( (SampleApp_NwkState == DEV_ROUTER) || (SampleApp_NwkState == DEV_END_DEVICE) )
????????????????????? ? {
??????????????????????????? // Start sending theperiodic message in a regular interval.
??????????????????????????? //這個定時器只是為發送周期信息開啟的,設備啟動初始化后從這里開始
??????????????????????????? //觸發第一個周期信息的發送,然后周而復始下去
??????????????????????????? osal_start_timerEx( SampleApp_TaskID,
????????????????????????????????????????????????? ? SAMPLEAPP_SEND_PERIODIC_MSG_EVT,
????????????????????????????????????????????????? ? SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT );
????????????????????? ? }
????????????????????? ? else
????????????????????? ? {
??????????????????????????? // Device is nolonger in the network
????????????????????? ? }
????????????????????? ? break;
?
????????????????????? default:
????????????????????? ? break;
???????????????? ? }
?
???????????????? ? // Release the memory 事件處理完了,釋放消息占用的內存
???????????????? ? osal_msg_deallocate( (uint8 *)MSGpkt );
?
???????????????? ? // Next - if one is available 指針指向下一個放在緩沖區的待處理的事件,
???????????????? ? //返回while ( MSGpkt )重新處理事件,直到緩沖區沒有等待處理事件為止
???????????????? ? MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID );
???????????????? }
?
???????????????? // returnunprocessed events 返回未處理的事件
???????????????? return (events ^ SYS_EVENT_MSG);
?????????? ? }
?
?????????? ? // Send a message out - This event is generated bya timer
?????????? ? //? (setup inSampleApp_Init()).
?????????? ? if ( events & SAMPLEAPP_SEND_PERIODIC_MSG_EVT )
?????????? ? {
???????????????? // Send the periodicmessage 處理周期性事件,
???????????????? //利用SampleApp_SendPeriodicMessage()處理完當前的周期性事件,然后啟動定時器
???????????????? //開啟下一個周期性事情,這樣一種循環下去,也即是上面說的周期性事件了,
???????????????? //可以做為傳感器定時采集、上傳任務
???????????????? SampleApp_SendPeriodicMessage();
?
???????????????? // Setup to sendmessage again in normal period (+ a little jitter)
???????????????? osal_start_timerEx( SampleApp_TaskID,SAMPLEAPP_SEND_PERIODIC_MSG_EVT,
????????????????????? (SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT+ (osal_rand() & 0x00FF)) );
?
???????????????? // returnunprocessed events 返回未處理的事件
???????????????? return (events ^SAMPLEAPP_SEND_PERIODIC_MSG_EVT);
?????????? ? }
?
?????????? ? // Discard unknown events
?????????? ? return 0;
?????????? }
?
?????
#if 0=================================================================
(6)? //接收數據,參數為接收到的數據
voidSampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
#endif=================================================================?
?????
????? void SampleApp_MessageMSGCB(afIncomingMSGPacket_t *pkt )
?????????? {
?????????? ? uint16 flashTime;
?????????? ? byte buf[3];
?
?????????? ? switch ( pkt->clusterId ) //判斷簇ID
?????????? ? {
???????????????? caseSAMPLEAPP_PERIODIC_CLUSTERID: //收到廣播數據
???????????????? ? osal_memset(buf, 0 , 3);
???????????????? ? osal_memcpy(buf, pkt->cmd.Data, 2); //復制數據到緩沖區中
???????????????? ?
???????????????? ? if(buf[0]=='D' && buf[1]=='1')????? //判斷收到的數據是否為"D1"????????
???????????????? ? {
????????????????????? ? HalLedBlink(HAL_LED_1, 0, 50, 500);//如果是則Led1間隔500ms閃爍
?????????? #if defined(ZDO_COORDINATOR) //協調器收到"D1"后,返回"D1"給終端,讓終端Led1也閃爍
????????????????????? ? SampleApp_SendPeriodicMessage();
?????????? #endif
???????????????? ? }
???????????????? ? else
???????????????? ? {
????????????????????? ? HalLedSet(HAL_LED_1, HAL_LED_MODE_ON);??????????????????
???????????????? ? }
???????????????? ? break;
?
???????????????? caseSAMPLEAPP_FLASH_CLUSTERID: //收到組播數據
???????????????? ? flashTime = BUILD_UINT16(pkt->cmd.Data[1], pkt->cmd.Data[2] );
???????????????? ? HalLedBlink( HAL_LED_4, 4, 50, (flashTime / 4) );
???????????????? ? break;
?????????? ? }
?????????? }
?
?????
#if 0=================================================================
(7)? //分析發送周期信息
voidSampleApp_SendPeriodicMessage( void )
#endif=================================================================?
voidSampleApp_SendPeriodicMessage( void )
?????????? {
?????????? ? byte SendData[3]="D1";
?
?????????? ? // 調用AF_DataRequest將數據無線廣播出去
?????????? ? if( AF_DataRequest( &SampleApp_Periodic_DstAddr,//發送目的地址+端點地址和傳送模式
?????????????????????????????????????? ?? &SampleApp_epDesc,//源(答復或確認)終端的描述(比如操作系統中任務ID等)源EP
?????????????????????????????????????? ?? SAMPLEAPP_PERIODIC_CLUSTERID, //被Profile指定的有效的集群號
?????????????????????????????????????? ?? 2,?????? // 發送數據長度
?????????????????????????????????????? ?? SendData,// 發送數據緩沖區
?????????????????????????????????????? ?? &SampleApp_TransID,????// 任務ID號
?????????????????????????????????????? ?? AF_DISCV_ROUTE,?????// 有效位掩碼的發送選項
?????????????????????????????????????? ?? AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )? //傳送跳數,通常設置為AF_DEFAULT_RADIUS
?????????? ? {
?????????? ? }
?????????? ? else
?????????? ? {
???????????????? HalLedSet(HAL_LED_1, HAL_LED_MODE_ON);
???????????????? // Error occurred inrequest to send.
?????????? ? }
?????????? }
?
?????
?????
?????
?????
?????
?????
?????
?????
?????
?????
?????
?????
?????
?????
?????
?????
?????
?????
?????
?
?
?
?
?
?
?
?
?
?
?
?
? ? ??
總結
以上是生活随笔為你收集整理的ZigBee 协议栈的调度顺序代码分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 算法导论 答案勘误(ing)
- 下一篇: 模拟电子技术,电力电子技术