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

OSAL解读笔记(4)

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

osal_start_timerEx(simpleBLETaskId,SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD ); 这个就是每0.4秒调用一次。

实际上是执行了下列函数:

OneConnetedDevice_WriteCharX(simpleBLEScanIdx, BLE_CHAR1,&simpleBLESendValue, 1); 第一个参数是当前的连接下位机号,第2个参数是特征值,第3个是要发送的字符,第4个是长度。这里先给特征值1写一个字节下去。随后这个值++。 然后就是往特征值6发送一个字符串:

OneConnetedDevice_WriteCharX(simpleBLEScanIdx,BLE_CHAR6,(uint8*)str, osal_strlen(str)); 这个串有几个字符,它含义为 “time=ld”注意到发送完后,有simpleBLEScanIdx++; GATT_WriteCharValue( p->simpleBLEConnHandle, &req, simpleBLETaskId ); 发送完后,应该有返回结果看一看吧。 事实上,发送完的结果在

void simpleBLECentralProcessGATTMsg( gattMsgEvent_t *pMsg )中得到体现的:

LCD_WRITE_STRING_VALUE(\ 但是这里好象只处理了特征值1的部分,对于特征值6的部分没有处理。

事实上,我们要找到这个BLE_DEV *p = simpleBLECentralGetDev(pMsg->connHandle); 即找到下位机的设备列表中的句柄。但没有去找特征,是特征1还是6好象没办法分辩出来。这里暂时跳过吧。

13.有一个地方没有理解,就是在这个GATT事件处理中,有下列: else if ( p->simpleBLEDiscState != BLE_DISC_STATE_IDLE ) {

simpleBLEGATTDiscoveryEvent( pMsg ); }

于是整个程序都读了一遍,再回顾一下。

看一个简单的,给几个已连上的下位机发数据部分:

这个程序没有对是否连上作出判断,不管后来下位机是否关机,反正都是往下位机发送,而且也没有个停止机制不停地发。正式程序似不能这样。应允许关掉下位机。

再看一个连接performPeriodicTask_AutoConnect()

注意到如果 已经连接,或者正在连接,或者正在断开连接,这三种情况下,都会调用断开连接这个函数。

gStatus = GAPCentralRole_TerminateLink( p->simpleBLEConnHandle );

注意到这个断开连接中,带有一个参数,就是连接句柄,故断开连接它是断开某一个下位机的连接,而不是断开所有的连接。

在空闲时,会调用建立连接这个函数。于是在事件处理函数中(不是本任务的事件处理,而是回调函数的事件处理)会处理一切事宜。再往下看这些连接事宜是如何处理的。

建立连接事件中,会先将这个下位机的连接句柄保存下来,然后,调用: osal_start_timerEx(simpleBLETaskId,START_DISCOVERY_EVT, DEFAULT_SVC_DISCOVERY_DELAY ); 于是会有一个发现事件发到我们的主任务中。

16

在这个任务中,会处理这个

p->simpleBLEDiscState = BLE_DISC_STATE_SVC; ///将这个状态变为发现服务 GATT_DiscPrimaryServiceByUUID( p->simpleBLEConnHandle, uuid,

ATT_BT_UUID_SIZE, simpleBLETaskId );

调用这个后,将GATT事件中,产生一个调用,而这个调用中,有读,有写,除这两个之外的就是发现服务,还有一个就是下位机往上发的通知。

p->simpleBLEDiscState != BLE_DISC_STATE_IDLE时,它就是表示要进行发现服务工作。因为我们在建立连接时,会将它设为SVC。

再理一遍:

A再看一下,这个建立连接,是被按下中心键触发的。在按下中心键时,我们就将这个序号置为0了(IDX)。 B于是,在回调函数中就会有建立连接的响应。于是在这个响应中,将把这个句柄保存下来。且将特征值句柄清0,然后调用发现服务事件被发送到主任务中。主任务收到这个事件后,调用发现服务(当然,先将这个状态变为发现如上文中的兰色字符)

C 在GATT事件中,会有反应,主任务中,会有系统事件发过来,它们不是按键事件,而是另一个GATT事件。在这个事件处理中除了读,写,下位机往上发之外,因为你已经将这个变成兰色部分了,因此,它就会去调用这个函数:

D simpleBLEGATTDiscoveryEvent(),正是在这个函数中,得到特征1和特征2的句柄的。注意到我们这里并没有用到IDX这个变量,而是在这个发现服务这个值中,它的pMsg中含有连接的句柄,通过这个句柄,找到我们要处理的下位机,而不是依靠IDX去找下位机。 再看兰色字符处的设置SVC,在什么地方改回IDLE的呢?正是在发现了特征6之后,再 p->simpleBLEDiscState = BLE_DISC_STATE_IDLE;了。

E 在第一个下位机完成之后,又怎样接着去发现第2个呢?原来是按下中心健后, osal_start_timerEx(simpleBLETaskId,SBP_AUTO_CONNECT_EVT, SBP_PERIODIC_EVT_AUTO_CONNECT ); 产生了一个自动连接事件引起的。这个自动连接事件会不断地调用

performPeriodicTask_AutoConnect(); // 执行动连接--不停地进行除非。。。直到原来扫描到的3个从机都连完了。

现在再来看一个手机综合的例子,这个例子是手机为上位机,我们只编写下位机程序。测量温湿度,控制开关状态及测量AD值。这与我们的应用比较符合的。

先看广播信息: FFF0 09错? 我们得到下列广播信息: ? ? ? 1+a

02 01 06 0b 52 45 4e 59 57 45 4c 4c 02 f0 ff 0b 09 41 6d 6f 53 6d 61 72 74 R E N Y W E L L A m o S m a r t 52 46 05 12 06 00 06 00 02 0a 后面全是0 R F

兰色部分是广播数据:advertData[] 0b指的是扫描数据

17

这样看来,广播数据并没有含MAC地址和RSSI部分,它只含有几个简单的信息。如果上位机不扫描,则它就不会有进一步的信息了,所以,我们如果想决定是否和它连接,必须在这个广播包中,就将一个我们规定的地址发出去。不然没办法筛选。因为连过的东西我们不想再连接了。这样看来,我们要在广播包中含有一个唯一的编码。这个编码可以是MG0001,这个都是不可修改的。手机的APP可以设为只去扫描编码前为匹配的才会去连接,而且,已经连过的也不会再去连接。

下位机在连接好之后,先进行AD转换,同时等上位机的命令。: 下位机编码规定如下:

XX X XXXXX

产品名称两位 产品类别 地址 最多99999个

类别:1--4~20mA 2--0~5V 3 0~10V 4 串口

上位机可对下位机进行配置,如果为模拟量,则配置命令为:

参数名称 参数量程 (即满量程为多少值)串口命令串 位置描述字符串 这4个参数都是以长度+参数来表示的。支持双字节的汉字。

例如参数名称为 pm2.5 1000ppm 无 轧钢一厂3车间1号鼓风机环境量 配置命令为 0x05 pm2.5 7 1000ppm 0 0x1e “轧钢一厂3车间1号鼓风机环境量” 如果为串口,则为

0x05 ?pm2.5? 0x07 ?1000ppm? 0x03 0x68 0x02 0x05 0x1e ?轧钢一厂3车间1号鼓风机环境量?

其中68 02 05是发给传感器的询问值。 如果是模拟量采集,则它为0 电池电压也是一个很重要的参数要读取的。

看一下这个周期性的任务在做什么?原来在做这个采集温度和湿度。

对于我们来说,这个没必要,只要读的时候采一下就可以了。

Char5,6,7,8,9,A都是为了读数据上去的。它们在回调函数中调用。程序中最多读20个字节上去,这个要改掉。

Char1,2,4 是读的,它的读只有一个字节。但是它在读什么,还没搞清楚。 Char1 Char2 Char3 Char4 Char5 Char6 Char7 Char8 Char9 charA 读 上位机用来读温湿度 获得系统名字部分 用来获得高低温报警部分 用来将AD采样值发上去 用来读PWM值 写 用来做写,让某个LED亮/灭的 用来做串口用的。下位机收到后打印出来。 用来修改本系统名字的 用来设定最高,最低报警的 好象没什么用处 用来设置PWM的 上位机可以读它的更新时间 用来更新updatetime的。会收到4个字节。

详细看一下这个函数:

static void peripheralStateNotificationCB( gaprole_States_t newState )

18

这个函数是由启动事件中,设置了它,仔细看一下,它处理连接过程中的一些事宜:

case GAPROLE_STARTED: 处理GAP角色初始时的事宜,它将system_id这个值用MAC address代替。由于MAC为6位,system_id为8位,故它将中间两位清零了。 case GAPROLE_ADVERTISING:开始广播时,将这个信息打印显示一下。 case GAPROLE_CONNECTED: 已经连接时,将这个信息打印一下。 case GAPROLE_WAITING: 这个注释为正断开,有点词不达意似的。

case GAPROLE_WAITING_AFTER_TIMEOUT: 这个表示超时了,含义不清楚。

我想在连接时读AD,发串口命令(如果有的话)还是怎么读? 我们先让这个调试运行一下看一看。

结果发现这个串口没有打印,但有时候偶尔又有打印,原因未找到。本来运行就会打印,结果运行后,要等手机扫描后,再点击进到主界面时,才会有打印信息出现。 还有就是经常扫描不到设备,非得要按一个复位键才会扫描到。

再看一下keyfob这个TI的例子:

定义了,正好看一下它是如何得到电池电压的。

#define BATT_ADC_LEVEL_3V 409 应该是4096 为什么是409。 #define BATT_ADC_LEVEL_2V 273 一时没看懂。

串口现在可以打印了,因为进入了休眠模式。去掉就好了。

现在试一下,存储128个ASCII,从00到7F 然后再打印出来看一下。

我们先在启动时将它写入到NV中,然后在周期性任务中,将它打印出来看一下。发现128个字节是可以保存的,也是可以打印的,就是每次打128字节会出错。死机。 串口打印时有时出现不正常的换行。不知是什么原因?感觉也许超级终端有问题。

H 大功初成

以下我们主机用amo的主机例子程序。而从机用amo的手机采温度湿度及AD值的例子程序(没用它配套的从机程序)打算修改这两个程序,实现双向串口打印。

现在要编一个主机,一个从机,它们进行通讯,因为现在没有手机,即使有,也可能出错调试时间过长。

这样,主机先得到从机的广播看一下。将广播信息打印出来。将RSSI显示出来。

然后建立连接,通过某服务的某一个特征值,向下位机写一个hello,下位机回一个world算是通过一个基本验证了。

这样,我们还是先回到主机程序,看一下这个收到的信息是怎样的。

19

主程序中,有设备资信事件,设备发现事件,设备连接事件。看这个对应的是不是广播信息,扫描信息和连接信息?

根据按键来看,主机并没有收广播信息这一说法。而是直接扫描主机。而且一次最多扫描到8个主机。如果设备较多,就没有办法了。只能多次扫描。能不能只扫描感兴趣的主机?

我们先把这个主机程序再看一下,在这个基础上修改。 一切起源于按下了UP键之后,按下它就调用了:

GAPCentralRole_StartDiscovery( DEFAULT_DISCOVERY_MODE,

DEFAULT_DISCOVERY_ACTIVE_SCAN,

DEFAULT_DISCOVERY_WHITE_LIST );

这个函数一旦调用,就会引起GAP回调函数有信息回来。 就有设备资信信息过来。我们调一下看。 有事件传过来,该事件为: typedef union {

gapEventHdr_t gap; //!< GAP_MSG_EVENT and status. gapDeviceInitDoneEvent_t initDone; //!< GAP initialization done.

gapDeviceInfoEvent_t deviceInfo; //!< Discovery device information event structure.

gapDevDiscEvent_t discCmpl; //!< Discovery complete event structure. gapEstLinkReqEvent_t linkCmpl; //!< Link complete event structure. gapLinkUpdateEvent_t linkUpdate; //!< Link update event structure. gapTerminateLinkEvent_t linkTerminate; //!< Link terminated event structure. } gapCentralRoleEvent_t;

先看一下gapDeviceInitDoneEvent_t这部分,这中间有一个设备地址,调试中显示为00 00 ??78 13 其中的两个??是因为它不是ASCII,所以IAR系统就不显示了。 到时看一下这个中心机的地址是不是这个。

再看一个很重要的设备资料,只看到一个02 其它的我们没有看到。我们想把这个打印出来看一下。它的长度为0F。看一下

发现完成事件中有一个地址,不知是不是下位机的地址:19 02 7D 1E 7C 17?

我直接将这个gapDeviceInitDoneEvent_t打出来看一下。

结果发现,在第一次进到这个GAP_DEVICE_INFO_EVENT中,打印出来的就是广播信息。 和手机上收到的是一样的。

在第2次进到这个事件中,会打印出广播信息。

我们发现这个打印老是出错,怎样让这个打印在消息中处理?即我们需要打印时,就发送一个消息给任务,在任务中在有空时才去打印这个消息中的内容,等打完后才去重新打印,即打印完了后,(这个可能要用一个函数来决定,再去打印下一个)这样就能把所有的消息都

20

百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库OSAL解读笔记(4)在线全文阅读。

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