0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

RTT平台zephyr_polling软件包SPI Bluenrg2芯片宕机问题与修复

冬至子 来源:paradox 作者:paradox 2023-09-25 17:08 次阅读

项目的代码测试完成之后,准备收尾时,出现了问题。清除掉开发过程中用来调试的print打印之后,zephyr_polling 的 HCI 突然不能正常工作了,之前测试可用的 zephyr_polling 中的各个例程都不再能运行。

这个时候是去掉了 print 打印的,不能从日志找问题。经过一个一个尝试之后定位到了 SPI 接收操作完成之后的一个 print。将其去掉之后,芯片运行会宕机,但若是替换为一个 2 ticks (即2ms)的时延,例程都能正常运行。

但是显然不能这样处理这个问题,这样一是治标不治本 (只是在这个环境下避免了时序问题的发生,当条件改变,问题还可能出现),二是影响性能。

于是使用这个(不太好用的)逻辑分析仪开始寻找问题。

1.是否接收header发送的太频繁

先考虑问题是否出在轮询接收,发送 header 过于频繁,导致芯片down。

根据逻辑时序图,很多地方都是发起接收之后直接读取芯片的待发数据大小。而此时芯片并不一定准备好了做接收,读到的数据大小很大,导致重复多次地读取无用 byte

1.jpg

官方例程里没有这个问题是因为接收时中断调用的,芯片那边主动要求接收数据,一定准备好发送了。轮询的话则应该等待芯片做好准备,拉高irq线再发送recv_header

处理:

在接收操作发送 header 前加入 !IsDataAvailable() 校验,确认芯片准备好了再发 header 确定要接收的数据量。

加入判断机制后大大减少了启动用时,提高了效率。

但是去掉print芯片还是down了。

2.是否是拉高cs_pin后irq_pin响应太慢

考虑是否是拉高cs后irq_pin响应太慢

观察时序图发现,MCU 拉高 cs 希望发送数据之后,过了较长一段等待时间后 irq 才拉高进行 header 传输。

1.jpg

测试这种情况:cs 拉高再拉低,等待较长一段时间才 irq 拉高,此时传输数据,芯片并没有 down:

1.jpg

3.是否不能在发送header之后同时收发

在接收处加入校验后的代码,去掉 print 芯片还是 down 了。观察其最后的时序,发现其发送了发送 header 之后,同时进行了收发,然后 down 了。

没有delay 发送接收碰撞 后续芯片 down 了, spi 通信失败:

1.jpg

并且,反复测试之后,芯片都是在这一次传输之后宕机。这里发送的命令010cfc032c0101是关闭芯片自带 host。同时传输的是 04ff03:01:000106 厂商事件包,应该是一个 6 字节的心跳包。

最后的那一个 06 是因为 host 要传输的命令是 7 个字节,最后有个随机的电平。协议栈不会对芯片的特殊厂商事件包进行处理,即使被塞入接收队列,最后协议栈处理的时候也会将其丢弃。

考虑是否不能同时收发。对比观察正常的收发的时序。

带 2 ticks delay 的接收

1.jpg

对比发现,正常的工作的传输并不会出现收发同时的情况。

抛开这个宕机问题不谈,在发送的事务流程中,对于传输数据过程中芯片发过来的数据是直接丢弃的,而这将导致丢包。虽然这里丢失的是厂商事件包,本来就不会对其处理,但是处于普适性应该将其纠正。

解决同时收发的问题

观察时序图发现,发送 header 之后不进行数据传输时被芯片允许的。尝试在实际发送之前检查 send_header 响应中接收缓冲区数据量,如果不为 0,结束当此发送流程,先做一次完整接收,并将接收到的数据塞到接收队列里,再重新发送 send_header (使用while循环,直到待接收数据为0),继续当前数据的发送。

直接在 send_header 传输完成之后加入判断,进行一次接收:

/* Read header */
rt_spi_transfer(ble_spi, &header_master, &header_slave, HEADER_SIZE);
rx_bytes = (((uint16_t)header_slave[2])< < 8) | ((uint16_t)header_slave[1]);
uint16_t byte_count = (header_slave[4] < < 8)| header_slave[3];
if (byte_count > 0) 
{
    hci_driver_init_loop();
    result = -2;
}
else
{
  if(rx_bytes >= size)
  {
    /* Buffer is big enough */
    rt_spi_transfer(ble_spi, buffer, &read_char_buf, size);
  }
  else
  {
    /* Buffer is too small */
    result = -2;
  }
  /* Release CS line */
  rt_pin_write(hci_config.cs_pin_num, PIN_HIGH);
}

测试发现并不行,这时想起我没拉高 CS 结束这一次发送传输事务就直接启动了一次接收,肯定会出错。加入这一句:rt_pin_write(HCI_TL_SPI_CS_PIN, PIN_HIGH);。

但加入后仍然不能正常使用。发送超时了,也就是在发起接收的时候, cs 拉低之后,irq 一直没有拉高

| /

RT - Thread Operating System
/ | 5.0.1 build Sep 9 2023 21:50:28
2006 - 2022 Copyright by RT-Thread team
do components initialization.
initialize rti_board_end:0 done
initialize stm32l4_hw_lptim_init:0 done
initialize finsh_system_init:0 done
msh >zephyr
zephyr_polling_init
bt_init_hci_driver
SPI_init_process device_name: spi10, spi_name: spi1, rate: 1000000, databits: 8, LSB_MSB: 1, Master_Slave: 0, CPOL: 0, CPHA: 1
SPI_init_process cs_pin_num: 1, irq_pin_num: 0
hci_driver_open, SPI_config_finish
I: (bt_hci_core)hci_init():3230: work start.
msh >SPI Send timeout 101
E: (bt_hci_core)hci_send_cmd():2928: Unable to send to driver (err -1)

查看时序图:

1.jpg

发现后续irq_pin直到超时了都没动一下,怀疑是前一次的发送流程没有被芯片认定结束。

经过一系列尝试和测试之后,发现要想结束当次发送流程,需要将 cs 拉高一定的时间,才能让 chipset 觉得这次发送完了:

if (byte_count > 0) {
    /* Release CS line */
    rt_pin_write(HCI_TL_SPI_CS_PIN, PIN_HIGH);
    /* to end the send, we need a delay */
    rt_thread_delay(1);
    hci_driver_init_loop();
    result = -2;
}

虽然这里引入了时延,但是收发撞到一起的情况属于特殊情况,对于整体的性能影响不大。

修改后芯片down掉的问题得到解决:

| /

RT - Thread Operating System
/ | 5.0.1 build Sep 9 2023 21:50:28
2006 - 2022 Copyright by RT-Thread team
do components initialization.
initialize rti_board_end:0 done
initialize stm32l4_hw_lptim_init:0 done
initialize finsh_system_init:0 done
msh >zephyr
zephyr_polling_init
bt_init_hci_driver
SPI_init_process device_name: spi10, spi_name: spi1, rate: 1000000, databits: 8, LSB_MSB: 1, Master_Slave: 0, CPOL: 0, CPHA: 1
SPI_init_process cs_pin_num: 1, irq_pin_num: 0
hci_driver_open, SPI_config_finish
I: (bt_hci_core)hci_init():3230: work start.
msh >prepare_event_process, step: 1
prepare_event_process, step: 2
prepare_event_process, step: 3
prepare_event_process, step: 4
prepare_event_process, step: 5
I: (bt_hci_core)hci_init_end():3205: work end.
E: (bt_smp)smp_self_test():5695: smp_self_test start
I: (bt_hci_core)bt_dev_show_info():3008: Identity: 02:80:e1:00:00:f5 (public)
I: (bt_hci_core)bt_dev_show_info():3042: HCI: version 5.2 (0x0b) revision 0x1222, manufacturer 0x0030
I: (bt_hci_core)bt_dev_show_info():3044: LMP: version 5.2 (0x0b) subver 0x0015
Bluetooth initialized
Advertising successfully started
Connected
HRS notifications enabled
HRS notifications disabled
Disconnected (reason 0x13)

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 收发器
    +关注

    关注

    10

    文章

    3438

    浏览量

    106077
  • 缓冲器
    +关注

    关注

    6

    文章

    1923

    浏览量

    45539
  • 逻辑分析仪
    +关注

    关注

    3

    文章

    214

    浏览量

    23203
  • MCU控制
    +关注

    关注

    0

    文章

    48

    浏览量

    6760
  • RTThread
    +关注

    关注

    8

    文章

    132

    浏览量

    40910
收藏 人收藏

    评论

    相关推荐

    RTT_Zephyr_Polling BlueNRG2 SPI使用说明

    在RT-Thread平台下,利用 BlueNRG2 蓝牙芯片运行 RTT_Zephyr_Polling 协议栈。使用 SPI 作为 HCI
    的头像 发表于 09-21 14:54 1329次阅读
    <b class='flag-5'>RTT_Zephyr_Polling</b> <b class='flag-5'>BlueNRG2</b> <b class='flag-5'>SPI</b>使用说明

    RTT zephyr_polling软件包 Bluenrg2蓝牙芯片启动流程

    在用标准的 HCI 指令控制设备进行蓝牙操作之前,需要提前通过 VS Command 对设备进行配置,只有正确配置好的设备才能正常使用。
    的头像 发表于 09-27 11:19 1422次阅读
    <b class='flag-5'>RTT</b> <b class='flag-5'>zephyr_polling</b><b class='flag-5'>软件包</b> <b class='flag-5'>Bluenrg2</b>蓝牙<b class='flag-5'>芯片</b>启动流程

    如何用Ubuntu qemu跑zephyr_polling的蓝牙?

    进入 RT-Thread online packages → IoT - internet of things 目录即可看到 zephyr_polling软件包,勾选软件包
    的头像 发表于 09-28 11:24 1968次阅读
    如何用Ubuntu qemu跑<b class='flag-5'>zephyr_polling</b>的蓝牙?

    如何使用RTT Studio配置at软件包来连接wifi模块?

    如何使用RTT Studio配置at软件包来连接wifi模块?
    发表于 02-16 07:47

    分享一种基于littlevgl2rtt软件包的RGB屏幕接口优化方案

    StudioOS版本:4.0.3开发板:Art-Pi + 正点原子4.3寸RGB屏软件包:Littlevgl2rtt(latest)温馨提示:下面的优化方案是基于该软件包的优化,如果是自己一直lvgl的不再此
    发表于 06-07 14:57

    SPI驱动屏幕移植LVGL软件包具体流程

    _da, send_data, RT_NULL,2);}二、移植lvgl(一)、添加lvgl软件包首先打开rtthread setting,点击右侧的缩进,打开后,选择软件包,再将多媒体
    发表于 07-08 15:09

    rtt有支持多个文件压缩的软件包

    rtt有支持多个文件压缩的软件包么,比如tar指令,或者有那个大佬实现了多文件压缩的源码可以分享一下么?
    发表于 11-15 10:53

    怎样使用SDK中的Beacon示例对BLUENRG2进行重新编程呢?

    我希望使用 BLUENRG-M2 模块构建一个带有 BLUENRG2 的项目。我购买了一块 X-NUCLEO-BNRG2A1 板开始使用,并将该板上的 SWDIO、SWDCLK、NRESET、VDD
    发表于 01-03 10:00

    WK2124 SPI转串口芯片驱动软件包

      WK2124 软件包  1 介绍  WK2124 软件包是为WK2124 SPI转四串口扩展芯片而开发的RT-Thread驱动。通过R
    发表于 03-06 11:01

    I2C模块arduinoio Simulink软件包

    I2C模块arduinoio Simulink软件包
    发表于 01-22 14:06 0次下载

    RT-Thread软件包定义和使用

    RT-Thread软件包是运行于RT-Thread物联网操作系统平台上,面向不同应用领域的通用软件组件 。RT-Thread 同时提供了开放的软件包
    的头像 发表于 05-21 11:29 1w次阅读
    RT-Thread<b class='flag-5'>软件包</b>定义和使用

    STM32F103C8 使用RT-Thread软件包系统读取MPU6050

    常见的元件自然有相应的软件包啦,在工程根目录打开ENV工具1.在这个目录下可以发现很多软件包,我们将MPU6xxx打开2.在打开RTT的iic支持
    发表于 12-06 14:36 12次下载
    STM32F103C8 使用RT-Thread<b class='flag-5'>软件包</b>系统读取MPU6050

    RTT zephyr_polling SPI Bluenrg2数据传输测试

    RTT 那边的 Kconfig 配置完成,项目的基本开发内容就完成了。然后再对协议栈在 Bluenrg2 芯片上采用 SPI 作为 HCI 的数据传输进行测试。
    的头像 发表于 09-25 16:25 921次阅读
    <b class='flag-5'>RTT</b> <b class='flag-5'>zephyr_polling</b> <b class='flag-5'>SPI</b> <b class='flag-5'>Bluenrg2</b>数据传输测试

    RT-Thread平台 zephyr_polling软件包 Bluenrg2 蓝牙芯片启动流程

    RTT zephyr_polling软件包 Bluenrg2 蓝牙芯片启动流程 “开源之夏”“蓝牙HOST协议栈
    的头像 发表于 09-27 18:40 931次阅读
    RT-Thread<b class='flag-5'>平台</b> <b class='flag-5'>zephyr_polling</b><b class='flag-5'>软件包</b> <b class='flag-5'>Bluenrg2</b> 蓝牙<b class='flag-5'>芯片</b>启动流程

    RTT平台zephyr_polling软件包SPI Bluenrg2问题排查

    在对协议栈在 Bluenrg2 芯片上采用 SPI 作为 HCI 的数据传输进行测试的时候,发现存在丢问题。
    的头像 发表于 10-23 15:41 667次阅读
    <b class='flag-5'>RTT</b><b class='flag-5'>平台</b><b class='flag-5'>zephyr_polling</b><b class='flag-5'>软件包</b><b class='flag-5'>SPI</b> <b class='flag-5'>Bluenrg2</b>丢<b class='flag-5'>包</b>问题排查