.前言
小弟初来乍到,这是小弟的第一篇博客,暂时还在上学,没有什么工作经验,本篇博客主要记录我在这几天学习BLE协议协议栈的一点心得体会,并用一个主从透传的实验来记录过程,如有错误之处,还望各位大佬多多包涵
二.工程环境
- CC2541核心板 * 2
- CC Debugger * 1
- USB转TTL串口模块 * 2
- BLE-1.4.2协议栈
- IAR For 8051 10.20.1
- 脑子+核桃仁
三.实验过程
1.简介
说简单点就是,低功耗(号称一颗纽扣电池用一年,没量过我也不晓得),然后可以用主机和从机数据传输(废话)。
2.工程说明
本次工程是主从透传实验,也就是两块CC2541的板子通过USB-TTL连接到PC,PC打开两个串口助手,且一个串口助手发送的信息可以被另一个串口助手接收到,这就叫串口透传(大神绕道)。
BLE4.0是TI公司在OSAL这个系统上开发的一款协议栈,已经将底层的一些操作全部封装成Lib库,用户是看不到底层的,我们只需要大致了解以及学会使用就可以了。
本博客不讲原理,只讲实际。
3.从机协议栈配置
首先要打开一个BLE的例程(当然你得先装好BLE的协议栈和IAR,IAR的版本不限制,这个自行百度吧),如下图所示:
没啥讲究,双击打开,粗暴点.....
这个工程是从机的工程
如果使用的是高版本的IAR,请打开工程后选择如下图所示的最上面的一行,右击----Option-----General Opyions-----Number of Virtual修改为8,否则会出现编译错误。
首先我们了解一下特征,特征值这些玩意儿
在蓝牙BLE中做一个不恰当的比喻,有两个人,路人甲和路人乙,路人甲前面有n个篓子,比如4个吧,然后路人乙可以拿篓子里的东西或者向篓子里放东西,
但路人甲有规定
第一个篓子只能拿不能放
第二个篓子能拿能放
第三个篓子不能拿只能放
第四个篓子不太一样,路人甲自己放东西进去后,他会通知路人乙里边放了什么东西,路人乙只能放,不能主动拿。
以上两个人,路人乙代表是蓝牙通讯中的主机,或者叫客户端
路人甲代表的是蓝牙通讯中的从机,或者叫服务器
以上4个篓子,每个篓子代表一个特征
篓子里的东西代表的就是特征值,也就是每个特征的数据,
路人甲的规定(能拿,能放,能够通知路人乙有什么东西)就代表了特征的属性(可写,可读,可通知)
所以,一个特征由特征值,属性等一些东西组成,而一个BLE从机可以有几个特征
这个不恰当的比喻大致就简单的描述了一下蓝牙BLE通讯的内容。
好,那么我们开始为从机添加一个篓子,也就是一个特征(TI给的协议栈例程里本身就有5个特征值,我们自己再添加一个)
添加数据一般在GATT层,也就是simpleGATTprofile.c文件里增加特征(此文件在IAR左边的文件树里的Profile文件夹下)
首先添加特征的UUID和数据的容量,通俗的讲就是篓子的编号和篓子最多能放多少东西(不理解的话不要紧,往后慢慢就懂了,先定义了就是),还有我使用的是Visual Studio,看代码修改代码方便一点,贴的图不大一样,你们用IAR一样修改,不用管。
接下来,进入到simpleGATTprofile.c,增加UUID的变量,直接复制上边Characteristic 5 UUID就可以,然后粘贴,改一下就好(方便)
在接下来,我们添加属性,下图我们可以看到,
1.我们Char6的属性,权限是GATT_PROP_NOTIFY | GATT_PROP_WRITE即可通知,可写(也就是路人乙可以向篓子里放东西,路人甲可以通知路人乙,篓子里有哪些东西)(专业点:主机可以往特征值里写入数据,不能主动读取数据,从机可以随时通知主机,我这个特征的特征值是啥,当然主机要获得通知,必须打开从机的通知开关,这个下面会讲,暂时不管)
2.我们的char6特征的特征值是多少,即篓子里最大能放多少东西
static uint8 simpleProfileChar6[SIMPLEPROFILE_CHAR6_LEN] = { 0 };
也就是说CHAR6这个特征内定义了一个数组,数组长度我们开头定义了是10,就是说篓子的容量就是10个字节;
3.static gattCharCfg_t *simpleProfileChar6Config,这个比较特殊,只要特征是可通知的,也就是GATT_PROP_NOTIFY ,那么必须要这一个变量,里边保存了通知开关的状态,入打开了通知或关闭通知。
4.就是个名字
下面我们把属性添加进属性表里,属性表其实是一个数组,我们在下图添加了4个数组元素,那么我们就要先把数组的元素个数改一下,我们加了4个,所以改成17+4=21,这四个属性拷贝上面的,然后复制下来再修改就好了,这里用的GATT_PERMIT别看错了,这里就不说了,就是把刚刚定义的那些属性加入到一张表里,就这样
接下来修改SimpleProfile_SetParameter函数,这个函数的作用是写入特征值(只有从机有,从机可以随时读写所有特征值)
怎么修改,在case sIMPLEPROFILE_CHAR5这一块操作下面添加CHAR6的操作,如下图所示,注释写好了。
接下来修改SimpleProfile_GetParameter,这个函数的作用就是从机获取指定特征的特征值,这个就没啥好说的,一目了然。
接下来是两个回调函数,一个读回调,一个写回调,也就是说,主机向从机的特征中写入数据,那么从机会马上跳进写入的回调函数,主机读取从机的特征值,从机就马上跳进读回调函数,就是这样
第一个,读回调函数:添加一个case是CHAR6的,如下图红框所示,直接照搬上面CHAR5的,改个数字,完事儿,置于哪里把数据发送给主机的一会儿说(这个是协议栈自动发给主机的,不需要我们写什么代码,只要把数据放到pValue中就行了)
第二个,写回调函数:在函数中再加一个case,CHAR6的,如下图,作用就是,主机要写入从机的特征值,这个函数会被调用,然后由这个函数,将主机发来的数据拷贝到从机本身的特征值中(当然你也可以有骚操作,就不写入特征值,直接对数据进行骚操作)
好的,到这里,GATT层已经写完了
下面就是应用层的修改了,例程的应用层源文件是simpleBLEPeripheral.c
一进去就先看SimpleBLEPeripheral_Init,很明显,初始化函数,是OSAL系统来后,应用层第一个调用的函数,初始化,这里修改的东西不多,就一个串口初始化,和特征值初始化,很简单,不废话贴图
串口初始化:UART_CB是串口接收到数据后的回调函数
我们来看看NPI_InitTransport的实现,这里也需要修改一些东西:
在npi.c文件中,我们需要修改波特率和关闭流控,两个宏定义改成右边这样就好了,波特率115200,流控FALSE
,再看下图,BLE的串口使用的是DMA+超时(其实我不大确定),所以,判断一下event&HAL_UART_TIMEOUT看看是不是接收到数据了,如果收到了,使用OSAL提供的发起事件函数启动发送数据的事件,再往下看事件
这个就是刚刚回调中发送的事件在uint16 SimpleBLEPeripheral_ProcessEvent(uint8 task_id, uint16 events)函数中
大致做了以下几个事情:①用NPI_RxBufLen读取串口缓存区内的收到的数据长度,如果有数据就使用NPI_ReadTransport读取数据到定义的数组内,然后通过SimpleProfile_SetParameter写入CHAR6的特征值,然后回到上面这个函数的实现那里看看,是不是会将写入的数用通知发送给主机?这样子是不是就顺理成章了?(当然如果主机没有打开从机的通知,这里就只是写入特征值,不会通知特征值给主机)
好了,到这里,我们就实现了,我们PC通过串口写数据给CC2541从机,然后从机将数据发送给主机的过程
我们还需要在用户层对主机发来的数据进行一些处理,也就是将主机数据打印到串口,实现透传
我们已经修改过了GATT层的回调,但GATT层的回调并不是最后的回调函数,调用玩GATT层的回调函数后,会继续回调应用层的一个回调函数:static void simpleProfileChangeCB( uint8 paramID )
我们应用层的操作都在这里,很明显TI的例程已经写了几个,我们不去管它,粗暴的添加一个CHAR6,做了什么呢?
首先SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR6, Char6Buff);这个GATT层的函数已经在前面实现过了,很明显获得CHAR6的特征值,保存到Char6Buff里,
然后NPI_WriteTransport(Char6Buff, strlen(Char6Buff));,把数据发送到串口,完成了,这就好了,主机发过来数据直接传到串口。
到这儿我们完成了主机发来的CHAR6数据转发到串口的任务。
最后,我们还需要添加一点点小配置,我不确定不配置会不会有什么影响,但最好还是配置吧,不多
在simpleGATTprofile.c中,初始化通知吧......两个红框,模仿char4的写就是了
还有一个处理主机发来的打开通知的请求,这个case在GATT层的写回调函数里simpleProfile_WriteAttrCB,收到主机请求打开通知是,调用函数打开通知开关,就好了,这一段是必须的,
全部完成,最后编译前还需要修改一些东西,IAR的配置,加上HAL_UART=TRUE还有在低功耗POWER_SAVING前加个x,也就是宏定义的是xPOWER_SAVING,而不是POWER_SAVING,也就不会进去低功耗,你前面加个a,abcd,123都随意。
最后,编译,下载,手机下个fastBLE调试吧
然后主机的程序,稍等