蓝牙如何初始化,02蓝牙外设初始化
蓝牙如何初始化,02蓝牙外设初始化OSAL直译就是操作系统抽象层。它是一个类操作系统的事件驱动型软件框架。每建立一个任务,都会分配一个唯一任务ID,同时对应一个任务事件处理函数,用来处理不同的事件。然后不断地轮询每个任务,判断其是否有事件需要处理,如此往复。1、了解OSAL:4、采用截图的方式,将整个实验过程还原出来,附带行号,便于学习的小伙伴们能依据图文完全重复实验结果。本文目标:弄清楚广播前的初始化。正文:
说明:
1、蓝牙协议栈版本:1.5.1.1
2、蓝牙IC:CC2540或者CC2541
3、IDE版本:IAR For 8051 10.20.1
4、采用截图的方式,将整个实验过程还原出来,附带行号,便于学习的小伙伴们能依据图文完全重复实验结果。
本文目标:弄清楚广播前的初始化。
正文:
1、了解OSAL:
OSAL直译就是操作系统抽象层。它是一个类操作系统的事件驱动型软件框架。每建立一个任务,都会分配一个唯一任务ID,同时对应一个任务事件处理函数,用来处理不同的事件。然后不断地轮询每个任务,判断其是否有事件需要处理,如此往复。
建立任务,如加粗的SimpleBLEPeripheral_Init( taskID )就是官方例程建立的一个Demo应用任务,该初始化在文件OSAL_SimpleBLEPeripheral.c中:
void osalInitTasks( void )
{
uint8 taskID = 0;
tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);
if (tasksEvents != NULL)
{
osal_memset( tasksEvents 0 (sizeof( uint16 ) * tasksCnt));
}
else
{
HAL_ASSERT_FORCED();
}
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 );
SM_Init( taskID );
GATT_Init( taskID );
GAPRole_Init( taskID );
GAPBondMgr_Init( taskID );
GATTServApp_Init( taskID );
SimpleBLEPeripheral_Init( taskID );
}
以上任务集对应一个事件处理函数表,该表中存放的是事件处理函数指针:
图1(操作文件:OSAL_SimpleBLEPeripheral.c)
2、关注(暂时)两个初始化
图2(操作文件:OSAL_SimpleBLEPeripheral.c)
在GAPRole_Init()中会确定gap角色状态为初始态,gap角色为外设等
图3(操作文件:peripheral.c)
而在SimpleBLEPeripheral_Init()中则进行各种参数的初始化,详见源码。
3、关注(暂时)两个任务(由OSAL调度执行)
图4(操作文件:OSAL_SimpleBLEPeripheral.c)
这两个任务(所有任务都是)是轮询执行的,OSAL一直在轮询所有的任务,查看是否有需要处理的事件。先说第二个任务SimpleBLEPeripheral_ProcessEvent,这是个OSAL调度任务,会随着系统的运行,不断地产生各类事件来触发不同的执行流程。在外设初始化SimpleBLEPeripheral_Init()的最后会触发启动设备事件,如下图:
图5(操作文件:simpleBLEPeripheral.c)
于是在SimpleBLEPeripheral_ProcessEvent()中进行了如下处理:
图6(操作文件:simpleBLEPeripheral.c)
即启动设备,启动绑定管理,设置周期运行事件。而设备一旦启动,就执行各类初始化动作,当初始化完成时就会产生SYS_EVENT_MSG事件,并通知OSAL进行相关处理,这就引出了第一个任务GAPRole_ProcessEvent,如下:
图7(操作文件:peripheral.c)
调用函数gapRole_ProcessOSALMsg()处理消息:
图8(操作文件:peripheral.c)
再调用函数gapRole_ProcessGAPMsg()处理gap消息:
图9(操作文件:peripheral.c)
至此,设备初始化完成,保存密钥、设备地址,并更新广播数据。GAP状态变为GAPROLE_STARTED,触发回调函数peripheralStateNotificationCB(),显示本机地址以及初始化完成标识:
图10(操作文件:simpleBLEPeripheral.c)
4、输出提示信息
由于官方例程用LCD进行输出显示,为了学习的各位小伙伴们能更加简单地学习,我们之后的所有实验测试都是基于串口来实现的,这样只要你有个蓝牙模块就可以实现所有我们讲述的例程。
在不改变源码结构的基础上,我们来实现串口输出提示信息。首先在hal_lcd.c中加入引用串口的头文件:
图11(操作文件:hal_lcd.c)
接着,修改LCD显示字符串函数void HalLcdWriteString ( char *str uint8 option),在该函数最后添加串口输出函数:
图12(操作文件:hal_lcd.c)
5、编译下载
图13(实验结果)
6、扩展说明:
GAP: Generic Access Profile,即通用访问规范(当然还有其他译法,暂且这么翻译)。具体相关概念自己查阅。这里要说明的是,作为初学者,我们只要知道GAP是干嘛的就行,简单来说就是负责设备配置,设备初始化,安全管理,设备发现,建立连接,断开连接等,都是与连接相关的(准备、建立,管理,终止等)。