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

一、初识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
  }
}

发布了13 篇原创文章 · 获赞 3 · 访问量 1853

猜你喜欢

转载自blog.csdn.net/weixin_44127810/article/details/104341027
今日推荐