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

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

3天内不再提示

RTT zephyr_polling SPI Bluenrg2数据传输测试

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

RTT 那边的 Kconfig 配置完成,项目的基本开发内容就完成了。然后再对协议栈在 Bluenrg2 芯片上采用 SPI 作为 HCI 的数据传输进行测试。

数据传输使用的是 zephyr_polling 的 thoughput Example。

配置

软件包配置

数据传输

数据吞吐例程内部逻辑是将接收到的数据转发回中心设备。主要提供了两个 GATT 服务:write 和 notify。前者用于接收中心设备发来的数据,后者用于向连接的中心设备发送数据。

输入zephyr运行Example。

手机端使用 BLE调试宝(类似的BLE APP应该都行)连接设备,开启notify服务:

1.jpg

数据传输

数据吞吐例程内部逻辑是将接收到的数据转发回中心设备。主要提供了两个 GATT 服务:write 和 notify。前者用于接收中心设备发来的数据,后者用于向连接的中心设备发送数据。

输入zephyr运行Example。

手机端使用 BLE调试宝(类似的BLE APP应该都行)连接设备,开启notify服务:

1.jpg

连续发送数据:

1.jpg

收发数据没有丢包。

串口打印如下:

initialize rti_board_start:0 done
initialize drv_pm_hw_init:0 done
initialize rt_hw_spi_init:0 done
| /

RT - Thread Operating System
/ | 5.0.1 build Sep 20 2023 22:39:47
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
throughput_svc_init()
Advertising successfully started
I: (bt_hci_core)bt_sleep_prepare_work():4040: start
I: (bt_hci_core)bt_sleep_prepare_work():4046: end
I: (bt_hci_core)bt_sleep_wakeup_work_start():4058: start
I: (bt_hci_core)bt_sleep_wakeup_work_start():4061: end
I: (bt_hci_core)bt_sleep_wakeup_work_end():4072: start
I: (bt_hci_core)bt_sleep_wakeup_work_end():4074: end
Connected

数据传输测试

数据传输测试首先是保证传输的稳定性,保证没有丢包误码。在保证可靠的前提下,再对数据传输的速率进行测试。测试包括双工的收发速率测试和单口的传输速率测试。

测试传输的单个数据包大小为 20 字节。

这里有一个测试方案的问题,一开始使用的方案不对,测得的数据不能保证准确性(没有保证可靠传输),在社区导师的帮助下才得到了比较准确的测试结果。

测试单口传输速率
单口传输的话需要把 thoughput 例程中的发送关闭。此时由于没有给 APP 端反馈,为了保证可靠传输,需要在接收处对接收的数据进行计数,并启动一个软件定时器,定时打印计数。将打印得到的接收字节数与 APP 端的发送字节数对比,二者相符则可以基本保证可靠传输。再根据打印的计数,计算传输速率。

exampleperipheral_throughputthroughput_service.c
关闭发送:

static void throughput_tx_ccc_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
{
bool notif_enabled = (value == BT_GATT_CCC_NOTIFY);
// tx_enable = notif_enabled;
// 修改为
tx_enable = 0;
}
在接收处添加计数

static ssize_t data_rx(struct bt_conn *conn, const struct bt_gatt_attr *attr, const void *buf,
uint16_t len, uint16_t offset, uint8_t flags)
{
...
recv_count += len;
return len;
}
使用协议栈的软件定时器打印计数:

struct k_timer count_work;
...
void count_timeout(struct k_timer *timer)
{
printf("count_timeout(): %dn", recv_count);
recv_count = 0;
}
...
k_timer_init(&count_work, count_timeout, NULL);
k_timer_start(&count_work, K_SECONDS(25), K_SECONDS(50)); // 25s后第一次执行 之后50s为周期执行

这里存在一个如何同步计数的问题。人点击APP端发送的开始和停止时需要反应时间的,需要回避开始和结束。

首先是计数速率的时候,只能取不包含开始和结束的时间段内的计数来计算。

而可靠性保证的时候,并不需要在一次计数完成的时候刚好结束,往后再计数一个周期,将全部的计数结果加起来,能与APP端相符即可。

采取的方案是启动协议栈,并在 APP 端连接后,开始连续发送测试数据包。计数的打印为 25s 后第一次执行,之后 50s 为周期执行。四次打印后结束发送,等待最后一次打印。将 5 次打印的计数求和,与APP端的发送数对比。然后取中间三次 50s 打印的字节数计算传输速率。

经过实际测试,APP 端 2 ms 发送间隔下,在长时间的连续发送下会产生丢包,需要将发送间隔上调至 3 ms 才能保证压测之下没有丢包。

20字节 间隔 2ms 传输持续 200s

协议栈端计数接收到 1494160 字节数据,但 APP 端发出 75046 个数据包,1500920 字节数据。

存在丢包情况。此时速率为 1494160 / 200 = 7470.8 byte/s

单个数据包大小为 20 字节,APP 端 3ms 发送间隔,测试打印:

[16:49:11.997]收←◆Connected
[16:49:26.163]收←◆count_timeout(): 17180
[16:50:16.110]收←◆count_timeout(): 213960
[16:51:06.061]收←◆count_timeout(): 211220
[16:51:56.016]收←◆count_timeout(): 212000
[16:52:45.978]收←◆count_timeout(): 57080

接收到的数据包为 17180+213960+211220+212000+57080 = 711440 字节,与APP端相符。

1.jpg

当前条件下的可靠传输速率为 (213960+211220+212000) / (50 * 3) = 4247.87 byte/s

测试双工的收发速率

数据吞吐例程内部逻辑是将接收到的数据转发回中心设备。在APP端保证发出和收到的字节数相同就能基本保证可靠性,然后再计数固定时间内传输的字节数即可得到传输速率。

同时收发的条件下,需要将发送间隔设置到 25ms 才能保证传输不丢包。

[00:11:22.697]收←◆Connected
[00:11:37.647]收←◆count_timeout(): 4280
[00:12:27.610]收←◆count_timeout(): 36400
[00:13:17.572]收←◆count_timeout(): 36400
[00:14:07.530]收←◆count_timeout(): 36320
[00:14:57.484]收←◆count_timeout(): 36360
[00:15:47.440]收←◆count_timeout(): 1900

APP端收发数相符,没有丢包。打印的计数和为151600,与APP端相符。

速率为 (36400+36400+36320+36360)/200 = 726.95 byte/s

双工传输的速率并不理想,查看传输时的时序图,发现传输所占用的时间比例很少,协议栈有很大的优化空间。

1.jpg

问题

首先是从时序图可以看到 SPI 通信口的利用率不高,有优化空间。

此外 APP 端给芯片发送数据的时候是通过 write GATT 服务进行的,写入的时候会检查接收缓冲区大小,如果满了,应当等待有空闲才会发送(实际去查看APP端的日志,即使将间隔设定为 1 ms,发送的间隔也不会是 1 ms,而是会根据实际情况浮动)。这种机制下,丢包是不应该的。

这两个问题有待之后去改进。

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

    关注

    14

    文章

    2214

    浏览量

    70669
  • 定时器
    +关注

    关注

    23

    文章

    3147

    浏览量

    112037
  • SPI接口
    +关注

    关注

    0

    文章

    251

    浏览量

    33934
  • BLE技术
    +关注

    关注

    0

    文章

    24

    浏览量

    5795
  • RTThread
    +关注

    关注

    7

    文章

    129

    浏览量

    40519
收藏 人收藏

    评论

    相关推荐

    RTT_Zephyr_Polling BlueNRG2 SPI使用说明

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

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

    项目的代码测试完成之后,准备收尾时,出现了问题。清除掉开发过程中用来调试的print打印之后,zephyr_polling 的 HCI 突然不能正常工作了,之前测试可用的 zephyr_pol
    的头像 发表于 09-25 17:08 783次阅读
    <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>芯片宕机问题与修复

    如何用Ubuntu qemu跑zephyr_polling的蓝牙?

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

    DSP2812的SPI数据传输

    利用DAC8534芯片和2812的SPI接口实现多路DA转换,但是DAC8534的数据传输是24位的,[8位(地址加通道选择)+16位(数据16位精度)],但是SPI
    发表于 08-11 20:26

    关于数据传输接口

    单片机用于数据传输的外设有哪些?原谅在下孤陋寡闻,我所知道的有SPI、I2C,不知还有哪些?谁的数据传输速度最快?
    发表于 09-02 12:22

    Linux SPI总线和设备驱动架构之SPI数据传输的队列化

    Linux SPI总线和设备驱动架构之SPI数据传输的队列化 附件图文详情
    发表于 11-20 14:52

    介绍一种STM32数据传输方式SPI

    之前介绍了STM32数据传输的一种方式IIC,这次我将进行另外一种数据传输方式SPI
    发表于 02-17 06:02

    什么是U盘的数据传输

    什么是U盘的数据传输率     便携存储是依靠USB接口与系统相连,其接口的速度就限制着移动硬盘的数据传输率。目前的US
    发表于 01-30 10:21 628次阅读

    基于SPI总线的无线数据传输系统设计

    基于SPI总线的无线数据传输系统设计   摘要: 通过基于SPI总线的无线数据通信设备,利用无线数据收发芯片NRF905和51单片机STC
    发表于 03-13 11:42 3655次阅读
    基于<b class='flag-5'>SPI</b>总线的无线<b class='flag-5'>数据传输</b>系统设计

    数据传输速率是什么意思

    数据传输速率是什么意思 数据传输速率是通过信道每秒可传输的数字信息量的量度。数据传输速率也称为吞吐率。数据传输速率由很
    发表于 03-18 14:45 4941次阅读

    数据传输中的成帧

    什么是数据传输中的成帧 数据传输中的成帧 成帧技术是一种用来在一个比特流内分配或标记信道的技术,为电信提供选择基本的时隙结构和管理方式、错误
    发表于 03-18 14:46 3671次阅读

    SPI是什么 SPI数据传输

    数据传输 SPI 的英文全称为 Serial Peripheral Interface,顾名思义为串行外设接口。 SPI 是一种同步串行通信接口规范,主要应用于嵌入式系统中的短距离通信。该接口
    的头像 发表于 07-21 10:03 5040次阅读

    SPI数据传输有哪些方式

    SPI 数据传输可以有两种方式:同步方式和异步方式。 同步方式:数据传输的发起者必须等待本次传输的结束,期间不能做其它事情,用代码来解释就是,调用
    的头像 发表于 07-25 10:54 3375次阅读
    <b class='flag-5'>SPI</b><b class='flag-5'>数据传输</b>有哪些方式

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

    地址:RTT_PACKAGE_zephyr_polling 前面已经完成了 SPI 接口的实现,要让 zephyr_pollingBluenrg2 上运行起来,下一步是实现其特殊
    的头像 发表于 09-27 18:40 412次阅读
    RT-Thread平台 <b class='flag-5'>zephyr_polling</b>软件包 <b class='flag-5'>Bluenrg2</b> 蓝牙芯片启动流程

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

    在对协议栈在 Bluenrg2 芯片上采用 SPI 作为 HCI 的数据传输进行测试的时候,发现存在丢包问题。
    的头像 发表于 10-23 15:41 236次阅读
    <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>丢包问题排查