ZIGBEE-Z-stack协议栈

Z-stack--一个小操作系统。用户通过 API 函数就可以轻易用 ZigBee。

协议栈主函数 ----Zmain.C

 

 

/****************************************************************

 * @fn      main

 * @brief   First function called after startup.

 * @return  don’t care

 */

int main( void )

{

  // Turn off interrupts

  osal_int_disable( INTS_ALL );   //关闭所有中断 

 

  // Initialization for board related stuff such as LEDs

  HAL_BOARD_INIT();         //初始化系统时钟

 

  // Make sure supply voltage is high enough to run

  zmain_vdd_check();             //检查芯片电压是否正常

 

  // Initialize board I/O

  InitBoard( OB_COLD );         //初始化 I/O ,LED 、Timer  等 

 

  // Initialze HAL drivers

  HalDriverInit();               //初始化芯片各硬件模块

 

  // Initialize NV System

  osal_nv_init( NULL );            // 初始化 Flash  存储器

 

  // Initialize the MAC

  ZmacInit();          //初始化 MAC 层

 

  // Determine the extended address

  zmain_ext_addr();    //确定 IEEE  64 位地址

 

  // Initialize basic NV items

  zgInit();              // 初始化非易失变量

 

#ifndef  NONWK

  // Since the AF isn’t a task, call it’s initialization routine

  afInit();

#endif

 

  // Initialize the operating system

  osal_init_system();    // 初始化操作系统

 

  // Allow interrupts

  osal_int_enable( INTS_ALL );   // 使能全部中断

 

  // Final board initialization

  InitBoard( OB_READY );    // 初始化按键

 

  // Display information about this device

  zmain_dev_info();       //显示设备信息

 

  /* Display the device info on the LCD */

#ifdef LCD_SUPPORTED

  zmain_lcd_init();

#endif

 

#ifdef  WDT_IN_PM1

  /* If WDT is used, this is a good place to enable it. */

  WatchDogEnable( WDTIMX );

#endif

  osal_start_system(); // No Return from here 执行操作系统,进去后不会返回 

 return 0;         // Shouldn’t get here.

}

 

重点了解 2 个函数:

 

1. 初始化操作系统   :osal_init_system();     <系统初始化函数>

有 6 个初始化函数,只需关心  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) ,用户需考虑 ,重要函数

}

 

 

函数对 taskID 个东西进行初始化,每初始化一个,taskID++。

 

 

 

2. 运行操作系统       :osal_start_system();

 

这个是任务系统轮询的主要函数。他会查找发生的事件然后调用相应的事件执行函数。如果没有事件登记要发生,那么就进入睡眠模式。这个函数是永远不会返回的

 

void osal_start_system( void )

{

 

#if !defined ( ZBIT ) && !defined ( UBIT )

  for(;;)  // Forever Loop

#endif

{

   uint8 idx = 0;       

osalTimeUpdate();//这里是在扫描哪个事件被触发了,然后置相应的标志位

Hal_ProcessPoll();  // This replaces MT_SerialPoll() and osal_check_timer().

   Do {

      if (tasksEvents[idx])  // Task is highest priority that is ready.

      {

        break;  //    得到待处理的最高优先级任务索引号 idx 

      }

} while (++idx < tasksCnt);

 

if (idx < tasksCnt)

{

      uint16 events;

 halIntState_t intState;    

 

 HAL_ENTER_CRITICAL_SECTION(intState);  // 进入临界区,保护

 events = tasksEvents[idx];         /*提取需要处理的任务中的事件   taskID 一一对应。这就是初始化与调用的关系。taskID 把任务联系起来了。 */

 

 tasksEvents[idx] = 0;  // Clear the Events for this task.清除本次任务的事件

 HAL_EXIT_CRITICAL_SECTION(intState); // 退出临界区

 

 events = (tasksArr[idx])( idx, events );//通过指针调用任务处理函数,关键

 

 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 pass through all task events with no activity?

{

      osal_pwrmgr_powerconserve(); // Put the processor/system into sleep

}

#endif

  }

}