打印
[蓝牙]

TI蓝牙BLE 协议栈代码学习 转

[复制链接]
2792|23
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
geraldbetty|  楼主 | 2020-7-16 20:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
I的蓝牙4.0BLE协议栈为BLE-CC254x-1.4.0,即现在的版本是1.4版本的。可以从TI官方下载或从附件中下载安装,默认是安装在C盘中。因为上一篇博文提到进行空中固件升级,当时没有安装在C盘下,死活生成不了bin文件,改在C盘下生成了。所以,我个人建议,还是默认安装吧,也占不了多大空间。
TI蓝牙4.0BLE协议栈的结构如下图所示:
由控制器和主机两部分构成,分层的思想很明晰。
控制器包括物理层PHY、数据链路层LL和主机控制器接口HCI构成。
物理层PHY是1Mbps自适应跳频的GFSK射频,工作于免许可证的2.4G频段。
数据链路层LL用于控制设备的射频状态,使设备工作于Standby(准备)、Advertising(广播)、Scanning(扫描)、Initiating(初始化)、Connected(连接)五种状态中的一种。
主机控制器接口HCI为主机和控制器之前提供标准的通信接口。

主机包括逻辑链路控制及自适应协议层L2CAP、安全管理层SM、属性协议层ATT、通用访问配置文件层GAP、通用属性配置文件层GATT构成。
逻辑链路控制及自适应协议层L2CAP为上层提供数据封装服务,允许逻辑上的点对点通信。
安全管理层SM配对和密钥分发服务,实现安全连接和数据交换。
属性协议层ATT允许设备向其他设备展示一块特定的数据,这块数据称之为“属性”。
通用属性配置文件层GATT定义了使用ATT的服务框架和配置文件(profile),BLE中所有数据的通信都要通过GATT层。
通用访问配置文件层GAP提供设备通信的接口,负责处理访问模式和程序,包括设备发现、建立连接、终止连接、初始化安全和设备配置等。
对于我们来说,直接接触的是GAP和GATT两个层。
最早接触这个项目的时候,听说CC2540/2541是51内核的SOC,当时我心想,毛毛雨啦,51的东东还不简单。等真接手了才发现,头大了,TI的工程师把协议栈封装和规划得都很好,不能不佩服。
先分析协议栈的流程吧,这里以TI的KeyFobDemo为例,该工程位于C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\KeyFob中。先看下工程的架构。对于我们开发来说,App和Profile两个文件夹中的内容是最主要的。
先从main()函数入手,打开App文件夹下的KeyFob_Main.c,找到main()函数:


  • int main(void)



  • {



  •   /* Initialize hardware */



  •   HAL_BOARD_INIT();//初始化硬件







  •   // Initialize board I/O



  •   InitBoard( OB_COLD );//初始化板卡IO







  •   /* Initialze the HAL driver */



  •   HalDriverInit();//初始化HAL层驱动







  •   /* Initialize NV system */



  •   osal_snv_init();//初始化Flash







  •   /* Initialize LL */







  •   /* Initialize the operating system */



  •   osal_init_system();//初始化OSAL







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



  • }



////////////////
上述代码,我加入了简单的中文注释,会发现有个很重要的东西——OSAL,Operation System Abstraction Layer,操作系统抽象层。OSAL还不是操作系统,但是实现了OS的很多功能。从前面的代码中我们可以看到,跟OSAL相关的有两个函数osal_init_system()和osal_start_system()(osal_pwrmgr_device()暂时先不去理会)。我们依次来看看。
在IAR环境中,可以在代码中osal_init_system()上单击鼠标右键,打开“Go to definition of osal_init_system”,

osal_init_system()在OSAL.c中,下面就是该函数的代码:


  • uint8 osal_init_system( void )



  • {



  •   // Initialize the Memory Allocation System



  •   osal_mem_init();//初始化内存分配系统







  •   // Initialize the message queue



  •   osal_qHead = NULL;//初始化消息队列







  •   // Initialize the timers



  •   osalTimerInit();//初始化定时器







  •   // Initialize the Power Management System



  •   osal_pwrmgr_init();//初始化电源管理系统







  •   // Initialize the system tasks.



  •   osalInitTasks();//初始化系统任务







  •   // Setup efficient search for the first free block of heap.



  •   osal_mem_kick();







  •   return ( SUCCESS );



  • }


该函数是完成一系列的初始化,跟操作系统有关的,仿佛是osalInitTasks(),我们进到这个函数里面。osalInitTasks()OSAL_KeyfobDemo.c中。


  • void osalInitTasks( void )



  • {



  •   uint8 taskID = 0;







  •   tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);



  •   osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt));







  •   /* LL Task */



  •   LL_Init( taskID++ );







  •   /* Hal Task */



  •   Hal_Init( taskID++ );







  •   /* HCI Task */



  •   HCI_Init( taskID++ );







  • #if defined ( OSAL_CBTIMER_NUM_TASKS )



  •   /* Callback Timer Tasks */



  •   osal_CbTimerInit( taskID );



  •   taskID += OSAL_CBTIMER_NUM_TASKS;



  • #endif







  •   /* L2CAP Task */



  •   L2CAP_Init( taskID++ );







  •   /* GAP Task */



  •   GAP_Init( taskID++ );







  •   /* GATT Task */



  •   GATT_Init( taskID++ );







  •   /* SM Task */



  •   SM_Init( taskID++ );







  •   /* Profiles */



  •   GAPRole_Init( taskID++ );



  •   GAPBondMgr_Init( taskID++ );







  •   GATTServApp_Init( taskID++ );







  •   /* Application */



  •   KeyFobApp_Init( taskID );



  • }




从每行代码,可以看到整个事件初始化的过程也是分层的。从链路层任务初始化(LL_Init)到硬件抽象层(Hal_Init)、主机控制器接口(HCI_Init)、逻辑链路控制及自适应协议层(L2CAP_Init)、GAP层(GAP_Init)、GATT层(GATT_Init)、安全管理层(SM_Init)。然后完成GAP层的配制(GAPRole_Init)、蓝牙绑定的管理初始化(GAPBondMgr_Init)及GATT层服务的初始化(GATTServApp_Init)。最后完成的是应用层的初始化(KeyFobApp_Init)。程序是一行一行地执行,各层的任务也是依次的完成初始化。

使用特权

评论回复

相关帖子

沙发
21ic小喇叭| | 2020-7-30 16:37 | 只看该作者
从链路层任务初始化(LL_Init)到硬件抽象层(Hal_Init),这一块,没太看明白,可以再讲讲吗

使用特权

评论回复
板凳
waveforms| | 2020-7-30 19:53 | 只看该作者
最近准备开始学蓝牙,先看下资料

使用特权

评论回复
地板
gygp| | 2020-8-1 21:51 | 只看该作者
怎么检测ble协议栈的数据是否发出

使用特权

评论回复
5
chenci2013| | 2020-8-1 21:56 | 只看该作者
蓝牙BLE SPP的区别是什么

使用特权

评论回复
6
biechedan| | 2020-8-1 21:56 | 只看该作者
         

使用特权

评论回复
7
wangdezhi| | 2020-8-1 21:56 | 只看该作者
蓝牙4.0ble服务端与客户端怎么区分

使用特权

评论回复
8
isseed| | 2020-8-1 21:56 | 只看该作者
BLE设备上的GATT服务是怎么搭建的

使用特权

评论回复
9
xietingfeng| | 2020-8-1 21:56 | 只看该作者
ble 的协议栈如何与rtos配合使用  

使用特权

评论回复
10
xietingfeng| | 2020-8-1 21:57 | 只看该作者
协议栈到底需要多少栈空间  

使用特权

评论回复
11
suzhanhua| | 2020-8-1 21:57 | 只看该作者
如何修改mtk的ble广播包  

使用特权

评论回复
12
mituzu| | 2020-8-1 21:57 | 只看该作者
如何使用BLE蓝牙模块

使用特权

评论回复
13
hellosdc| | 2020-8-1 21:57 | 只看该作者
蓝牙BLE开发,如何持续读取设备端的数据?

使用特权

评论回复
14
uiint| | 2020-8-1 21:57 | 只看该作者
BLE低功耗蓝牙模块是什么?

使用特权

评论回复
15
xietingfeng| | 2020-8-1 21:57 | 只看该作者
ble cc254x-1.4.1用哪个版本的iar

使用特权

评论回复
16
wangdezhi| | 2020-8-1 21:57 | 只看该作者
蓝牙模块单模式和双模式有什么区别?

使用特权

评论回复
17
chenci2013| | 2020-8-1 21:57 | 只看该作者
蓝牙音箱ble双模是什么意思

使用特权

评论回复
18
hellosdc| | 2020-8-1 21:57 | 只看该作者
BLE(低功耗蓝牙)的MTU是什么  

使用特权

评论回复
19
suzhanhua| | 2020-8-1 21:58 | 只看该作者
ble cc2541设置发射功率的函数在哪儿  

使用特权

评论回复
20
isseed| | 2020-8-1 21:58 | 只看该作者
是底层的东西吗?  

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

22

主题

1359

帖子

0

粉丝