BLE的软件开发--将应用添加到OSAL中1
OSAL是什么?
View Code
View Code
OSAL是BLE的一个简化的“操作系统”,可以完成“进程"调度,以及"进程"间通信。
在OSAL中,"进程"也被简化了,其实就是一个函数+通信,被称为一个task。task的函数可以是蓝牙LL层协议,也可以是硬件的中断、输入输出。OSAL会给每一个task分配一个buffer,用于task之间通信。总之,OSAL是个特别简单的操作系统,能完成函数的调用和各个函数(模块)之间的通信。
OSAL的使用
OSAL的使用也非常简单,我们只要把想要调用的函数填写到task列表中就行。具体来说,分为2步。
1、把函数写好,这里其实也有很多要注意的,特别是task之间通信的处理,但是跟怎么用OSAL没啥关系,这里先略过。
2、把写好的函数放入task列表,OSAL提供了一个全局变量:
const pTaskEventHandlerFn tasksArr[]
taskArr是一个task的数组,数组中元素的数据类型是pTaskEventHandlerFn,定义如下:
typedef unsigned short (*pTaskEventHandlerFn)( unsigned char task_id, unsigned short event );
可以看到,pTaskEventHandlerFn是一个函数指针类型,这个函数指针可以指向这样一种函数:参数类型为8bit的task_id和16bit的event,并返回一个16bit的数据的函数。
这里也说明了一点,所有的task其实都是一个函数,并且能够被pTaskEventHandlerFn指向,被放入taskArr供OSAL调用。task要提供一个task ID,以及一个事件event用于task之间通信。
了解了这些,我们就可以把自己写好的task函数放入taskArr中。
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 MyTask // task 11 };
然后,还要在osalInitTasks函数中,写一个task的初始化函数,并且注意顺序,要保证自己的task在taskArr中书序正好是初始化中的taskID值。
void osalInitTasks( void ) { uint8 taskID = 0; tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt); osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt)); LL_Init( taskID++ ); Hal_Init( taskID++ ); HCI_Init( taskID++ ); #if defined ( OSAL_CBTIMER_NUM_TASKS ) osal_CbTimerInit( taskID ); taskID += OSAL_CBTIMER_NUM_TASKS; #endif L2CAP_Init( taskID++ ); GAP_Init( taskID++ ); GATT_Init( taskID++ ); SM_Init( taskID++ ); GAPRole_Init( taskID++ ); GAPBondMgr_Init( taskID++ ); GATTServApp_Init( taskID++ ); /* MyApplication */ MyTask_Init( taskID ); //这里的taskID也是11,跟taskArr中的保持一致。 }
综上所述,OSAL提供的接口还是比较清晰的,开发人员要做的就是搞定应用的task,然后按照OSAL提供的接口放入即可。