ZigBee-OSAL初始化流程

我使用的协议栈版本及例子信息:

ZigBee2006\TexasInstruments\ZStack-1.4.3-1.2.1\Projects\zstack\Samples\SampleApp

 

 

首先借用前人的一个说明:

用户自己添加的应用任务程序在Zstack中的调用过程是:

 

(1).main() 执行(ZMain.c)

 

main() --->osal_init_system()

 

(2). osal_init_system()调用osalInitTasks(), (OSAL.c)

 

osal_init_system() --->osalInitTasks()

 

(3). osalInitTasks()调用SampleApp_Init() ,(OSAL_SampleApp.c)

 

osalInitTasks() --->SampleApp_Init()

 

osalInitTasks()中实现了多个任务初始化的设置,其中macTaskInit( taskID++)ZDApp_Init( taskID++ )的几行代码表示对于几个系统运行初始化任务的调用,而用户自己实现的SampleApp_Init()在最后,这里taskID随着任务的增加也随之递增.所以用户自己实现的任务的初始化操作应该在osalInitTasks()中增加.

 

//----------------------------------------------------------------------------------------------------

1、首先来看下主函数main()

ZSEG int main( void)   //主函数的功能就是完成初始化任务,然后进入OSAL
{
  // Turn off interrupts
 

  osal_int_disable( INTS_ALL);

  //Initialize HAL
 

  HAL_BOARD_INIT();

  // Make suresupply voltage is high enough to run
 

  zmain_vdd_check();

  //Initialize stack memory
 

  zmain_ram_init();

  //Initialize board I/O
 

  InitBoard( OB_COLD );

  // InitialzeHAL drivers
 

  HalDriverInit();

  //Initialize NV System
 

  osal_nv_init( NULL );

  // Determine the extended address
 

  zmain_ext_addr();

  //Initialize basic NV items
 

  zgInit();

  //Initialize the MAC
 

  ZMacInit();

#ifndef NONWK
 // Since the AF isn't a task, call it's initializationroutine
  afInit();
#endif

#ifdefLCD_SUPPORTED  
 HalLcdInit();
#endif
  
  // Initialize the operatingsystem
 

  osal_init_system();

  // Allowinterrupts
 

  osal_int_enable( INTS_ALL);

  // Finalboard initialization
 

  InitBoard( OB_READY );
 
 //HalLcdInit();
  // Display information about this device
 

  zmain_dev_info();
  
 
#ifdef LCD_SUPPORTED
  zmain_lcd_init();
#endif

 osal_start_system(); // No Return from here没有返回,即进入操作系统!!!
}

 

说明:初始化各软硬件后进入系统主循环函数。

          这里重点是两个函数:系统初始化函数 osal_init_system(); 系统主循环函数osal_start_system();

          下面记录下个人个人对系统初始化流程系统主循环流程的学习。这里先记录下系统初始化流程。

//----------------------------------------------------------------------------------------------------

 2、系统初始化流程

 

 2.1osal_init_system()——系统初始化函数

 byte osal_init_system( void )
{
  // Initialize the Memory AllocationSystem
 

  osal_mem_init();

  // Initialize the message queue
 

  osal_qHead = NULL;

#if defined( OSAL_TOTAL_MEM )
  osal_msg_cnt = 0;
#endif

  // Initialize the timers
 

  osalTimerInit();

  // Initialize the Power ManagementSystem
 

  osal_pwrmgr_init();

  // Initialize the system tasks.
 

  osalInitTasks(); //初始化系统任务

  // Setup efficient search for thefirst free block of heap.
  osal_mem_kick();

  return ( ZSUCCESS );
}

 

说明:这里重点是初始化系统任务函数:osalInitTasks(); 下面进入系统任务的初始化:

 

//---------------------------------------------------------------------------------------------------- 

2.2 osalInitTasks();  ——任务初始化函数

void osalInitTasks( void )
{
  uint8 taskID = 0;


   //osal_mem_alloc()为当前OSAL中的各任务分配存储空间(实际上是一个任务数组),函数返回指向任务缓冲

  //区的指针,因此tasksEvents指向该任务数组(任务队列).注意tasksEvents和后面谈到的tasksArr[]里的顺

 //序是一一对应的, tasksArr[]中的第i个事件处理函数对应于tasksEvents中的第i个任务的事件.

  tasksEvents = (uint16 *)osal_mem_alloc(sizeof( uint16 ) * tasksCnt);
  
     //osal_memset()把开辟的内存全部设置为0;sizeof( uint16 )是4个字节,即一个任务
     //的长度(同样是uint16定义),乘以任务数量tasksCnt,即全部内存空间

  osal_memset( tasksEvents, 0, (sizeof( uint16 ) *tasksCnt));  //OSAL.c中定义

  macTaskInit( taskID++);    //初始化各层任务 mac_taskID=0;
 nwk_init( taskID++);           //nwk_taskID=1;
  Hal_Init( taskID++);             //Hal_taskID=2;
#if defined( MT_TASK )
  MT_TaskInit( taskID++);    
//MT_taskID=3;(if defined)
#endif
  APS_Init( taskID++);           //APS_taskID=4;
  ZDApp_Init( taskID++);       //ZDAPP_taskID=5;
  SampleApp_Init( taskID );  //SampleApp_taskID=6;用户创建的任务

}

说明:任务初始化,就是为系统的各个任务分配存储空间,当然,这个空间初始化时为全0(NULL),然后为各任务分配taskID;这里的顺序要注意.系统主循环函数里tasksEvents[ idx]和tasksArr[idx]的idx与这里taskID是一一对应关系。后面再分析。

指针数组tasksEvents[]里面最终分别指向的是各任务存储空间

指针数组tasksArr[ ]里面最终分别指向的是各任务事件处理函数

这两个指针数组里面各元素的顺序要一一对应,因为后面需要相应任务调用相应事件处理函数.

对这两个数组的定义请参见后面.

问题:对于osal_mem_alloc()这个函数返回的是一个指向任务数组的指针,看前人分析的,我还没有去看这个函数。

说明:那么这里重点是各任务的初始化,MAC层和NWK层的未开源看不到,先记录下用户自己添加的任务初始化函数SampleApp_Init(taskID );   

//----------------------------------------------------------------------------------------------------  

 2.3 SampleApp_Init( taskID); ——用户应用任务初始化函数

 void SampleApp_Init( uint8 task_id)
{
  SampleApp_TaskID =task_id;  //osal分配的任务ID,这里为6,随着用户添加任务的增多而改变
  SampleApp_NwkState =DEV_INIT; 
//设备状态设定为ZDO层中定义的初始化状态(无连接)

  SampleApp_TransID = 0; //消息发送ID(多消息时有顺序之分)

  
 // Device hardware initialization can be added here or in main()(Zmain.c).
  // If the hardware is application specific - addit here.
  // If the hardware is other parts of the deviceadd it in main().

 #if defined ( SOFT_START ) 
 //如果选择了SOFT编译选项,则作为协调器启动
  
  // The "Demo" target is setup tohave SOFT_START and HOLD_AUTO_START
  // SOFT_START is a compile option that allowsthe device to start
  //  as a coordinator ifone isn't found.
  // We are looking at a jumper (defined inSampleAppHw.c) to be jumpered
  // together - if they are - we will start up acoordinator. Otherwise,
  // the device will start as a router.
 // if ( readCoordinatorJumper() )

   zgDeviceLogicalType = ZG_DEVICETYPE_COORDINATOR;
    //else
   //zgDeviceLogicalType = ZG_DEVICETYPE_ROUTER;

#endif // SOFT_START

#if defined ( HOLD_AUTO_START )
    //如果定义了HOLD_AUTO_START选项,则调用层的ZDOInitDevice,按照默认顺   
   //序网络中的第一个设备作为协调器,其他的设备作为子设备

   // HOLD_AUTO_START is a compile option that will surpressZDApp
    //  fromstarting the device and wait for the application to
    //  startthe device.

  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;  //指定端点号EP20
  SampleApp_Periodic_DstAddr.addr.shortAddr =0xFFFF;  //指定目的网络地址为广播地址

  
 

  
//--------------------------
 
 //闪烁消息:发送到组  
  // Setup for the flash command's destinationaddress - Group1 闪烁消息事件
 

  SampleApp_Flash_DstAddr.addrMode =(afAddrMode_t)afAddrGroup;  
//(组寻址)
 SampleApp_Flash_DstAddr.endPoint =SAMPLEAPP_ENDPOINT;  //EP20
  SampleApp_Flash_DstAddr.addr.shortAddr =SAMPLEAPP_FLASH_GROUP;   //组号0x0003
//-------------------------  
  // Fill out the endpointdescription.
 

  SampleApp_epDesc.endPoint =SAMPLEAPP_ENDPOINT;  //SampleApp EP描述符的EP号:20
  SampleApp_epDesc.task_id =&SampleApp_TaskID; 
 //SampleAppEP描述符的任务ID:6
 SampleApp_epDesc.simpleDesc
           = (SimpleDescriptionFormat_t*)&SampleApp_SimpleDesc;  
//SampleApp EP简单描述符
 SampleApp_epDesc.latencyReq =noLatencyReqs;  //延时策略

  
  
// Register the endpoint description with theAF
 
 
  afRegister(&SampleApp_epDesc );

  
  // Register for all key events -This app will handle all key events
 

  RegisterForKeys( SampleApp_TaskID);

  
  // By default, all devices start out in Group1  为闪烁消息配置的组
 

  SampleApp_Group.ID =0x0003;  //组号
  osal_memcpy( SampleApp_Group.name, "Group 3",7  );  //设定组名
  aps_AddGroup( SAMPLEAPP_ENDPOINT,&SampleApp_Group );  //把该组登记添加到APS中

  
 
#if defined ( LCD_SUPPORTED )
  
//HalLcdWriteString( "SampleApp", HAL_LCD_LINE_1);
 Print8(HAL_LCD_LINE_2,20,"SampleApp",1);
#endif
}

 

说明: 在SampleAPP例子中,应用层提供了节点间两种逻辑关系:一种是周期性消息发送,另一种是Flash消息发送。我个人认为就是两个簇,比如节点1的EP20与节点2的EP20通信,(可以单播,广播,间接,组传递),这两种逻辑关系属于两节点的EP20简单描述符下簇列表元素.且可以看到SampleApp_SendPeriodicMessage( void)与SampleApp_SendFlashMessage()下的clusterID项分别为SAMPLEAPP_PERIODIC_CLUSTERID和SAMPLEAPP_FLASH_CLUSTERID。

        用户应用任务初始化大致是:设置本应用发送数据的方式和目的地址寻址模式,登记注册本应用所用到的端点,以及配置相关发送模式所需的参数.

(个人觉得就此应用来说,ZC,ZR,ZD用到的都是EP20,具体以后再作记录)

//----------------------------------------------------------------------------------------------------

 以上为OSAL初始化大体流程,OSAL以及各软硬部件初始化完成后,就进入了系统主循环函数osal_start_system();系统主循环流程个人记录见下篇

你可能感兴趣的:(ZigBee-OSAL初始化)