Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
蓝牙BLE
RTT平台 zephyr_polling软件包 SPI Bluenrg2 丢包问题排查
发布于 2023-10-21 23:16:53 浏览:368
订阅该版
[tocm] # RTT zephyr_polling SPI Bluenrg2 丢包问题排查 >“开源之夏”“蓝牙HOST协议栈zephyr_polling完善” 项目个人记录 >菜鸡参与项目的个人记录 >项目软件包地址:[RTT_PACKAGE_zephyr_polling](https://github.com/bobwenstudy/RTT_PACKAGE_zephyr_polling) 在对协议栈在 Bluenrg2 芯片上采用 SPI 作为 HCI 的数据传输进行[测试](https://club.rt-thread.org/ask/article/8a8ee10a1827037f.html)的时候,发现存在丢包问题。当进行大吞吐连续传输时,可以发现协议栈收到的字节数少于测试APP发送的字节数。 首先需要找到丢包的位置,有多个可能:①在HCI层传输上报给协议栈上层的过程丢包;②在HCI层与芯片进行SPI通信时丢包;③在芯片接收和上报的过程丢包(按说可能性不大)。 使用在每一层计数接收到的数据的字节数,进行比较的方式确定产生丢包的位置。 ## 1 在HCI层传输上报给协议栈上层的过程丢包 在 HCI 层的 SPI 初始化`hci_driver_init()`处也设置一个打印当前接收的字节数的定时任务: ```c HCI_SPI_ACL_recv_count = 0; k_timer_init(&HCI_SPI_count_work, HCI_SPI_count_timeout, NULL); k_timer_start(&HCI_SPI_count_work, K_SECONDS(30), K_SECONDS(30)); void HCI_SPI_count_timeout(struct k_timer *timer) { printf("HCI SPI ACL recv count timeout: %d\n", HCI_SPI_ACL_recv_count); } ``` 在HCI层的接收函数`hci_driver_init_loop()`处,对ACL数据包进行判断和计数。 ```C switch(data[0]) { case HCI_EVENT_PKT: buf = bt_buf_get_controller_tx_evt(); break; case HCI_ACLDATA_PKT: buf = bt_buf_get_controller_tx_acl(); HCI_SPI_ACL_recv_count += ret; // printk("ACL: "); // for (int i = 0; i < ret; ++i) // { // printk("%02x:",data[i]); // } // printk("\n"); break; default: return; } ``` ### 测试 手机连接BLE模块,发送间隔设定为1ms,数据包大小20字节,测试得到打印结果。比较发现,协议栈上层的计数比HCI层接收处的数据计数更少,在HCI层传输上报给协议栈上层的过程有丢包。 检查HCI层接收数据和上报的代码,发现当数据传输量很大,MCU来不及处理时,协议栈上层的接收队列会堆积最后爆满,HCI 层申请 buffer 的时候可能失败,此时本次从芯片处接收到的数据就会被丢弃。 解决方案是在开始一次 SPI 接收之前,判断当前的缓冲区是否还有空间,有空间才接收。一般来说(事实上最后发现这个芯片好像并不是这样的),芯片收到的数据如果一直没有被HCI层接收,芯片端的缓冲区满了之后,芯片会暂停数据传输服务。这样可以使发送端的传输暂停,等待MCU完成处理后再继续传输,避免丢包。 ```C if (bt_buf_reserve_size(BT_BUF_ACL_IN) == 0) { printk("HCI ACL BUFFER EMPTY \r\n"); return; } int ret = HCI_TL_SPI_Receive(data, len); //ret: bytes num Recv ``` 再次测试发现,HCI层接收到的字节数和协议栈上层接收的字节数一致,但手机端发送的字节数和协议栈上层接收的字节数还是不一致,丢包还是存在。 ## 2 在芯片接收和上报的过程丢包 在 SPI 的接收函数`HCI_TL_SPI_Receive()`处也加入一个计数`HCI_SPI_ACL_recv_count`,计数从芯片处接收到的全部数据,包括包头等;在HCI层将数据包塞入缓冲区之后,加入一个计数`HCI_ACL_buf_recv_count`,计数buffer缓冲区内的数据字节数(不包括包头)。 - 四个计数分别是: `HCI_SPI_recv_count_timeout`: 从芯片处通过SPI接收到的全部数据包(包括包头) `HCI SPI ACL recv count timeout`: HCI层接收到的ACL数据包的数据(仅数据,不包括包头等) `HCI_ACL_buf_recv_count_timeout`: HCI层写入缓冲区后,缓冲区内的`data`字段里的数据(仅数据,不包括包头等) `app_count`: 协议栈上层接收到的数据(仅数据,不包括包头等) - 因为蓝牙启动的过程中也有一系列数据交互,为了确保计数的准确性,加入一个开始计数的`HCISPIFlag`,`HCISPIFlag`为`true`时才开始计数。当HCI层接收到手机端发送的`99:99:99:99`数据包(该数据包不会上报给协议栈上层)时,`HCISPIFlag`转为`true`。 - ACL数据包的包头为12字节,例如测试数据包的内容: 02:01:28:1b:00:17:00:04:00:52:0b:00:00:01:02:03:04:05:06:07:08:09:00:01:02:03:04:05:06:07:08:09 开始计数的命令判断: ```c bool HCIcountCmdCheck(uint8_t *buf) { uint8_t cmd[4] = {0x99, 0x99, 0x99, 0x99}; for (int i = 0; i < 4; ++i) { if (buf[i + 12] != cmd[i]) { return false; } } return true; } ``` HCI层SPI接收处的计数: ```c if(byte_count > 0) { /* avoid to read more data than the size of the buffer */ if (byte_count > size) { byte_count = size; } for(len = 0; len < byte_count; len++) { rt_spi_transfer(ble_spi, &char_00, (uint8_t*)&read_char, 1); buffer[len] = read_char; } HCI_SPI_recv_count += len; // ACL pack received count if (HCISPIFlag) { if (buffer[0] == HCI_ACLDATA_PKT) { HCI_SPI_ACL_recv_count += (len - 12); } } } ``` ### 测试 手机连接BLE模块,发送间隔设定为1ms,数据包大小20字节,测试得到打印结果: ```shell [00:26:45.218]收←◆Connected [00:27:05.152]收←◆HCI_SPI_recv_count_timeout: 660 HCI SPI ACL recv count timeout: 0 HCI_ACL_buf_recv_count_timeout: 0 [00:27:05.302]收←◆app count timeout: 0 [00:27:08.899]收←◆HCI count start app count start [00:27:35.134]收←◆HCI_SPI_recv_count_timeout: 302404 HCI SPI ACL recv count timeout: 188580 HCI_ACL_buf_recv_count_timeout: 188580 [00:27:35.284]收←◆app count timeout: 189840 [00:28:05.116]收←◆HCI_SPI_recv_count_timeout: 720932 HCI SPI ACL recv count timeout: 450160 HCI_ACL_buf_recv_count_timeout: 450160 [00:28:05.267]收←◆app count timeout: 451560 [00:28:35.096]收←◆HCI_SPI_recv_count_timeout: 1143556 HCI SPI ACL recv count timeout: 714300 HCI_ACL_buf_recv_count_timeout: 714300 [00:28:35.246]收←◆app count timeout: 715480 [00:29:05.081]收←◆HCI_SPI_recv_count_timeout: 1579780 HCI SPI ACL recv count timeout: 986940 HCI_ACL_buf_recv_count_timeout: 986940 [00:29:05.231]收←◆app count timeout: 988100 [00:29:35.066]收←◆HCI_SPI_recv_count_timeout: 1726692 HCI SPI ACL recv count timeout: 1078760 HCI_ACL_buf_recv_count_timeout: 1078760 [00:29:35.215]收←◆app count timeout: 1078760 ``` 手机APP端:
手机端发送 55276个包,共1105504字节,其中20字节的测试数据包 55275个,共1105500字节。 协议栈上层收到1078760字节数据,即53938个数据包; HCI层接收到的 ACL 数据包的数据字节数和 HCI 层写入缓冲区的`data`字段里的数据字节数,与协议栈上层的一致(最终一致,中间定时器打印的count数不一致是因为缓冲区的数据还未被取出)。从芯片处通过SPI接收到的全部数据包为1726692字节,其中660字节为启动阶段传输。ACL 数据包的包头为12字节,发送的命令 ACL 包为16字节,测试ACL数据包为32字节。则实际接收到的测试ACL数据包为`(1726692 - 660 - 16) / 32 = 53938`个,与协议栈上层的一致。 对比发现,在芯片接收手机数据和上报的过程中发生了丢包。一般来说,芯片收到的数据如果一直没有被HCI层接收,芯片端的缓冲区满了之后,芯片会阻止发送端(手机)继续发送数据。测试结果显示丢包发生在芯片处,可能需要和**Bluenrg2**的芯片厂商沟通咨询。
2
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
paradox
这家伙很懒,什么也没写!
文章
7
回答
1
被采纳
0
关注TA
发私信
相关文章
1
rtthread小程序“WIFI配网助手”进行蓝牙连接失败
2
透传的BLE蓝牙模块解析
3
柿饼派能实现蓝牙配网吗
4
ab32的notify的内容如何修改?
5
RT-Thread对低功耗蓝牙的支持
6
请问蓝牙mesh开发中如何实现ble部分
7
未知的寄存器名“r3”
8
BSP/nrf52832已经具备BLE协议栈串口透传DEMO
9
nrf52832 softdevice添加出错
10
蓝牙sdk,与art-pi的板子来回数据;类似项目使用protobuf来传输数据,求助其他方式
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
SFUD
msh
rt_mq_消息队列_msg_queue
keil_MDK
ulog
MicroPython
C++_cpp
本月问答贡献
出出啊
1517
个答案
342
次被采纳
小小李sunny
1443
个答案
289
次被采纳
张世争
805
个答案
174
次被采纳
crystal266
547
个答案
161
次被采纳
whj467467222
1222
个答案
148
次被采纳
本月文章贡献
出出啊
1
篇文章
4
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
1
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
1
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部