77范文网 - 专业文章范例文档资料分享平台

关于TI的CC2541的程序解读(3)

来源:网络收集 时间:2019-03-16 下载这篇文档 手机版
说明:文章内容仅供预览,部分内容可能不全,需要完整文档或者需要复制内容,请下载word后使用。下载word有问题请添加微信号:或QQ: 处理(尽可能给您提供完整文档),感谢您的支持与谅解。点击这里给我发消息

就有结果的,而是要通过空中无线协议栈去完成,完成后有消息返回来的。此时才正式确认读写成功。

F 再回头来从头到尾将这个主任务看一遍,有点看懂了

于是以上过程就基本分析完成了一半多,还有一些分析过程放下了没来得及分析。 在这种情况下,再从头到尾将程序读一遍,以便为未读完的部分做点准备。 █仔细看一下UP键的处理有几个问题:

GAPCentralRole_StartDiscovery( DEFAULT_DISCOVERY_MODE,

DEFAULT_DISCOVERY_ACTIVE_SCAN,

DEFAULT_DISCOVERY_WHITE_LIST ); 在初次按下UP键后,会调用上面这个函数 中心角色启动发现,也就是启动扫描。

另一个问题是,在此连接情况下按下UP键,将分别进行读,写操作。这个读写操作的句柄是怎么来的呢?req.handle = simpleBLECharHdl;---这是写时,要得到这个句柄才能写。 另外还有一个通讯句柄,也要的,如下:

status = GATT_WriteCharValue( simpleBLEConnHandle, &req, simpleBLETaskId ); 一个是特征值句柄,一个是通讯句柄。两个都要的。 此外还要注意到这两个函数都是封装在库里的。它必然产生一些消息或事件给我们的函数来处理。因为它是提交给无线栈了,处理完后有信息返回的,一般是成功或失败。 具体的我们先看到这,只是提出问题,后面的函数自然会回答的。

再看一下左键做了些什么?左键看上去好象是选择某一个下位机连接的。它负责的是将这个变量simpleBLEScanIdx++。这个变量是一个非常重要的变量。

右键,似乎更新连接:

GAPCentralRole_UpdateLink( simpleBLEConnHandle,

DEFAULT_UPDATE_MIN_CONN_INTERVAL, DEFAULT_UPDATE_MAX_CONN_INTERVAL, DEFAULT_UPDATE_SLAVE_LATENCY, DEFAULT_UPDATE_CONN_TIMEOUT ); 中间键比较重要,它用于连接或断开与某一个下位机的连接。

如果simpleBLEState == BLE_STATE_IDLE这个状态是空闲的,已连接,正在连接,正在断开4种可能性之一。 将对某一个进行连接:

peerAddr = simpleBLEDevList[simpleBLEScanIdx].addr; addrType = simpleBLEDevList[simpleBLEScanIdx].addrType; simpleBLEState = BLE_STATE_CONNECTING;

GAPCentralRole_EstablishLink( DEFAULT_LINK_HIGH_DUTY_CYCLE, DEFAULT_LINK_WHITE_LIST, addrType, peerAddr );

这里,用到了simpleBLEScanIdx很重要的变量,即已经扫描到的某个下位机。 而DOWN键,则决定是否显示RSSI信号强度。

█接下来的一个函数,是处理系统事件,加上附带的消息。

它是因为操作了键引起的。例如,UP键进行了读写,于是最后会触发到系统消息过来。UP

11

中间键,建立连接,也会有系统消息传过来。

建立连接时,只有当simpleBLEDiscState != BLE_DISC_STATE_IDLE才会去处理,哪么这个simpleBLEDiscState 什么时候给个值呢?原来在

void simpleBLECentralStartDiscovery( void )中,给过这个值

那又是谁在调用这个函数呢?这个在主任务的一个事件发生时,才会调用这个值,哪个这个事件START_DISCOVERY_EVT是谁给的呢?原来的建立连接时给的。哪么为什么会有建立连接这个事情发生呢?肯定是因为按下了中间键引起的。这里就能说得通了,由于按下了中间键,从而调用了一个建立连接的函数,而这个函数就会给一个回调函数发送一个事件,这个事件就是建立连接事件,这个事件中会产生一个开始发现事件给主任务,主任务在这个事件中会调用开始发现这个函数,开始发现这个函数会将这个simpleBLEDiscState 这个变送置为非空闲。非空闲就会去处理simpleBLEGATTDiscoveryEvent(pMsg).而这个函数会发现服务,发现特征量,发现完后会将这个变量置为空闲。发现服务和发现特征量时,会给句柄赋值?居然没发现,哪到底在哪里给这些句柄赋值的呢? 在建立连接时,就将通讯句柄赋值了:

simpleBLEConnHandle = pEvent->linkCmpl.connectionHandle; ///在建立连接事件时,将当前的连接句柄

simpleBLEProcedureInProgress = TRUE; ///设为当前的处理句柄

而在发现特征量时,有下列:

simpleBLECharHdl = BUILD_UINT16( pMsg->msg.readByTypeRsp.dataList[0], pMsg->msg.readByTypeRsp.dataList[1] ); 于是给这个特征量赋值了。

因此,这个回调函数是用来处理这个发现事件的,即发现某一指定的下位机的服务和特征。 它这里又是一个状态机来处理的。发现服务和发现特征是分两步完成的。

█下面仔细看一下这个回调函数,这个回调函数处理的不是主任务的系统事件,也不是主任务的其它事件,而是它内部的一些事件,这些事件,是由于启动了这个主机引起的,即我们在主任务开始时为响应这个events & START_DEVICE_EVT,启动了下列:

VOID GAPCentralRole_StartDevice( (gapCentralRoleCB_t *) &simpleBLERoleCB ); // Register with bond manager after starting device

GAPBondMgr_Register( (gapBondCBs_t *) &simpleBLEBondCB ); ///让绑定自动处理 启动了设备,也注册了绑定过程。

绑定过程在本例子中没做什么事,因为我们将它设为无需密码可直接连接的。

事实上,发密码过去是发一个随机的数过去。下位机我们已配置成无需密码连接了。

这个回调函数有几个事件要处理:

1. 初始化完成事件,此时就将本机的地址显示出来就可以了。什么时候调了一个初始化函数呢?在设置回调函数时就初始化了。

2. GAP设备资料事件 在发现这个下位机资料后,将这个下位机的信息加进去,特别注意到 simpleBLEScanRes++;将这个总共发现了多少个设备++一下。这里可能以后很有用的,因为以后用手机对多个下位机时,已经设置过的我们就不要再去设置它了,而且在扫描到这些下位机时,直接将它跳过去。但是扫描到的下位机怎么识别呢?下位机总有一个地址的,可以供识别的。另外,它还有字符串吗?(名称,不过名称也许是一样的,我们也许只扫描一类名称,别的名称如耳机就不要管它了,是不是可以这样?)另外在哪里发现它的名称呢?这

12

个本该是扫描时的工作吧。每扫描到一个下位机从设备,我们就会出现这个事件。

3. GAP_DEVICE_DISCOVERY_EVENT-----这个有点象设备扫描结束了时出来的这个事件。因为我们看到它将扫描完成后的通道数放到simpleBLEScanIdx = simpleBLEScanRes; 而这个simpleBLEScanRes=pEvent->discCmpl.numDevs; 所以感觉到它是扫描完成了调用的似的。

4.GAP_LINK_ESTABLISHED_EVENT 建立连接事件,这个前面已经分析过了。这里有: simpleBLEState = BLE_STATE_CONNECTED;

simpleBLEConnHandle = pEvent->linkCmpl.connectionHandle; ///在建立连接连接句柄 simpleBLEProcedureInProgress = TRUE; ///设为当前的处理句柄 我们在这个地方,将当前通讯句柄得到了。很重要的一个句柄。 5.GAP_LINK_TERMINATED_EVENT 这个就不多分析了。

6.GAP_LINK_PARAM_UPDATE_EVENT这个没做任何不处理。

G 我只能说,初步的理了一遍,该看的都看过了,基本理解了。

我现在想找到从机名称,看在这个事件中能否找出来,主要看两个事件,最主要是看GAP_DEVICE_DISCOVERY_EVENT和GAP_DEVICE_INFO_EVENT

先看第一个,将断点设在此。但是由于调试器看数据结构很不方便,没有发现这个下位机的名称。但总是会隐在某个地方的。

为此,我们再看一下从机的程序吧。从机是我们真正要做的,主机实际上是手机。要了解主机部分,还需要再看一下BTOOLS运行部分的程序看一看。

从机看过了,没有什么收获。

要不再看一下HostTestRelease 看从中能看出点什么过来。我想这个程序中应该通过串口给主机一些指令,主机随后根据这些指令去执行,应该可以看出点更详细的东西出来。 但是很难看下去。所以又转换一下思路: 看一下这个一拖三的系统处理过程:

1.首先按下UP键,此时将调用下列函数:

GAPCentralRole_StartDiscovery( DEFAULT_DISCOVERY_MODE, ///启动扫描 DEFAULT_DISCOVERY_ACTIVE_SCAN,

DEFAULT_DISCOVERY_WHITE_LIST ); 这个就是开始扫描,并不是开始连接

2 开始扫描后,所有事件将由这个处理

simpleBLECentralEventCB( gapCentralRoleEvent_t *pEvent ) 每扫到一个设备,就会有这个事件产生:GAP_DEVICE_INFO_EVENT此时我们看到可以打印扫到的这个设备及它的RSSI。正是在这里,本来想在这里将RSSI比较大的扫描的连接上,小的就不要连上了。但是后面发现这样不行,因为在扫描完成后,即GAP_DEVICE_DISCOVERY_EVENT后,它有下列处理:

simpleBLEScanRes = pEvent->discCmpl.numDevs; ///发现了多少下位机 将总数设置一下 osal_memcpy( simpleBLEDevList, pEvent->discCmpl.pDevList,

(sizeof( gapDevRec_t ) * pEvent->discCmpl.numDevs) ); ///全部拷进来了

13

当然,我们可以不管这个,将它删除后看一下是否不处理这个事件会有什么结果。如果可以不管这个,我们就可以将以前处理过的(因为我们已经得到了地址,处理过的保存起来了,我们总是在不停地扫描,看有没有新的进来,有新的进来就给它建立连接,已经处理过的就终止连接)

3.到此为止,程序将什么事也不做直到按下了中心键后,一键连接。

首先调用这个函数:performPeriodicTask_AutoConnect()这个函数主要的工作就是将第一个扫描到的下位机的地址取出来,且执行:

GAPCentralRole_EstablishLink( DEFAULT_LINK_HIGH_DUTY_CYCLE, DEFAULT_LINK_WHITE_LIST, addrType, peerAddr );

注意到取的地址为序号为simpleBLEScanIdx,而这个值在什么地方置0了?检查一下正是在设备扫描完毕后,将这个值置为0了。

4.调用这个函数后,将传一个事件:----自动连接事件,但是这个事件在1.6秒后才发生。 osal_start_timerEx(simpleBLETaskId,SBP_AUTO_CONNECT_EVT, SBP_PERIODIC_EVT_AUTO_CONNECT );

5.此时面临两个事情要做,一个是建立连接,将会产生连接事件,另一个是主任务要去响应这个自动连接事件。看它们是如何处理的?注意到这个自动连接事件延时了1.6秒。比较长,在这种情况下,应该建立连接这个事件早就执行了,故执行连接会被先响应。于是有

GAP_LINK_ESTABLISHED_EVENT事件发生。看在这中间发生了什么?在这里同样用到了关键变量:simpleBLEScanIdx。先将连接的句柄保存下来--这个很重要。然后将特征量句柄清0,这个句柄将在未来的某个地方设置。然后它将发送下列: osal_start_timerEx(simpleBLETaskId,START_DISCOVERY_EVT, DEFAULT_SVC_DISCOVERY_DELAY );

发送一个开始发现事件给任务 注意到这个延时仅为1ms基本上就是立即发送了。注意到在这里,这个变量simpleBLEScanIdx并没有++。

6.主任务在接到这个事件后,即调用simpleBLECentralStartDiscovery()这个函数的作用是 p->simpleBLEDiscState = BLE_DISC_STATE_SVC; ///状态改为正在发现服务 GATT_DiscPrimaryServiceByUUID( p->simpleBLEConnHandle, uuid,

ATT_BT_UUID_SIZE, simpleBLETaskId ); 下面这个函数是一个库函数,表示开始进行服务发现。 7 在服务发现期间,会反复的自动调用:

simpleBLEGATTDiscoveryEvent( gattMsgEvent_t *pMsg )

这里是这样处理的:先将起始句柄和未了句柄设置一下,这个看上去我们没有用到它: p->simpleBLESvcStartHdl = pMsg->msg.findByTypeValueRsp.handlesInfo[0].handle;

p->simpleBLESvcEndHdl = pMsg->msg.findByTypeValueRsp.handlesInfo[0].grpEndHandle; p->simpleBLEDiscState = BLE_DISC_STATE_CHAR1; req.startHandle = p->simpleBLESvcStartHdl; req.endHandle = p->simpleBLESvcEndHdl; req.type.len = ATT_BT_UUID_SIZE;

req.type.uuid[0] = LO_UINT16(SIMPLEPROFILE_CHAR1_UUID); req.type.uuid[1] = HI_UINT16(SIMPLEPROFILE_CHAR1_UUID);

14

GATT_ReadUsingCharUUID( p->simpleBLEConnHandle, &req, simpleBLETaskId );

然后去发现这个特征值1。

后来,得到了特征值1的句柄:

p->simpleBLECharHdl[0] = BUILD_UINT16( pMsg->msg.readByTypeRsp.dataList[0], pMsg->msg.readByTypeRsp.dataList[1] );

后面又去发现特征值6,在发现后又得到特征值6的句柄。

此时,第1个设备的连接就完成了。接下来,开始要连接第2个设备。

这时,1.6秒也已经到了,出现事件SBP_AUTO_CONNECT_EVT,于是会出现下列现象,如果simpleBLEScanIdx=simpleBLEScanRes 表明已经连上了所有的扫描到的从机,此时就会退出,再也不会进行连接动作了。

这里我们特别注意到simpleBLEScanRes 这个值,它在扫描事件中被设置了的。这个在扫描完成后设置了,而不是在GAP_DEVICE_INFO_EVENT中进行任何处理,故如果只用这个GAP_DEVICE_INFO_EVENT的话,就会出问题的。除非将这个值进行++处理。 如果没有完成,则会simpleBLEScanIdx++。这个很重要。然后它会: performPeriodicTask_AutoConnect(); // 执行动连接

osal_start_timerEx(simpleBLETaskId,SBP_AUTO_CONNECT_EVT, SBP_PERIODIC_EVT_AUTO_CONNECT );

这时,又会执行一个建立连接的动作。注意到在前面按下中间键时,已经进行了这个动作。 于是最后将所有扫描到的都连接上了。如果在此期间,有连接的失败的,将这个值: p->simpleBLEState = BLE_STATE_CONNECTED;

不会被设置。并且将这个p指向的结构设置为初始值。此后在发数据时就不会乱发了。 注意到断开连接时,这个simpleBLEScanIdx并没有--。即在设备列表中并没有去掉这个值。

8.如果一切顺利,这个设备都连接好了,且连了3个。当然如果设备本来少于3个,就按实际个数连接。

9.接着等按键操作了。先看几个简单的。比如按下down键。把所有的已经建好连接的下位机的RSSI回调函数激活或取消。

GAPCentralRole_StartRssi( p->simpleBLEConnHandle, DEFAULT_RSSI_PERIOD );// 关键 为了达到轮流激活取消的效果,用到了p中的一个变量p->simpleBLERssi来进行判断。

10.如果按下了左键,而且不是在扫描状态,即扫描完成了,就是显示各个下位机的地址。注意此时这个simpleBLEScanIdx++; 所以如果在按下中间键之前,按了左键,这个值就会变掉。到时,如果没有按中间键就去按这个左键,这个程序感觉要出错似的?不过不会了,因为在按下中间键时,会将这个值清0的。

11.如果按下了右键,这个是去更新参数,暂时不管这个了。

12.如果按下了开发板上的S1键,这个才是最复杂的,要开始发数据了。

15

百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库关于TI的CC2541的程序解读(3)在线全文阅读。

关于TI的CC2541的程序解读(3).doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印 下载失败或者文档不完整,请联系客服人员解决!
本文链接:https://www.77cn.com.cn/wenku/zonghe/528230.html(转载请注明文章来源)
Copyright © 2008-2022 免费范文网 版权所有
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ: 邮箱:tiandhx2@hotmail.com
苏ICP备16052595号-18
× 注册会员免费下载(下载后可以自由复制和排版)
注册会员下载
全站内容免费自由复制
注册会员下载
全站内容免费自由复制
注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: