💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
* 导师视频讲解:[**去听课**](https://www.bilibili.com/video/BV1k34y1D7Vz?p=26) >[success] **技术支持说明:** >**1**.一般以自主学习为主 > **2**.可到官方问答社区中提问:[**去提问**](https://bbs.csdn.net/forums/zigbee) > **3**.工程师**会尽快**解答社区问题,但他们是一线开发,【**难以保证**】解答时效,解答辛苦,感谢理解! <br/> ## **层次划分** 通过前面的章节可以了解到,Z-Stack可以被分成多个层次,例如: * MAC层 * NWK(网络层) * HAL(硬件适配层) * APP(应用层) <br/> ## **任务池初始化** 每一个层次都有一个对应的任务来处理本层次的事务,例如MAC层对应一个MAC层的任务、网络层对应一个网络层的任务、HAL对应一个HAL的任务,以及应用层对应一个应用层的任务等,这些各个层次的任务构成一个任务池,这个任务池也就是上节课讲到的tasksEvents数组,如图所示。 ![](https://img.kancloud.cn/fc/bd/fcbd9ad450dd32b813cc50388e647c97_1286x998.png =400x) ### 上节课曾讲到的任务池初始化函数osalInitTasks()可以在App目录下的OSAL_SampleSw.c文件中找到,如图所示。 ![](https://img.kancloud.cn/fe/fd/fefd536bdfb55c51c94c7fbcb6122b32_1701x1440.png =500x) <br/> osalInitTasks()函数定义代码如下: ``` /********************************************************************* * @fn osalInitTasks * * @brief This function invokes the initialization function for each task. * * @param void * * @return none */ void osalInitTasks( void ) { uint8 taskID = 0; tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt); osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt)); macTaskInit( taskID++ ); nwk_init( taskID++ ); #if !defined (DISABLE_GREENPOWER_BASIC_PROXY) && (ZG_BUILD_RTR_TYPE) gp_Init( taskID++ ); #endif Hal_Init( taskID++ ); #if defined( MT_TASK ) MT_TaskInit( taskID++ ); #endif APS_Init( taskID++ ); #if defined ( ZIGBEE_FRAGMENTATION ) APSF_Init( taskID++ ); #endif ZDApp_Init( taskID++ ); #if defined ( ZIGBEE_FREQ_AGILITY ) || defined ( ZIGBEE_PANID_CONFLICT ) ZDNwkMgr_Init( taskID++ ); #endif // Added to include TouchLink functionality #if defined ( INTER_PAN ) StubAPS_Init( taskID++ ); #endif // Added to include TouchLink initiator functionality #if defined( BDB_TL_INITIATOR ) touchLinkInitiator_Init( taskID++ ); #endif // Added to include TouchLink target functionality #if defined ( BDB_TL_TARGET ) touchLinkTarget_Init( taskID++ ); #endif zcl_Init( taskID++ ); bdb_Init( taskID++ ); zclSampleSw_Init( taskID++ ); #if (defined OTA_CLIENT) && (OTA_CLIENT == TRUE) zclOTA_Init( taskID ); #endif } ``` >[warning] 这个函数的代码较为复杂,读者暂时按照笔者的讲解思路简单地了解一下其中的原理就可以了。 这个函数首先申请了一个任务池存储空间,也就是这个tasksEvents数组。接着调用了很多带有“init”字样的函数,这些函数的作用是初始化各个层次的任务,例如: * 调用macTaskInit()函数初始化MAC层的任务。 * 调用nwk_init()函数初始化网络层的任务。 * 调用zclSampleSw_Init()函数初始化应用层的任务。 这个过程跟《OSAL的任务调度原理》章节中创建和初始化任务池是类似的,它们的主要差别在于: * 首先,任务池存储的数据结构不同,这里的tasksEvents是一个uint16类型的数组。 * 其次,tasksEvents支持存放多种类型的任务,例如MAC层的任务、网络层的任务和应用层的任务等。 * 最后,这里的每一个任务中都可能会包含多个待处理事件。 <br/> ## **事件处理函数** OSAL\_SampleSw.c文件中还定义了一个数组,代码如下: ``` //创建一个元素类型为pTaskEventHandlerFn的数组 1.const pTaskEventHandlerFn tasksArr[] = {     2.  macEventLoop, //第1个数组元素 3.  nwk_event_loop, //第2个数组元素 // //第3个数组元素 4.#if !defined (DISABLE_GREENPOWER_BASIC_PROXY) && (ZG_BUILD_RTR_TYPE)     5.  gp_event_loop,     6.#endif       // //第4个数组元素 7.  Hal_ProcessEvent,   //第5个数组元素 8.#if defined( MT_TASK )     9.  MT_ProcessEvent,     10.#endif     // //第6个数组元素 11.  APS_event_loop,    //  //第7个数组元素 12.#if defined ( ZIGBEE_FRAGMENTATION )     13.  APSF_ProcessEvent,     14.#endif  // //第8个数组元素 15.  ZDApp_event_loop,     // //第9个数组元素 16.#if defined ( ZIGBEE_FREQ_AGILITY ) || defined ( ZIGBEE_PANID_CONFLICT )     17.  ZDNwkMgr_event_loop,     18.#endif     // //第10个数组元素 19.  //Added to include TouchLink functionality     20.  #if defined ( INTER_PAN )     21.    StubAPS_ProcessEvent,     22.  #endif     // //第11个数组元素 23.  // Added to include TouchLink initiator functionality     24.  #if defined ( BDB_TL_INITIATOR )     25.    touchLinkInitiator_event_loop,     26.  #endif     // //第12个数组元素 27.  // Added to include TouchLink target functionality     28.  #if defined ( BDB_TL_TARGET )     29.    touchLinkTarget_event_loop,     30.  #endif     // 31.  zcl_event_loop,    //第13个数组元素 32.  bdb_event_loop,    //第14个数组元素 33.  zclSampleSw_event_loop,    //第15个数组元素 // //第16个数组元素 34.#if (defined OTA_CLIENT) && (OTA_CLIENT == TRUE)     35.  zclOTA_event_loop     36.#endif     37.}; ``` 前面章节中曾经讲到,tasksEvents中的每个任务可以包含0个或者多个待处理的事件,而这个数组类型变量pTaskEventHandlerFn是一个函数指针类型变量,用于指向事件对应的处理函数,因此这段代码定义了一个事件处理函数数组,这个数组中的每一个元素均表示某一个层次任务的事件处理函数,例如: * MAC层任务对应的事件处理函数是macEventLoop(),它专门处理MAC层任务中的事件。 * 网络层任务对应的事件处理函数是nwk\_event\_loop(),它专门处理网络层任务中的事件。 * 应用层任务对应的事件处理函数是zclSampleSw\_event\_loop(),它专门处理应用层任中的事件。 <br/> 以应用层事件处理函数zclSampleSw\_event\_loop()为例,可以在zcl\_samplesw.h文件中找到该函数的声明,代码如下: ``` /* * Event Process for the task */ extern UINT16 zclSampleSw_event_loop( byte task_id, UINT16 events ); ``` <br/> <br/> ## **项目定制** * 如需项目定制开发,可扫码添加项目经理好友(注明“**定制**”) * 定制范围:**NB-IoT**、**CATn(4G)**、**WiFi**、**ZigBee**、**BLE Mesh**以及**STM32**、**嵌入式Linux**等IoT技术方案 * 善学坊官网:[www.sxf-iot.com](https://www.sxf-iot.com/) ![](https://img.kancloud.cn/ca/73/ca739f92cab220a3059378642e3bd502_430x430.png =200x) * 非项目定制**勿扰**,此处**非**技术支持