欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

车干的ZigBee学习笔记八-浅析协议栈

程序员文章站 2022-03-07 09:33:37
...

一、初识OSAL

  • ZigBee协议栈的实时操作系统
  • 操作系统抽象层-Operating System Abstraction Layer
  • 作用:任务调度,资源分配和管理
  • 关键词:任务和事件
  • taskCnt–任务总数
  • taskEvents–指向事件表首地址的指针
  • taskArry–数组,数组中的每一个元素都是指向事件处理函数的指针

二、协议栈运行机制

1、入口在Zmain文件下,Zmain.c的main函数中,其中包含了各种硬件和协议栈的初始化,直到调用osal_start_system()函数,协议栈才开始真正运行起来。

  • int main(void)
  • {
  •   ...
    
  •   ...
    
  • osal_start_system(); //不再返回
  • return 0; //
  • }

2、当发生两个事件同时发生时,0SAL处理

  • #define SYS_EVENT_MSG 0X8000
  • #define SAMPLEAPP_SEND_PERIODIC_MSG_EVT 0X0001
  • 如果这两个事件同时发生,则events =0x8001
  • 异或运算,同为0,异为1
  • events^SYS_EVENT_MSG = 0x0001(只剩下最后一个事件)
  • events^SAMPLEAPP_SEND_PERIODIC_MSG_EVT =0x8000(只剩前一个事件)

三、osal_start_system(); 详解

void osal_start_system( void )
{
#if !defined ( ZBIT ) && !defined ( UBIT )
  for(;;)  //首先是一个FOR的死循环
#endif
  {
    uint8 idx = 0;  //定义变量用来索引事件表

    osalTimeUpdate(); //用来更新系统时钟
    Hal_ProcessPoll();  // 查看硬件方面是否有事件发生
    
    do {
      if (tasksEvents[idx])  // tasksEvents事件表,当有事件发生,idx 会变为一个16进制的数字
      {
        break;//idx不为0时,跳出do_while循环
      }
    } while (++idx < tasksCnt);  //如果没有事件发生,++idx继续检查下一项是否有事件发生

    if (idx < tasksCnt)  //跳出任务检查循环后,第一步,保证不超出任务总数
    {
      uint16 events;
      halIntState_t intState;

      HAL_ENTER_CRITICAL_SECTION(intState);  //进入中断
      events = tasksEvents[idx];  //保存事件
      tasksEvents[idx] = 0;  // 事件表清除为0.
      HAL_EXIT_CRITICAL_SECTION(intState); //退出中断

      events = (tasksArr[idx])( idx, events );//调用数据处理函数

      HAL_ENTER_CRITICAL_SECTION(intState); //进入中断
      tasksEvents[idx] |= events;  // 把未处理的事件返回给事件表
      HAL_EXIT_CRITICAL_SECTION(intState); //退出中断
    }
#if defined( POWER_SAVING )
    else  //完全通过所有没有活动的任务事件?
    {
      osal_pwrmgr_powerconserve();  // 完全通过所有没有活动的任务事件?
    }
#endif
  }
}