#define START_TEST_EVT 0x01 -------------启动时加个事件试一下simpleBL...h
B处理函数部分:它定义在simpleBLECentral.c中 我们怎样来处理这件事呢?---简单一点
这样行不行?先在初始化中,增加一个定时器事件。
在这个任务中,在收到定时器事件后,让灯反转一下,并重新开启一个定时器事件。这样灯就不停地反转了。不这么做。
复杂一点,就是先调用这个函数:
osal_start_timerEx (Hal_TaskID, HAL_TEST_EVENT, HAL_KEY_DEBOUNCE_VALUE); 我们先将一个事件,发给内核任务去处理
#define HAL_TEST_EVENT 0x1000 -----这个定义在hal_drivers.c中
于是,在内核中就要增加对这个事件的处理。但是这个处理很简单
我们知道,这个HalKeyPoll()总是要在按键被调用的。这个是有按键事件发生时才调用,所以不能将这个事件处理放在这里。
但是我们在Hal_ProcessEvent()中处理这件事情的。于是我们将这个事件放到这里来处理,在这个函数中增加对这个的处理部分。原来键处理是在回调函数中处理的,我们直接。。。 但是有一个要定义一下,就是定义一个时间到事件
#define TIMER_ARRIVED 0xC1 //gxd 2015/11/25
下面我们再总结一下这个过程。
1.初始化时,我们先给这个我们加的这个任务,即其ID号为MyTestTaskId,其运行的任务名为:MyTestEvent的这个任务,发送一个事件:(事件定义在simpleBLECentral.h文件中) osal_set_event( MyTestTaskId, START_TEST_EVT ); 启动测试事件,因为这个任务中也没有什么其它事件,故我们就将这个事任定义为0x01 我们知道它最多有16个事件。一般来说,这个0x8000就是系统事件。注意到每个任务都有自已怕系统事件。系统事件不是唯一的。
2.这个任务一旦运行,马上就会收到这个事件。在收到这个事件后,会向内核中的HAL事件处理程序发送一个延时后的事件
osal_start_timerEx (Hal_TaskID,HAL_TEST_EVENT, HAL_TIMER_DEBOUNCE_VALUE);
3.内核程序是专门处理这个事件的。所以过一段时间,就会收到它,这个时间长度为1000。单位是多少呢?需进一步了解----发现它的单位是ms 看函数定义中的注释中有。
4.内核事件处理程序中,会直接调用 Test_Send( 0, 0 );这个函数。这个函数将调用: osal_msg_send( MyTestTaskId, (uint8 *)msgPtr );即给MyTestTaskId发送一个信息。 注意看到原来键中断处理却不是这样做的,它原来的方法是在中断中,给内核任务发送一个键事件,在这个键事件处理中,调用keyPoll()中将键值得到,然后调用一个回调函数---我们预定定义好的。在这个回调函数中,调用了OnBoard_SendKeys()这个函数,在这个函数中给我们的这个任务发一个系统消息,且将消息设置了一下。 osal_msg_send( registeredKeysTaskID, (uint8 *)msgPtr );
6
而现在的做法是直接给测试任务发一个消息。
5. 于是我们的测试任务就会收到这个消息,而且是个系统消息。收到这个系统消息后,系统消息中的事件是 TIMER_ARRIVED 调用这个 My_TEST_ProcessOSALMsg()这个消息。在处理这个消息过程后,将销户这个消息。
6.在销户了这个消息之后,为了让这个过程不断地进行下去,我们再给内核发送一个测试事件。于是这个过程继续下去。
发现这个延时启动的计时器的单位为ms.故我们将这个时间定为1000。
发现加了这部分程序后,系统就死机了。跟踪发现信息没有发送过去。 后来发现程序将事件名称写错了,拷贝时忘记改引起的,修改后好了。
串口经常少打一个回车。而且是每打印5次就会发生这样的错误一次。这个不知所以了?
D 试着理解一下BLE协议部分,感觉有点乱
下面再继续读一下其它的代码部分
先看系统事件,它处理按键和GATT消息部分。
先看简单点的,消息处理:消息处理就是读写部分,当读或者写指令发出后,它在交给无线部分收发后,完成后会有响应,这个响应有4种情况,读错误,写错误,读成功,写成功。 下面具体看一下这个处理:
如果没有建立连接,则直接返回,这个可理解。 如果是读响应,(读出错不在这里)或读请求则有: uint8 valueRead = pMsg->msg.readRsp.value[0]; 证明这个消息中含有读的值。这个消息格式如下: typedef struct {
osal_event_hdr_t hdr; //!< GATT_MSG_EVENT and status uint16 connHandle; //!< Connection message was received on uint8 method; //!< Type of message
gattMsg_t msg; //!< Attribute protocol/profile message } gattMsgEvent_t;
如果不是读,也不是写,而且正在忙的话,就是在做发现的事情。例如,在接到发现从机事件时,就将这个状态改变成正在发现状态:simpleBLEDiscState = BLE_DISC_STATE_SVC; 此时就不是闲了。而如果有消息过来,要不就是读,要不就是写,要不就是在发现。 所在在收到了系统消息后,一个看这个消息是不是按键消息,一个看消息中附加的事件是不是GATT消息,如果是GATT消息,则进一步看是读还是写还是其它。其它只有一种情况就是发现消息。而这个发现消息也是因为按了UP键引发的。
最后我们还是看一下键处理,尽管这个键处理比较复杂一些。
●先看UP键。如果没建立连接,就调用一个函数去发现从机扫描。如果正在扫描时按下UP键,就终止扫描了。不过除非你连接按两下UP,不然因为连接速度很快,不会出现终止扫描这种情况。
如果已经建立连接了,按UP键的话就是一次是写,一次就是读,一直按一直这样做下去。 ●再看一下左键处理。
7
显示扫描到的设备号。按一下换一个,直到最多8个又回来了。
●再看右键 是连接更新。这个不知在做什么,因为源代码看不到在库里。
●再看中心键,如果选择要连接的从机是空闲状态,还没有进行连接,则进行连接,如果已经是连接状态,则断开连接。
●再看DOWN键,每按一次,是读取RSSI或取消读取RSSI。 注意到扫描和连接是两件事情。扫描只是看下面有多少从机。而连接则是给指定的从机去连接。连的是谁则通过左键去选。做试验时我们只有一个从机,只买了一个。
程序还是没有看完全,还得继续努力去消化一下。只有多花时间多去看,对代码看上去就记住得差不多的时候,这个代码也就看得差不多了。这样下来速度是慢了点,但是比较深入一点。
我们再一次将客户机(中心)这个程序解读一遍:
先看在这个事件处理程序:它处理三种事件,第1种是系统事件,第2种是启动事件,第3种是开始发现事件。
简单点的先看第3种。第3种是一个开始发现事件。我想这个开始发现事件应该是按了UP键后发出的吧。本来也没有必要搞这么一个绕来绕去的,在按键中直接调这个函数simpleBLECentralStartDiscovery( );不就行了吗?我们看一下在什么地方触发了这个事件? static void simpleBLECentralEventCB( gapCentralRoleEvent_t *pEvent )中调用了这个事件。 在GAP_LINK_ESTABLISHED_EVENT事件中,发调用这个 osal_start_timerEx(simpleBLETaskId,START_DISCOVERY_EVT, DEFAULT_SVC_DISCOVERY_DELAY );
照理,我们应该在UP键中会出现这个发现设备事件?
理解错了,原来这个是发现FFF0服务?而不是发现从机。原来是与从机建立连接后,再启动这个发现从机服务的过程,而不是扫描从机。注意到这里发现FFF0服务的服务。下位机如果有N个,则怎样去发现呢?另外每个下位机它的服务都是FFF0吗? 我估计下回还要看一下同时连接3个从机的例子能从中间找点线索吧。 调用了这个发现从机服务后,还要做什么呢?此时应该可以与服务器的特征参数通讯了吧? 只能先跟踪到这里了。过一会再来回顾这部分的处理吧。
接下来我们看到第2种事件,就是启动事件,启动事件由这个任务的init()的。 启动事件中,也做了不少事情的,主要有:
注册了两个函数,其中一个是RSSI事件处理回调函数和一个状态处理回调函数,也就是收到一些事件后,如何处理收到的事件消息。
绑定处理函数,这个可能是处理密码与配对的吧。也是一个回调函数。 于是我们再稍深入一点,看RSSI函数回调到底做了些什么? RSSI回调函数,就做了一件事,将RSSI的值显示在屏幕上。 事件处理函数有点比较复杂,它的目的是处理一些事件:
GAP初始化完成事件,初始化完成后,将信息在屏幕上显示出来。 设备资料事件:在一个给定的广播的服务UUID列表中,发现一个给定的UUID(FFF0吗?) 设备发现事件:在屏幕上显示设备发现,和去选择这个字样。
建立连接事件:它会调用一个osal_start_timerEx( simpleBLETaskId, START_DISCOVERY_EVT, DEFAULT_SVC_DISCOVERY_DELAY );生成一个事件,然后由任务中去开始发现指定的从机。这个有点象是建立连接? 断开连接事件:显示连接被断开。
参数更新事件:就是显示一个para,update在显示屏上。
8
接下来我们看比较麻烦的最后一个,就是系统事件。系统事件含两种消息处理,一种是按键消息处理,一种是GATT消息处理。其中GATT消息处理有三种情况,读,写,不闲着。前两种比较简单一点,就是从自带的消息中将字符取出来。并显示在屏幕上。 后面一个就调用这个函数:simpleBLEGATTDiscoveryEvent( pMsg );
这个函数处理GATT发现函数。这个函数中,处理两种情况,一种是服务发现,一种的特征发现。在特征被发现后就将它进入空闲状态。
服务发现干些什么事呢?当一切顺利时,就将状态置为特径发现,便于下一次来处理。 将FFF1这个值会设置进去,也就是说好象只对FFF1进行操作。 特征发现,保存处理句柄,这个没理解。等待以后理解吧。 最后看一下键盘处理吧:
UP键,是去扫描用的。调用了一个GAPCentralRole_StartDiscovery函数。如果已经连接,则分别去写,读这个相关联的句柄中的某一个字符。但只是进行读写动作,读写完成后自然会在一个回调函数中处理的。simpleBLECentralProcessGATTMsg()会有GATT事件消息产生的。
LEFT键---显示多个下位机设备。每按一次,显示一个。直到。。 右键: 更新连接------不知道这个是做什么用的。
中间键:相当于一个回车键,它是确认它或者是断开连接。
下键: 它不断地显示这个RSSI值。再按一下,就是不再显示了。 初步看完来,再自上而下看一遍代码
看到simpleBLEGATTDiscoveryEvent( gattMsgEvent_t *pMsg )这个函数理解一下。
这个函数在GATT事件中,当不是读,也不是写时,而且也不是闲时,就会调用这个函数去处理这个消息。我们知道系统消息有两个,一个是按键消息,一个是GATT消息。GATT消息应该是由于操作按键引起的。
当simpleBLEDiscState != BLE_DISC_STATE_IDLE时,表示它的发现状态处理空闲时,但却有系统事件传过来,说明此时就是发现事件要处理了。发现状态有三种状态,一种是空闲,一种是发现了服务,一种是发现了特征值。 建立连接失败了,就将这个置为空闲了。 终止连接了,也将这个标志置为空闲了。
调用发现FFF0的服务,则这个标志置为BLE_DISC_STATE_SVC---这个是唯一一个给值的 发现服务成功了(完成了),就将这个标志置为BLE_DISC_STATE_CHAR 发现特征后,就将它又置为空闲了。
什么时候会调用发现FFF0服务呢?这个在事件处理中,当( events & START_DISCOVERY_EVT )时,就会调用发现FFF0这个服务。 哪这个事件又由谁触发的呢?这个是由建立连接事件引起的。建立连接又是由谁引起的?这个是由按下中间键引起的。于是整个流程就比较清楚了。
E总结很重要,这里有点不乱了
这样总结一下:
●先是按下了UP键,开始扫描下位机。而且将搜到的下位机可以全部显示出来,这部分当前还没有读到。(稍后再继续读下去余下的代码也许就明白了)
●然后是左键可以选择指定的下位机。按左键时有simpleBLEScanIdx++,这个非常重要。
9
这个是选定要连接的从机中的哪一个从机用的。非常重要。
●接下来,再就是按下中间的键,就可以对指定的下位机进行连接。这个指定的从机就是用这个simpleBLEScanIdx数来代表的,这个是序号,又一次很重要。 在对下位机进行连接过程中,会调用下列函数:
GAPCentralRole_EstablishLink( DEFAULT_LINK_HIGH_DUTY_CYCLE, DEFAULT_LINK_WHITE_LIST, addrType, peerAddr );
注意到这个参数地址类型,对方地址。这个是对指定的从机进行连接。 peerAddr = simpleBLEDevList[simpleBLEScanIdx].addr; addrType = simpleBLEDevList[simpleBLEScanIdx].addrType;
下位机的地址及类型,是从一个设备列表中找出来的。而其中有一个比较重要的量就是: simpleBLEScanIdx,这个变量就是我们选定的要连接的下位机的设备序号。而这个序号又是怎么来的呢,是按左键选定得来的。至于它总共有多少个下位机被发现且放到列表数组中这个暂时不考虑。等一会看完所有的代码,也许自然就知道了(又一次轻轻放下它再说,人生需要先放下很多次,不然脑袋就乱了)。
●当调用了上面的“中心角色建立连接”函数后,我估计它会产生一个事件,就是GAP_LINK_ESTABLISHED_EVENT。这个事件是由回调函数处理的。因为我们在一开始启动了一个中心角色的设备的时候,就将这个回调函数附着上去。建立连接后,它会推一个定时器延时的事件产生(当然这里还有很多其它的事件会产生,这只是其中的一个),它就是 osal_start_timerEx(simpleBLETaskId,START_DISCOVERY_EVT, DEFAULT_SVC_DISCOVERY_DELAY );
●因此过一会儿,也就是1秒后,它会给我们的任务发现一个事件,这个事件就是开始去发现服务和特征值。我们的主任务在收到这个事件后就会调用: simpleBLECentralStartDiscovery( ); ///调用发现从机函数 在这个函数中,我们只查找FFF0的服务。
simpleBLEDiscState = BLE_DISC_STATE_SVC; ///现处于发现服务状态 这个重要! // Discovery simple BLE service 这个函数在库里面,其它地方好象找不到 GATT_DiscPrimaryServiceByUUID( simpleBLEConnHandle,
uuid, ////FFF0 ATT_BT_UUID_SIZE, /// 2
simpleBLETaskId ); ///由哪一个任务ID去处理的 这里特别注意到第一个参数:simpleBLEConnHandle,它是在建立连接时被设置的。即按下中心键后,产生了连接事件,在这个事件中被设置的。
于是我们就是处理这个发现过程,而这个发现过程会引起系统事件,并附加有消息,这个消息的处理用这个函数来处理的simpleBLEGATTDiscoveryEvent( gattMsgEvent_t *pMsg )中间非读,非写的部分。
●调用了这个函数后,就会产生一些系统消息,这个系统消息不是按键消息,它的事件而是GATT_MSG_EVENT。于是我们就要处理这个消息了。这个GATT_MSG_EVENT有三种可能性,一种是读,一种是写,一种就不是读也不是写,它就是去将消息处理一下 if ( simpleBLEDiscState != BLE_DISC_STATE_IDLE ) simpleBLEGATTDiscoveryEvent( pMsg );
●在发现完成后,它会将simpleBLEDiscState = BLE_DISC_STATE_IDLE等于空闲的,后面读或写时就不会跑到发现这个地方去了
●到了这一步,就可以对读写的特征值进行读写了。而对这些特征值的读或者写,不会马上
10
百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库关于TI的CC2541的程序解读(2)在线全文阅读。
相关推荐: