Z-STACK 协议栈学习 -- OSAL

     期间参加了一次天池的比赛,然后就来了项目,,,(无力),比赛的内容也忘得差不多了,有时间再补上。

     项目需要用zigbee做通信,为了开发得快一点这里就使用了Z-Stack,这是一个近似于小型操作系统管理的协议栈。我们先来看以下它的工作流程。

一、OSAL

     OSAL管理着开发板上的各种资源,是一个为操作系统,他的工作流程如下。

     首先我们需要知道整个协议栈程序的开端,程序的开端在Zmain文件夹的Zmian.c文件中,在这个c文件中可以看到一段如下的程序:

int main( void )
{
  // Turn off interrupts
  osal_int_disable( INTS_ALL );
  // Initialization for board related stuff such as LEDs
  HAL_BOARD_INIT();
  // Initialize board I/O 
  InitBoard( OB_COLD );
  // Initialze HAL drivers
  HalDriverInit();
  // Initialize NV System
  osal_nv_init( NULL );
  // Initialize the MAC
  ZMacInit();
  // 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();
#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 );
  SysTickSetup();
  // Final board initialization
  InitBoard( OB_READY );
  /* Display the device info on the LCD */
#ifdef LCD_SUPPORTED
  zmain_dev_info();
  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.
} // main()

     在这段程序中可以看到各种带有init的函数,这些函数都是用于做初始化的,比如  HAL_BOARD_INIT()是板外设的初始化。HalDriverInit()是驱动程序的初始化。这些直接跳过,直接看osal_start_system()这个函数,这个函数是用于启动操作系统的。双击它按F12进入该函数,可以看到函数中有这样一段程序:

  for(;;)  // Forever Loop
#endif
  {
    osal_run_system();

#ifdef USE_ICALL
    ICall_wait(ICALL_TIMEOUT_FOREVER);
#endif /* USE_ICALL */
  }

     可以看到,这是一个死循环,在死循环中有一个运行操作系统的函数osal_run_system(),我们的协议栈就是在这个循环中不断运行的。

     OK,双击osal_run_system()函数按F12进入,看到这样一段程序:

  do {
    if (tasksEvents[idx])  // Task is highest priority that is ready.
    {
      break;
    }
  } while (++idx < tasksCnt);

  if (idx < tasksCnt)
  {
    uint16 events;
    halIntState_t intState;

    HAL_ENTER_CRITICAL_SECTION(intState);
    events = tasksEvents[idx];
    tasksEvents[idx] = 0;  // Clear the Events for this task.
    HAL_EXIT_CRITICAL_SECTION(intState);

    activeTaskID = idx;
    events = (tasksArr[idx])( idx, events );
    activeTaskID = TASK_NO_TASK;

    HAL_ENTER_CRITICAL_SECTION(intState);
    tasksEvents[idx] |= events;  // Add back unprocessed events to the current task.
    HAL_EXIT_CRITICAL_SECTION(intState);
  }

     这段程序中首先是是一个do while的循环,判断了一个数组是否非零,这个数组很重要,我们把它叫做事件数组,它的元素都是16位的UINT16型数据,这个数组的元素个数等于我们定义的任务的数量(这里又提到了一个任务的概念,稍后解释)。

     当这个数组非零时表示着以idx为编号的任务有事件要处理,那么就跳出循环,处理事件。继续向下执行语句直到这一句 events = (tasksArr[idx])( idx, events ),这条语句的意思是调用编号为idx的任务的任务处理函数,处理的事件是events,这里最后有一个赋值的操作,就是将(tasksArr[idx])( idx, events )的值赋给events,这是因为处理函数的返回值是events(在任务处理函数中每处理一个事件都会做一个抑或操作,表示事件已经处理过)。

     以上就是OSAL的运行流程,下一篇我们来看一下事件的处理过程。

扫描二维码关注公众号,回复: 2613937 查看本文章

猜你喜欢

转载自blog.csdn.net/weixin_39749553/article/details/81368173