ti蓝牙40协议栈解析Word文档格式.docx
- 文档编号:20487115
- 上传时间:2023-01-23
- 格式:DOCX
- 页数:8
- 大小:21.06KB
ti蓝牙40协议栈解析Word文档格式.docx
《ti蓝牙40协议栈解析Word文档格式.docx》由会员分享,可在线阅读,更多相关《ti蓝牙40协议栈解析Word文档格式.docx(8页珍藏版)》请在冰豆网上搜索。
每个数据包的每次接收都是用32位寻址,理论上可连接十亿台设备。
针对一对一连接,并支持新型拓扑的一对多连接。
d蓝牙4.0总共40个信道,都分布在2.4ghz,其中0.12.39三个信道用来广播信息。
e蓝牙4.0的引起超低的功耗而备受瞩目。
是3.0的升级版,较3.0更加省电,成本更低,3ms低延迟,超长有效连接距离,aes-128加密;
2.ble
a.蓝牙4.0规范中的一种,其中master最多有7个外设,低功耗,低延迟,低吞吐量。
b.
六种设备状态
待机状态(standby):
设备没有传输和发送数据,并且没有连接到任何设备
广播状态(advertiser):
周期性广播状态
扫描状态(scanner):
主动寻找正在广播的设备
发起链接状态(initiator):
主动向扫描设备发起连接。
主设备(master):
作为主设备连接到其他设备。
从设备(slave):
作为从设备连接到其他设备。
五种工作状态
准备(standby),广播(advertising),监听扫描(scanning),发起连接(initiating),已连接(connected)
四种设备类型
cnetral主机(常作为client端):
如手机,pc
peripheral从机(常作为service端):
如心率计,血糖计
observer观察者:
broadcast广播者:
连接过程:
peripheral开启广播-->
central扫描从机广播-->
peripheral接收到central的扫描请求,
peripheral向central发送扫描回应数据-->
central向peripheral发起连接-->
开始通信。
c.ble中的连接参数(connectionevent==确认连接应答信号-->
设备大多数情况下都在sleep状态下,每个connectionevent都由master发起包,在由slaver回复)
参数1:
connectioninterva-->
l两个connectionevent之间的空闲值,单位为1.25ms,最小
7.5ms,最大4s。
参数2:
slavelatency-->
slaver设备没有数据要发时,跳过一定数目的connectionevent的值,Rang:
0-499.
参数3:
supervisiontimeout-->
超时时间,就是两个设备在连接的这段时间没有发生通讯而导致连接自动断开的值。
Range(10ms-----32s)但是必须满足以下条件参数3>
=参数1*(参数2+1)。
d.兼容性
ble协议结构
a.结构可分为三大层(
控制层(controller)(hci、ll、phy))
协议层(host)(l2cap、sm、att、gatt、gap)
应用层(app)(gattprofile和gapRole/securityprofiles)
b.各层单元逻辑
phy物理层:
主要是射频和电路部分
ll链路控制层:
通过计算器的设置来控制物理层
hci通讯层:
向host和controller提供一个标准化接口,该层可以由软件api实现或者用硬件接口uaRtspiusb来控制
l2cap逻辑链路控制和适配层:
负责逻辑链路的连接以及事件的分发,位于基带协议之上。
l2cap向上层提供面向连接的和无连接的数据服务。
它的功能包括:
协议的复用能力、分组的分割和重新组装以及数据组提取。
l2cap允许高层协议和应用发送和接受高达64byte的数据分组
sm安全服务层:
提供配对密匙的发放,实现安全链接和数据交换
att属性层:
是ble中一个很重要的一层,所有的数据都要经过这层,展示属性的称为服务器,与之配对的称为客户端。
主机设备可以是服务器也可以是客户端
规定了client和server两个角色,数据存在service端,以attribute形式存在,client则以读或写的方式来对server端数据进行操作
gatt定义使用att的服务框架
gatt规定了配置文件(profile)结构。
在ble中所有的profile或者服务用到的数据块都称为“特性”characteristic,基于att层更加细化的根据性质把传输的数据分成特定的类并标上uuid(每类att也有一个独特的uuid)gap主要用于设备查找,连接建立,广播发送接收的一些控制
app层:
profile定义的是特定的一个使用环境,相同的也有个uuid
c.名词解释
profile:
可以理解成是一种规范,蓝牙组织规定了一系列的profile,如心率计,防丢器等。
每个profile中都会包含多个service
service:
可以理解成一个服务,在ble从机中,通过多个服务(如电量信息服务,系统信息服务等),每个service里面包含多个characteristic特征值。
characteristic特征值才是bel的主体,(如:
点量80%。
会通过电量的characteristic特征值存在从机的profile里,这样主机可以通过这个characteristic来读取80%这个数据。
)
characteristic:
characteristic特征值,主从机的通讯全是通过characteristic来实现的,可以理解为一个标签,通过这个标签可以获取或者写入想要的内容
uuid:
统一识别码我们刚才提到的service和characteristic,都需要一个唯一的uuid来标识。
cc2540
a.芯片特性
内部由一个51内核和基本外设构成,时钟频率可达32mhz,机器周期为一个时钟周期,拥有内部阻容振荡器,8kbRam,256kbFlash
5通道dma,1个16位,两个8位定时器,红外生成电路,32khz有捕捉功能睡眠定时器
数字信号强度指示器(Rssi),电池监视和温度感应器,8通道12位adc,2个uaRt,usb拥有smartReadybluetooth两个模式,cc2541支持(bR和ble模式)
传输速率:
低于100kbps
b.引脚分配
c.最小系统
篇二:
第十五节ble蓝牙4.0协议栈启动分析
第十五节ble蓝牙
4.0协议栈启动分析
ti的这款cc2540/cc2541器件可以单芯片实现ble蓝牙协议栈结构图的所有组件,包括应用程序。
从这章开始我们来剖析协议栈源码,我们选用
simplebleperipheral工程开刀,这是一个从机的例程,基本的工作是对外广播,等待主机来连接,读写展示的属性。
首先打开工程文件,打开后可以看到整个工程的结构。
我们按照系统的启动顺序来一步一步走,我们都知道在c代码中,一般启动的首个函数为main,这个函数在simplebleperipheral_main.c中,打开文件,可以看到这个文件只有一个main函数和一个函数的申明,我们暂时不理会那个申明的函数,先看main都做了些什么工作:
1
2
3
4
5
6
7
8
9
10
11
12
13intmain(void){/*initializehardware*/hal_boaRd_init();
//硬件初始化//initializeboardi/oinitboard(ob_cold);
//板级初始化/*initialzethehaldriver*/haldriverinit();
//hal驱动初始化/*initializenVsystem*/osal_snv_init();
//Flash存储snV初始化/*initializell*//*initializetheoperatingsystem*/osal_init_system();
//osal初始化
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34}/*enableinterrupts*/hal_enable_inteRRupts();
//使能总中断//Finalboardinitializationinitboard(ob_Ready);
//板级初始化#ifdefined(poweR_saVing)osal_pwrmgr_device(pwRmgR_batteRy);
//低功耗管理#endif/*startosal*/osal_start_system();
//noReturnfromhere启动osalreturn0;
通过代码我们可以看到,系统启动的过程,主要是做了一些初始化,如果开启了低功耗,则还需要开启低功耗管理。
我们先不去理会初始化做了什么,但是我们知道在main函数的最后启动了osal,那么我们就进去看看osal是如何运作的。
在iaR中如果需要跳转到某个函数或变量的定义,可以在此函数名中右击然后选择gotodefinition……就可以调到相应的定义。
9voidosal_start_system(void){#if!
defined(zbit);
)//Foreverloop#endif{osal_run_system();
}}
这里看到我们进入了一个死循环,并且一直调用osal_run_system(),那我们再进入此函数。
5 678910111213141516171819202122232425262728293031323334353637383940414243444546474849osaltimeupdate();
//定时器更新#endifhal_processpoll();
//hal层信息处理do{if(tasksevents[idx])//taskishighestprioritythatisready.{break;
}}while(++idxti蓝牙4.0协议栈,解析)erconserve();
//puttheprocessor/systemintosleep}#endif/*yieldincasecooperativeschedulingisbeingused.*/#ifdefined(configuse_pReemption)}#endif}
篇三:
蓝牙4.0协议栈按键流程分析
在介绍蓝牙按键流程分析之前,我们需要了解一个概念,那就是就是osal。
什么是osal呢?
可能大伙对于os是比较了解的,学了计算机的搞过os的也基本接触过,简单来说就是一个操作系统抽象层,可以理解为运行在cc2540上的操作系统,说操作系统还不能算,ti的osal只实现了任务切换和消息机制。
并且把协议栈的代码、硬件处理的代码,用户程序的代码等分别放到了osal层的不同任务处理函数中去了,各任务函数之间通过消息机制、同一个任务之间通过事件的的方式来通信。
什么是eVent事件?
osal为每个任务函数分配了一个16位的事件变量,每一位代表一个事件,最高位为0x8000
表示为系统事件sys_eVent_msg。
其余的15位留给用户自定义需要的事件。
通常事件由定时
器启动,比如一秒后我要点亮led2,这就需要发送一个点亮led2的事件,然后等待定时器1s后溢出,于是启动点亮led2事件,事件会调用相应的hal层api点亮led2。
什么是msg消息
msg是比eVent事件更具体并且可以携带数据的一种通信方式,msg的标记是按数值,而不是按位。
比如0x01和0x02是两个不同的消息,但对于事件0x03则是0x01事件和0x02事件的组合。
msg收发使用osal_msg_send()和osal_msg_receive();
当调用osal_msg_send()发送一个msg的同时会在eVent列表中触发一个messagereadyevent。
(请注意最后一句话,这句话点出了为什么按键时间的触发为何会导致系统事件也接受到了)
现在以simplebleperipheral为例说明按键流程
在simplebleperipheral任务初始化函数中有这样一条代码:
//Registerforallkeyevents-thisappwillhandleallkeyevents
RegisterForkeys(simplebleperipheral_taskid);
这个函数来自onboard.c源文件中/**********************************************************************keyboardRegisterfunction**thekeyboardhandlerissetuptosendallkeyboardchangesto*onetask(ifataskisregistered).**ifataskregisters,itwillgetallthekeys.youcanchangethis*toregisterforindividualkeys.*********************************************************************/uint8RegisterForkeys(uint8task_id){//allowonlythefirsttaskif(registeredkeystaskid==no_task_id)
{
registeredkeystaskid=task_id;
return(true);
}else
return(false);
}
向一个全局变量registeredkeystaskid中赋值自己的任务id,调用了这个函数就能成功注册按键服务,那这个全局变量在何时使用呢?
分析到这里,感觉有点迷糊了,我们可以从顶到下分析。
任何一个程序都是从main函数开始的,这点我们要坚信。
所以我们首先找到这个main函数
打开simplebleperipheral_main.c文件可以看到/**************************************************************************************************
*@fnmain*
*@briefstartofapplication.*
*@paramnone*
*@returnnone***************************************************************************************************/intmain(void){/*initializehardware*/
hal_boaRd_init();
//initializeboardi/o
initboard(ob_cold);
/*initialzethehaldriver*/
haldriverinit();
/*initializenVsystem*/
osal_snv_init();
/*initializell*//*initializetheoperatingsystem*/
osal_init_system();
/*enableinterrupts*/
hal_enable_inteRRupts();
//Finalboardinitialization
initboard(ob_Ready);
#ifdefined(poweR_saVing)
osal_pwrmgr_device(pwRmgR_batteRy);
#endif/*startosal*/
osal_start_system();
//noReturnfromherereturn0;
}
我们打开initboard(ob_Ready);
可以看到如下代码/*********************************************************************
*@fninitboard()
*@briefinitializethecc2540dbboardperipherals
*@paramlevel:
cold,waRm,Ready*@returnnone*/voidinitboard(uint8level){if(level==ob_cold){
//interruptsoff
osal_int_disable(ints_all);
//turnallledsoff
halledset(hal_led_all,hal_led_mode_oFF);
//checkforbrown-outreset
//chkReset();
}else//!
ob_cold{
/*initializekeystuff*/
onboardkeyintenable=hal_key_inteRRupt_enable;
//onboardkeyintenable=hal_key_inteRRupt_disable;
halkeyconfig(onboardkeyintenable,onboard_keycallback);
看到我上面标注的函数了吧?
那个是一个按键回调服务注册函数,注册了一个onboard_keycallback函数
halkeyconfig函数的实现:
将上述的回调函数的地址复制给了函数指针变量。
通过跟踪发现该函数的指针变量在按键的轮询函数中调用了,如下图:
/**************************************************************************************************
*@fnhalkeypoll
*
*@briefcalledbyhal_drivertopollthekeys
*@paramnone
*@returnnone**************************************************************************************************/
voidhalkeypoll(void)
uint8keys=0;
uint8notify=0;
#ifdefined(cc2540_minidk)
if(!
(hal_key_sw_1_poRt
(hal_key_sw_2_poRt
#else
(hal_key_sw_6_poRt
if((hal_key_joy_moVe_poRt
#endif
/*ifinterruptsarenotenabled,previouskeystatusandcurrentkeystatus
*arecomparedtofindoutifakeyhaschangedstatus.
*/
hal_keyintenable)
if(keys==halkeysavedkeys)
/*exit-sincenokeyshavechanged*/
return;
else
notify=1;
/*keyinterrupthandledhere*/
if(keys)
/*storethecurrentkeysforcomparationnexttime*/
halkeysavedkeys=keys;
/*invokecallbackifnewkeysweredepressed*/
if(notify
}在这里底层的按键查询函数调用一个函数指针,而非具体的函数,这样就将处理按键的接口留给了上层,上层应用中,叧需解析的函数指针传入的参数1:
keys就知道是哪个按键被按下了。
我们再回到刚才的onboard_keycallback回调函数处,该回调函数代码如下:
/*********************************************************************
*@fnonboard_keycallback
*@briefcallbackserviceforkeys
*@paramkeys-keysthatwerepressed
*state-shifted
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- ti 蓝牙 40 协议 解析