吴忠躺衫网络科技有限公司

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

RTT平臺zephyr_polling軟件包SPI Bluenrg2丟包問題排查

冬至子 ? 來源:paradox ? 作者:paradox ? 2023-10-23 15:41 ? 次閱讀

在對協議棧在 Bluenrg2 芯片上采用 SPI 作為 HCI 的數據傳輸進行測試的時候,發現存在丟包問題。當進行大吞吐連續傳輸時,可以發現協議棧收到的字節數少于測試APP發送的字節數。

首先需要找到丟包的位置,有多個可能:①在HCI層傳輸上報給協議棧上層的過程丟包;②在HCI層與芯片進行SPI通信時丟包;③在芯片接收和上報的過程丟包(按說可能性不大)。

使用在每一層計數接收到的數據的字節數,進行比較的方式確定產生丟包的位置。

1 在HCI層傳輸上報給協議棧上層的過程丟包
在 HCI 層的 SPI 初始化hci_driver_init()處也設置一個打印當前接收的字節數的定時任務:

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: %dn", HCI_SPI_ACL_recv_count);
}
在HCI層的接收函數hci_driver_init_loop()處,對ACL數據包進行判斷和計數。

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完成處理后再繼續傳輸,避免丟包。

if (bt_buf_reserve_size(BT_BUF_ACL_IN) == 0)
{
printk("HCI ACL BUFFER EMPTY rn");
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:281b00:17:00:04:00:520b00:00:01:02:03:04:05:06:07:08:09:00:01:02:03:04:05:06:07:08:09

開始計數的命令判斷:

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接收處的計數:

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字節,測試得到打印結果:

[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端:

1.jpg

手機端發送 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層接收,芯片端的緩沖區滿了之后,芯片會阻止發送端(手機)繼續發送數據。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 接收機
    +關注

    關注

    8

    文章

    1184

    瀏覽量

    53632
  • SPI接口
    +關注

    關注

    0

    文章

    259

    瀏覽量

    34549
  • BLE技術
    +關注

    關注

    0

    文章

    28

    瀏覽量

    5917
  • MCU芯片
    +關注

    關注

    3

    文章

    253

    瀏覽量

    11627
  • RTThread
    +關注

    關注

    8

    文章

    132

    瀏覽量

    41000
收藏 人收藏

    評論

    相關推薦

    RTT_Zephyr_Polling BlueNRG2 SPI使用說明

    在RT-Thread平臺下,利用 BlueNRG2 藍牙芯片運行 RTT_Zephyr_Polling 協議棧。使用 SPI 作為 HCI 傳輸方式。
    的頭像 發表于 09-21 14:54 ?1390次閱讀
    <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_polling 中的各個例程都不再能運行。
    的頭像 發表于 09-25 17:08 ?1147次閱讀
    <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>芯片宕機問題與修復

    RTT zephyr_polling軟件包 Bluenrg2藍牙芯片啟動流程

    在用標準的 HCI 指令控制設備進行藍牙操作之前,需要提前通過 VS Command 對設備進行配置,只有正確配置好的設備才能正常使用。
    的頭像 發表于 09-27 11:19 ?1492次閱讀
    <b class='flag-5'>RTT</b> <b class='flag-5'>zephyr_polling</b><b class='flag-5'>軟件包</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 ?2040次閱讀
    如何用Ubuntu qemu跑<b class='flag-5'>zephyr_polling</b>的藍牙?

    如何使用RTT Studio配置at軟件包來連接wifi模塊?

    如何使用RTT Studio配置at軟件包來連接wifi模塊?
    發表于 02-16 07:47

    SPI驅動屏幕移植LVGL軟件包具體流程

    _da, send_data, RT_NULL,2);}二、移植lvgl(一)、添加lvgl軟件包首先打開rtthread setting,點擊右側的縮進,打開后,選擇軟件包,再將多媒體
    發表于 07-08 15:09

    rtt有支持多個文件壓縮的軟件包

    rtt有支持多個文件壓縮的軟件包么,比如tar指令,或者有那個大佬實現了多文件壓縮的源碼可以分享一下么?
    發表于 11-15 10:53

    I2C模塊arduinoio Simulink軟件包

    I2C模塊arduinoio Simulink軟件包
    發表于 01-22 14:06 ?0次下載

    RT-Thread 軟件包介紹

    RT-Thread 軟件包介紹軟件包的目的軟件包在高級語言中非常常見,很多高級語言都有對應的軟件包平臺,比如 Python 的 PyPi,R
    發表于 05-21 19:38 ?5572次閱讀

    RT-Thread軟件包定義和使用

    RT-Thread軟件包是運行于RT-Thread物聯網操作系統平臺上,面向不同應用領域的通用軟件組件 。RT-Thread 同時提供了開放的軟件包
    的頭像 發表于 05-21 11:29 ?1.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

    什么是Linux軟件包,如何管理它們

    現代類 Unix 操作系統都提供了一個集中的軟件包管理機制,以幫助用戶搜索、安裝和管理軟件。而軟件通常以的形式存儲在倉庫中,對軟件包的使用
    的頭像 發表于 02-06 14:59 ?1502次閱讀

    RT-Thread在線軟件包改為本地軟件包的方法

    RT-Thread 的軟件包,使用時需要手動通過 ENV 工具 更新到 本地的 packages 目錄,并且 packages 目錄默認不參與 Git 工程管理,軟件包多了,偶爾需要更改軟件包本身的一些代碼,這就造成了
    的頭像 發表于 08-11 15:02 ?1294次閱讀
    RT-Thread在線<b class='flag-5'>軟件包</b>改為本地<b class='flag-5'>軟件包</b>的方法

    RTT zephyr_polling SPI Bluenrg2數據傳輸測試

    RTT 那邊的 Kconfig 配置完成,項目的基本開發內容就完成了。然后再對協議棧在 Bluenrg2 芯片上采用 SPI 作為 HCI 的數據傳輸進行測試。
    的頭像 發表于 09-25 16:25 ?966次閱讀
    <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協議棧zephyr_polling
    的頭像 發表于 09-27 18:40 ?968次閱讀
    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> 藍牙芯片啟動流程
    菲律宾百家乐官网赌场娱乐网规则 | VIP百家乐-挤牌卡安桌板| 六合彩报| 免费百家乐官网倍投软件| 澳门皇冠娱乐城| 百家乐全讯网2| 投注平台出租| 七胜百家乐娱乐城总统网上娱乐城大都会娱乐城赌场 | 网上百家乐官网玩法| 大发888娱乐场官方下载| 游戏百家乐官网的玩法技巧和规则| 澳门百家乐如何算| 澳门赌场攻略| 百家乐做庄家必赢诀窍| 百家乐官网多少点数算赢| 百家乐最好投注法是怎样的去哪儿能了解一下啊| 网上百家乐官网有人赢过吗| 大发888娱乐城充值| 汉百家乐官网春| 渝北区| 百家乐道具扫描| 宜丰县| 威尼斯人娱乐城线上博彩| 网上赌百家乐官网有假| 娱乐城棋牌| 百家乐qq游戏| 太原百家乐官网招聘| 24葬书-葬法| 库伦旗| 威尼斯人娱乐城反水| 华盛顿百家乐官网的玩法技巧和规则 | 联众百家乐官网的玩法技巧和规则 | 大发888 娱乐免费游戏| 百家乐有多少局| 永利高百家乐官网怎样开户 | 关于百家乐官网概率的书| 圣保罗百家乐的玩法技巧和规则| 太阳城百家乐官网赌场| 红树林百家乐官网的玩法技巧和规则| 现金百家乐| 太阳城娱乐网88|