Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2264607
  • 博文数量: 187
  • 博客积分: 1457
  • 博客等级: 上尉
  • 技术积分: 2423
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-13 09:41
个人简介

如需要绘制PCB,设计电路可以和我联系。sunhenu@163.com.

文章分类

全部博文(187)

文章存档

2017年(2)

2016年(2)

2015年(7)

2014年(13)

2013年(80)

2012年(83)

分类: LINUX

2013-04-19 17:26:52

这里events = (tasksArr[idx])( idx, events ); 是因为每一个任务的事件处理函数返回的都是这个任务没有被处理完成的事件。
比如说用户应用任务的事件处理函数:
SampleApp_ProcessEvent( uint8 task_id, uint16 events ),如下:

每个任务都有不同的事件,因此在进行事件的处理前要进行判断,对于SampleApp

大事件1_接收系统消息:

按键小事件(包含了组发送flash消息事件和进组退组事件)

接收数据小事件

设备网络状态变化小事件

大事件2_向外发送消息:

发送 periodic 消息 

下面的SampleApp_ProcessEvent()就是通过上面的顺序对用户添加的应用任务进行事件的轮询:

uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events )

{

  afIncomingMSGPacket_t *MSGpkt;  //接收到的消息

  /*如果大事件是接收系统消息*/   //则接收系统消息再进行判断

  if ( events & SYS_EVENT_MSG )

  {

MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID ); 

//接收属于本应用任务SampleApp的消息(SampleApp_TaskID标记。

    while ( MSGpkt )  //接收到 

             {                                                                     

switch ( MSGpkt->hdr.event ) //系统消息的进一步判断

                        {       

                                    // Received when a key is pressed

                            /*小事件:按键事件*/

                            //  如果一个OSAL任务已经被登记注册,那么任何键盘事件都将接受一个KEY_CHANGE事件信息。

                                case KEY_CHANGE:   //#define KEY_CHANGE  0xC0 --Key Events         
                                     
SampleApp_HandleKeys(((keyChange_t*)MSGpkt)->state,((keyChange_t*)MSGpkt)->keys );

                                     break; 

                              //执行具体的按键处理函数,定义在sampleAPP.c

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

                             /*小事件:接收数据事件*/

                            //  接收数据事件,调用函数AF_DataRequest()接收数据

                            case AF_INCOMING_MSG_CMD:

                                   SampleApp_MessageMSGCB( MSGpkt ); 

                                   break; 

                                //调用回调函数对收到的数据进行处理       

                                // Received whenever the device changes state in the network

                              /*小事件:设备网络状态变化事件*/

                                //  只要网络状态发生改变,就通过ZDO_STATE_CHANGE事件通知所有的任务,注意,是所有任务都会收到这消息。

                                case ZDO_STATE_CHANGE:  

                                              SampleApp_NwkState = (devStates_t)(MSGpkt->hdr.status); 

                                              if ( (SampleApp_NwkState == DEV_ZB_COORD)

                                                  || (SampleApp_NwkState == DEV_ROUTER)

                                                  || (SampleApp_NwkState == DEV_END_DEVICE) )

                                                          {

                                                                // Start sending the periodic message in a regular interval.

                                                                /*按一定间隔启动定时器*/

到这里产生了ZDO状态改变时间,从下面的if判断语句可以看出,这个时候已经完成了对协调器,路由器,终端的确定和设置,这里针对3种不同类型的设备进行了发送周期性事件的设置。你可以设置自己需要的设备进行周期性事件设置。比如说针对终端设置一个周期性采集数据的功能。

//这个定时器只是为发送周期信息开启的,设备启动初始化后从这里开始触发第一个周期信息的发送,然后周而复始下去

                                        osal_start_timerEx( SampleApp_TaskID,

                                                                           SAMPLEAPP_SEND_PERIODIC_MSG_EVT,

                                                                           SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT );

                                                                      }

                                                                                  else

                                                                                              {

                                                                                                        // Device is no longer in the network

                                                                                              }

                                      break;

                                    default:

                                          break;

                          }

      // Release the memory

      //以上把收到系统消息这个大事件处理完了,释放消息占用的内存

      osal_msg_deallocate( (uint8 *)MSGpkt );

      // Next - if one is available

      /*指针指向下一个"已接收到的[程序在while ( MSGpkt )内]放在缓冲区的待处理的事件,与SampleApp_ProcessEvent处理多个事件相对应,返回while ( MSGpkt )重新处理事件,直到缓冲区没有等待处理事件为止。*/

      MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID );

    }

    // return unprocessed events

    // 两者相异或,返回未处理的事件,returnosal_start_system()下的events = (tasksArr[idx])( idx, events )语句中,重新在osal_start_system()下轮询再进入此函数进行处理。

    return (events ^ SYS_EVENT_MSG); 

  }

  // Send a message out - This event is generated by a timer

  /*下面是处理周期性事件的代码,利用SampleApp_SendPeriodicMessage()处理完当前的周期性事件,然后启动定时器开启下一个周期性事情,这样一种循环下去,也即是上面说的周期性事件了,可以做为温度采集使用。*/

  //  (setup in SampleApp_Init()).

  if ( events & SAMPLEAPP_SEND_PERIODIC_MSG_EVT )  //发送周期消息事件

  {

    // Send the periodic message

    SampleApp_SendPeriodicMessage();

    // Setup to send message 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)) );

    // return unprocessed events

    // 两者相异或,返回未处理的事件,同样是返回到osal_start_system()下的events = (tasksArr[idx])( idx, events )语句中。

    return (events ^ SAMPLEAPP_SEND_PERIODIC_MSG_EVT);

  }

}

上面没有提到flash事件如何处理,其实它被放到按键事件去处理了,很简单。


参考文章为 http://wjf88223.blog.163.com。
阅读(3494) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~