微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 硬件工程师文库 > 由浅入深,蓝牙4.0/BLE协议栈开发攻略大全(3)

由浅入深,蓝牙4.0/BLE协议栈开发攻略大全(3)

时间:07-22 来源:本站整理 点击:

SAL初始化

  /* Enable interrupts */

  HAL_ENABLE_INTERRUPTS(); // 使能总中断

  // Final board initialization

  InitBoard( OB_READY ); // 板级初始化

  #if defined ( POWER_SAVING )

  osal_pwrmgr_device( PWRMGR_BATTERY ); // 低功耗管理

  #endif

  /* Start OSAL */

  osal_start_system(); // No Return from here 启动OSAL

  return 0;

  }

  通过代码我们可以看到,系统启动的过程,主要是做了一些初始化,如果开启了低功耗,则还需要开启低功耗管理。我们先不去理会初始化做了什么,但是我们知道在main函数的最后启动了OSAL,那么我们就进去看看OSAL是如何运作的。

  在IAR中如果需要跳转到某个函数或变量的定义,可以在此函数名中右击然后选择Go To Definition……就可以调到相应的定义。

  

  void osal_start_system( void )

  {

  #if !defined ( ZBIT ) && !defined ( UBIT )

  for(;;) // Forever Loop

  #endif

  {

  osal_run_system();

  }

  }

  这里看到我们进入了一个死循环,并且一直调用osal_run_system(),那我们再进入此函数。

  </blockquote></div><div style="text-align: left;"><div class="blockcode"><blockquote>void osal_run_system( void )

  {

  uint8 idx = 0;

  #ifndef HAL_BOARD_CC2538

  osalTimeUpdate(); // 定时器更新

  #endif

  Hal_ProcessPoll(); // Hal层信息处理

  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); // 退出临界区

  }

  #if defined( POWER_SAVING ) // 没有事件发生,并且开启了低功耗模式

  else // Complete pass through all task events with no activity?

  { // 系统进入低功耗模式

  osal_pwrmgr_powerconserve(); // Put the processor/system into sleep

  }

  #endif

  /* Yield in case cooperative scheduling is being used. */

  #if defined (configUSE_PREEMPTION) && (configUSE_PREEMPTION == 0)

  {

  osal_task_yield();

  }

  #endif

  }

  在这里可以看到这个OSAL的核心,整个OSAL通过检测每个任务是否有事件发生,如果有则执行相应的任务,处理相应的事件。如果没有事件需要处理并且开启了低功耗模式,则系统就会进入低功耗模式。

  这里有一个很关键的地方,OSAL是如何知道哪个事件需要哪个任务来处理呢?

  events = (tasksArr[idx])( idx, events ); // 执行事件处理函数

  我们看这里有一个很关键的数组tasksArr,很显然,这是一个函数指针数组,我们看看它的定义。

  const pTaskEventHandlerFn tasksArr[] =

  {

  LL_ProcessEvent, // task 0

  Hal_ProcessEvent, // task 1

  HCI_ProcessEvent, // task 2

  #if defined ( OSAL_CBTIMER_NUM_TASKS )

  OSAL_CBTIMER_PROCESS_EVENT( osal_CbTimerProcessEvent ), // task 3

  #endif

  L2CAP_ProcessEvent, // task 4

  GAP_ProcessEvent, // task 5

  GATT_ProcessEvent, // task 6

  SM_ProcessEvent, // task 7

  GAPRole_ProcessEvent, // task 8

  GAPBondMgr_ProcessEvent, // task 9

  GATTServApp_ProcessEvent, // task 10

  SimpleBLEPeripheral_ProcessEvent // task 11

  };

可以看到在这个数组的定义中,每个成员都是任务的执行函数,按照任务的优先级排序,并且在osalInitTasks中初始化的时候,我们可以看到每个任务都有一个对应的初始化函数,并且传递了一个taskID,此ID从0开始自增

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top