This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

【CC2541测评】CC2541迷你开发套件使用心得分享+osal上手by无聊达

在开始学习之前,推荐大家阅读《蓝牙4.0 BLE开发完全手册---物联网开发技术实战》这本书,这本书从基础讲起,确实对初学者很有用,初学者在论坛里逛了多久都没有用,因为你没有基础,甚至看不懂论坛里的人在讨论啥,只有看了了这本书,才能较快地入门osal开发。

正版图书链接:http://product.dangdang.com/23237630.html    

 

当然也有dao版电子书,已经有大佬分享过了:

 https://e2echina.ti.com/question_answer/wireless_connectivity/bluetooth/f/103/t/156405

 

 

 

 

OSAL为:Operating System Abstraction Layer,即操作系统抽象层,支持多任务运行,它并不是一个传统意义上的操作系统,但是实现了部分类似操作系统的功能在多个协议栈中通用的任务调度和事件处理的操作系统抽象层,它不是完整的操作系统。可以直接运行,也可以运行在RTOS等操作系统进程中。不支持抢占时间片,任务优先级不可以调整,任务优先级决定于任务ID,任务ID越小,优先级越高BLE协议栈各层的任务优先级比应用程序的高。

流程解析

首先我们找到主函数所在的文件

 

接下来一个个分析红底函数

 

int main(void)

{

  /* Initialize hardware */

  HAL_BOARD_INIT();

 

  // Initialize board I/O

  InitBoard( OB_COLD );

 

  /* Initialze the HAL driver */

  HalDriverInit();

 

  /* Initialize NV system */

  osal_snv_init();

  

  /* Initialize LL */

 

  /* Initialize the operating system */

  osal_init_system();

 

  /* 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

 

  return 0;

}

 

  /* Initialize hardware */

  HAL_BOARD_INIT(); //HAL_BOARD_INIT()是通过宏定义来实现的,主要功能是初始化时钟等

 

 

  // Initialize board I/O

  InitBoard( OB_COLD ); //初始化板外围设备

 

 

 

/* Initialze the HAL driver */

  HalDriverInit(); //初始化定时器,adcdmalcdled

 

 

 

  /* Initialize NV system */

  osal_snv_init(); //初始化NV flash页面。用于保存配对数据或你的用户自定义数据的一段flash4kB空间

 

  /* Initialize the operating system */

  osal_init_system(); //oasl 操作系统初始化, 包含内存分配、消息队列、定时器、电源管理和任务等,务必重点学习

osalInitTasks();//初始化系统任务中,可以看到各个任务及其初始化的id,注意以下3

1. 任务优先级决定于任务ID,任务ID越小,优先级越高;

2. BLE协议栈各层的任务优先级比应用程序的高;

3. 初始化协议栈后,越早调入的任务,任务ID越高,优先级越低,即系统倾向于处理新到的任务;

osal_init_system简单理解为设置要在while1)里边运行的taskosal_start_system就是while(1)循环

osal_init_systemosalInitTasks这个函数就是设置任务IDID1对应task1ID2对应task2.osal_run_system里边不断查询需要处理的任务,最后调用对应的ProcessEvent进行处理。

可以看到下面的taskID和tasksArr数组中的序号是一一对应的

为每个任务分配taskID:

t可以看到askID和下面tasksArr数组中的序号是一一对应的

 

  /* Enable interrupts */

  HAL_ENABLE_INTERRUPTS(); //开启中断

 

  // Final board initialization

  InitBoard( OB_READY ); //最终板初始化,总共有三个板初始化状态COLD,WARM,READY,除了COLD外,填啥都一样

 

 

  #if defined ( POWER_SAVING )

    osal_pwrmgr_device( PWRMGR_BATTERY );//检测是否开启低功耗

  #endif

 

  /* Start OSAL   osal 操作系统启动,进入大循环中*/

  osal_start_system(); // No Return from here,整个的大循环入口,务必重点学习

 

接下来从 osal_start_system中的osal_run_system函数的任务调度部分开始

通过tasksEvents判断任务有没有挂起

最核心的是一个do-while循环,一个if判断。

这个循环就是完成判断当前的事件表中有没有事件发生,如果有就执行下面的代码

 

最后总结一下用户自己设计的任务代码在osal中的调用过程

main() ---> osal_init_system()---> osalInitTasks()--->KeyFobApp_Init( taskID );

在osalInitTasks()中实现了多个任务初始化的设置,接下来研究如何在osal中添加自己的任务

共分为四个步骤:

步骤1:在KeyFobDemo.c中编写任务(事件)处理函数KeyFobDemo_ProcessEvent()

步骤2:将任务事件处理函数添加到在OSAL_KeyFobDemo.c中数组tasksArr[]的最下边

步骤3:在KeyFobDemo.c中编写任务初始化函数KeyFobDemo_Init()

步骤4:在OSAL_KeyFobDemo.c中的osalInitTasks()中调用任务初始化函数KeyFobDemo_Init(),进行任务初始化