Zigbee Z-Stack 3.0.2 开发(二)Z-Stack协议栈的基本框架和工作原理

ZStack版本:Z-Stack 3.0.2
下载和调试器:SmartRF04EB
IDE开发软件:IAR Embedded Workbench IDE - 8051 10.20.1
开发平台:基于TI-CC2530的任意厂家的
Z-Stack协议栈是TI对应zigbee协议的实现,目前最新的版本是 3.0.2。
Z-Stack协议栈里植入了OSAL实时操作系统,下面我们简单介绍一下这个操作系统:
名称:OSAL(Operating System Abastraction Layer)
作用:任务调度,资源分配和管理
要点:任务和事件
tasksCnt 任务个数
tasksEvents 任务事件表首地址的指针
tasksArr 数组,数组每个元素对应一个任务事件处理函数的指针
tasksEvents 和tasksArr是对应的,
OSAL只做了两件事情:首先进行系统的初始化,然后启动OSAL操作系统。最后就是任务轮询过程,系统将会不断查询每个任务是否有事件发生,如果有事件发生,就调用相应的事件处理函数,处理完成后,清除当前任务的事件标志,如果没有事件发生,则查询下一个任务。
1、main函数的分析
TI的Z-Stack协议是用C语言编写的,程序的入口点就是main()函数,而且整个Z-Stack都只有一个main()函数入口,所以程序的入口点也是main()函数,在Z-Stack 3.0.2协议栈中有四个main函数的定义,分别位于.Z-Stack 3.0.2\Projects\zstack\ZMain中的四个文件夹中,这四个文件分别对应了2种芯片和四种工程类型。针对CC2530来说,TI2530DB是单CC2530架构工程,TI2530ZNP是CC2530+MCU架构工程,在此我们只分析TICC2530DB的。 main()函数开始分析:

int main( void )
{
  // Turn off interrupts
  osal_int_disable( INTS_ALL );//关闭所有中断
  // Initialization for board related stuff such as LEDs
  HAL_BOARD_INIT();//板子硬件初始化,时钟,LED灯
  // Make sure supply voltage is high enough to run
  zmain_vdd_check();//电压检测,确保芯片可正常启动
  // Initialize board I/O
  InitBoard( OB_COLD );//板载I/O初始化
  // Initialze HAL drivers
  HalDriverInit();//硬件驱动初始化
  // Initialize NV System
  osal_nv_init( NULL );//FLASH存储器初始化
  // Initialize the MAC
  ZMacInit();//MAC层初始化
  // Determine the extended address
  zmain_ext_addr();//扩展地址确定
#if defined ZCL_KEY_ESTABLISH
  // Initialize the Certicom certificate information.
  zmain_cert_init();//认证初始化
#endif
  // Initialize basic NV items
  zgInit();//基本NV条目初始化
#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();//设备信息的显示,需要LCD支持
  /* Display the device info on the LCD */
#ifdef LCD_SUPPORTED
  zmain_lcd_init();//如果定义LCD_SUPPORTED宏,则初始化LCD
#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.
} // main()

main函数主要在系统启动后,进行一些硬件、服务、操作系统等方面的初始化工作,最后启动操作系统。在main函数里的所有初始化函数中,有两个比较重要的函数是:osal_init_system();//初始化操作系统和
osal_start_system(); // No Return from here 启动操作系统。
2、osal_init_system()函数的分析
osal_init_system()在整个Z-Stack 3.0.2协议中,只有一处定义,上面说的四种工程类型中的main文件,只是对该函数进行调用即可。函数主要初始化了操作系统用到的资源,比如:内存,堆栈等,但我们重点关注的是操作系统任务初始化函数osalInitTasks();

uint8 osal_init_system( void )
{
#if !defined USE_ICALL && !defined OSAL_PORT2TIRTOS
  // Initialize the Memory Allocation System
  osal_mem_init();//初始化内存
#endif /* !defined USE_ICALL && !defined OSAL_PORT2TIRTOS */
  // Initialize the message queue
  osal_qHead = NULL;//初始化消息队列
  // Initialize the timers
  osalTimerInit();//初始化定时器
  // Initialize the Power Management System
  osal_pwrmgr_init();//初始化电源管理系统
#ifdef USE_ICALL
  /* Prepare memory space for service enrollment */
  osal_prepare_svc_enroll();//准备用于服务注册的内存空间
#endif /* USE_ICALL */
  // Initialize the system tasks.
  osalInitTasks();//初始化系统任务,**需要重点分析**
#if !defined USE_ICALL && !defined OSAL_PORT2TIRTOS
  // Setup efficient search for the first free block of heap.
  osal_mem_kick();
#endif /* !defined USE_ICALL && !defined OSAL_PORT2TIRTOS */
#ifdef USE_ICALL
  // Initialize variables used to track timing and provide OSAL timer service
  osal_last_timestamp = (uint_least32_t) ICall_getTicks();
  osal_tickperiod = (uint_least32_t) ICall_getTickPeriod();
  osal_max_msecs = (uint_least32_t) ICall_getMaxMSecs();
  /* Reduce ceiling considering potential latency */
  osal_max_msecs -= 2;
#endif /* USE_ICALL */
  return ( SUCCESS );
}

3、osalInitTasks()任务初始化函数的分析

osalInitTasks()函数在Z-Stack 3.0.2协议栈中有多处定义,如下图所示:
在这里插入图片描述
除第一个操作系统OSAL.c文件的函数osal_init_system()函数是调用该函数外,其余文件中均有一个该文件的定义。其中不同文件代表了TI的不同类型的工程例程。而且每个文件还可用于不同芯片和架构。比如同一文件OSAL_GenericApp.C可用于TICC2530单芯片架构和单芯片+MCU架构,TICC2538单芯片架构和单芯片+MCU架构。我们在此,仅以OSAL_GenericApp.C文件进行分析。这是TI给出的一个通用的例程,我们先分析该文件中的
osalInitTasks()函数,再分析其它函数,代码如下:

/*********************************************************************
 * @fn      osalInitTasks
 *
 * @brief   This function invokes the initialization function for each task.
 *
 * @param   void
 *
 * @return  none
 */
void osalInitTasks( void )
{
  uint8 taskID = 0;//任务ID初始化,即任务的优先级
  tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);//任务时间表内存分配
  osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt));//将全部内容初始化为0
  macTaskInit( taskID++ );//taskID = 1 MAC层任务初始化
  nwk_init( taskID++ );//taskID = 2 网络层任务初始化
#if !defined (DISABLE_GREENPOWER_BASIC_PROXY) && (ZG_BUILD_RTR_TYPE)
  gp_Init( taskID++ );//taskID = 3 电源管理任务初始化
#endif
  Hal_Init( taskID++ );//taskID = 4 硬件层任务初始化
#if defined( MT_TASK )
  MT_TaskInit( taskID++ );//taskID = 5 串口监控任务初始化
#endif
  APS_Init( taskID++ );//taskID = 6 APS层任务初始化
#if defined ( ZIGBEE_FRAGMENTATION )
  APSF_Init( taskID++ );//taskID = 7 APSF层任务初始化
#endif
  ZDApp_Init( taskID++ );//taskID = 8 MAC层任务初始化
#if defined ( ZIGBEE_FREQ_AGILITY ) || defined ( ZIGBEE_PANID_CONFLICT )
  ZDNwkMgr_Init( taskID++ );//taskID = 9 任务初始化
  #endif
  // Added to include TouchLink functionality
#if defined ( INTER_PAN )
  StubAPS_Init( taskID++ );//taskID = 10 任务初始化
#endif
// Added to include TouchLink initiator functionality
#if defined( BDB_TL_INITIATOR )
  touchLinkInitiator_Init( taskID++ );//taskID = 11 任务初始化
#endif
// Added to include TouchLink target functionality
#if defined ( BDB_TL_TARGET )
  touchLinkTarget_Init( taskID++ );//taskID = 12 任务初始化
#endif
  zcl_Init( taskID++ );//taskID = 13 ZCL任务初始化
  bdb_Init( taskID++ );//taskID = 14 bdb任务初始化
  zclGenericApp_Init( taskID );//taskID = 15 本工程主任务初始化,重点关注
}

  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值