讲到蓝牙芯片开发(应用级别开发),大家都会感到十分神秘,认为十分难以下手。但是,实际上并没有那么难,和其他嵌入式开发相比较,它的特点如下,
1. 需要了解蓝牙的相关协议。底层协议并不需要应用开发者来完成,但是开发者要明白产品要用到哪些相关的协议,所选的芯片是否支持这些特性;另外,结合蓝牙协议分析仪sniffer来分析产品哪里有问题(会用协议分析仪来解读协议十分重要);还有,蓝牙芯片的应用级开发,也理解相关的时序,比如初始化/连接/断开等。
2. Debug工具的应用。
2.1 在第一点中我们谈到蓝牙协议分析仪(sniffer),这个可以抓取和分析蓝牙的无线信号;
2.2 蓝牙芯片抓取到数据后,要通过UART或者USB接口传给CPU或者其他主设备,这是通过UART/USB重要的数据流,相关的协议分析仪是我们对问题分析的利器,不可不重视;
2.3 嵌入式芯片一般还有UART debug port,这个对于开发也很重要,可以打印debug message;
2.4 IDE中也会包含debug工具,这个也十分重要。
如果对于蓝牙协议和debug工具应用比较得心应手,那么在开发和debug过程中就会比较省力。
今天来举例讲一个CSR BC5 Bluetooth auto reconnect fail issue debug案例。
这个issue主要是讲,当Host PC(Windows 7)重启后,SPP无法自动重新连接。
这里有几个关键字,SPP,断开连接,重新连接。
确定主题后,我们要寻找蓝牙协议相关的定义,于是,找到了下面关键的图表。这个图表告诉我们,如果是Host PC (Windows 7)重新启动主动断开连接disconnect,CSR BC5芯片会收到"SPP_DISCONNECT_IND"消息通知;我们查看对应得代码,在message loop (我看的代码对应的函数名称是task_hander()),找到消息"SPP_CONNECT_IND",发现它是可以发起重新连接的,那么,为什么不能重新连接成功呢?
下面,就要分析连接connect那段了。从下面的图表可以看出,如果是CSR BC5发起连接,那么会收到"SPP_CONNECT_CFM"消息通知。好的,我们再去代码找消息"SPP_CONNECT_CFM"(还是在函数task_hander()中)。通过debug message,我们看到,首次连接状态为“SPP_CONNECT_PENDING”,然后“SPP_CONNECT_FAILED”,在这2中状态来回倒腾几次后,收到"SPP_CONNECT_REJECTED",此时CSR BC5停止自动重新连接,将蓝牙状态设置为"READY". 这就造成了这个auto reconnect failed问题.
对于这个问题,可以从2个方面来分析,
1. 系统为什么会发出"SPP_CONNECT_REJECTED"这个状态信息?这是合理的吗?
2. 即使我们收到"SPP_CONNECT_REJECTED",我们依旧下指令告诉蓝牙芯片需要再次连接。
分析1,是刨根究底找正解root cause,一般会花上很长时间;
分析2,是见招拆招,专业讲法是workaround,也就是说,我没有解掉root cause,但仅就问题本身而言,可以满足客户需求。负面影响是,可能会因为这个补丁造成其他issue,后续的项目维护就要不停地打补丁。
因为时间比较紧急,我们不幸也选择了“分析2”的解法。对于这个问题,可能给客户带来的影响是,耗电可能会增加 (原因是,别人已经reject你,你怎么还要connect人家,没完没了)。
最后,讲讲debug方法。在解这个issue时,需要打印debug message,常规做法是使用IDE配合硬件debug套件(SPI 转USB)可以得到debug message。可惜的是,做这个案子的前辈们,遇到问题就想拉电重启(BT chip power off),造成和IDE debugger断开连接,调试中断。好在经过不断思索,发现可以把一些信息发到UART接口 (使用uart_raw_write()函数),然后使用协议分析仪来抓取debug message。