NCS更改MTU大小
一、 什么是MTU
MTU(Maximum Transmission Unit)即最大傳輸單元,它定義了藍(lán)牙網(wǎng)絡(luò)層協(xié)議一次能傳輸?shù)淖畲髷?shù)據(jù)量。在藍(lán)牙低功耗(BLE)通信中,MTU的大小直接影響到數(shù)據(jù)傳輸?shù)男屎托阅?/p>
MTU過小的影響
當(dāng)MTU設(shè)置過小時(shí),會(huì)導(dǎo)致以下問題:
- 數(shù)據(jù)分片增加 :數(shù)據(jù)需要被分成更小的片段進(jìn)行傳輸,增加了傳輸?shù)拇螖?shù)和復(fù)雜性。
- 傳輸效率降低 :頻繁的數(shù)據(jù)分片和重組會(huì)消耗更多的帶寬和時(shí)間。
- 連接穩(wěn)定性下降 :過小的MTU可能導(dǎo)致數(shù)據(jù)包丟失或傳輸錯(cuò)誤,影響連接的穩(wěn)定性
所以為了能夠單包發(fā)送更大的數(shù)據(jù),服務(wù)器和客戶端都需要更新它們的MTU。MTU需要滿足主機(jī)和從機(jī)之間允許的最小值,必須支持更大的MTU的遷就支持更小的
MTU
在Zephyr里面CONFIG_BT_BUF_ACL_RX_SIZE和 CONFIG_BT_L2CAP_TX_MTU這兩個(gè)宏決定了ZephyrMTU的大小,下圖是MTU的關(guān)系已經(jīng)Kconfig對(duì)應(yīng)表
調(diào)用這個(gè)發(fā)送函數(shù)會(huì)報(bào)-128錯(cuò)誤
二、如何修改MTU大小
1、增加主機(jī)向從機(jī)配置的MTU大小
在prj.conf添加如下幾個(gè)宏:
CONFIG_BT_L2CAP_TX_MTU=247
CONFIG_BT_BUF_ACL_RX_SIZE=251
CONFIG_BT_BUF_ACL_TX_SIZE=251
添加如上幾個(gè)宏,從機(jī)就支持支持最大的247的MTU了,但是這個(gè)是初始化協(xié)議棧的時(shí)候設(shè)置的,而MTU交換是主機(jī)和從機(jī)建立連接之后進(jìn)行協(xié)商,所以主機(jī)可以在連接之后,主動(dòng)設(shè)置從機(jī)的MTU大小了,那么怎么設(shè)置從機(jī)主動(dòng)發(fā)起MTU請(qǐng)求和請(qǐng)求的大小呢:
有兩個(gè)辦法
1.1 第一個(gè)辦法:固定MTU大小
再上面的宏里面,再添加一個(gè)宏就可以實(shí)現(xiàn)連接后自動(dòng)更新NTU大小了
CONFIG_BT_GATT_AUTO_UPDATE_MTU=y
在這里插入圖片描述
使用Kconfig search 查詢MTU,可以看到下面的描述連接后自動(dòng)申請(qǐng)MTU大小,為什么我要多此一舉呢,因?yàn)橛行┛蛻舨恍枰暾?qǐng)這么大的MTU,需要?jiǎng)討B(tài)去修改MTU大小或者自己隨著在某個(gè)操作里面修改MTU大小,
2、第二個(gè)辦法:使用函數(shù)從機(jī)主動(dòng)向主機(jī)申請(qǐng)?jiān)黾覯TU大小
2.1 添加宏
CONFIG_BT_GATT_CLIENT
2.2 在函數(shù)里面添加如下代碼,然后再connect回調(diào)時(shí)間里面調(diào)用
/*MTU exchange*/
static struct bt_gatt_exchange_params mtu_exchange_params[CONFIG_BT_MAX_CONN];
static void mtu_exchange_cb(struct bt_conn *conn, uint8_t err,
struct bt_gatt_exchange_params *params)
{
LOG_INF("MTU exchange %u %s (%u)", bt_conn_index(conn),
err == 0U ? "successful" : "failed", bt_gatt_get_mtu(conn));
}
static int mtu_exchange(struct bt_conn *conn)
{
uint8_t conn_index;
int err;
conn_index = bt_conn_index(conn);
LOG_INF("MTU (%u): %u", conn_index, bt_gatt_get_mtu(conn));
mtu_exchange_params[conn_index].func = mtu_exchange_cb;
err = bt_gatt_exchange_mtu(conn, &mtu_exchange_params[conn_index]);
if (err) LOG_INF("MTU exchange failed (err %d)", err);
else LOG_INF("Exchange pending...");
return err;
}
在connect回調(diào)調(diào)用:
三、測(cè)試
我們使用nrf下面的串口服務(wù)例程進(jìn)行測(cè)試,具體怎么編譯程序和燒錄可以看我之前寫的博客
3.1 添加LOG
void mtu_updated(struct bt_conn *conn, uint16_t tx, uint16_t rx)
{
LOG_INF("Updated MTU: TX: %d RX: %d bytesn", tx, rx);
}
static struct bt_gatt_cb gatt_callbacks = {
.att_mtu_updated = mtu_updated,
};
隨后在main函數(shù)注冊(cè)回調(diào):

3.2 可以看到,默認(rèn)例程的MTU大小只有23字節(jié)大小,每包數(shù)據(jù)發(fā)送超過了這個(gè)大小就會(huì)報(bào)錯(cuò),

3.3、在手機(jī)上面申請(qǐng)
兩個(gè)都是一樣的,可以看到,連接之后,通過主機(jī)更新或者從機(jī)和主機(jī)申請(qǐng)交換MTU大小也會(huì)改變,

3.4 添加自動(dòng)連接更新MTU的宏&自己在連接添加MTU更換的宏

審核編輯 黃宇
-
NCS
+關(guān)注
關(guān)注
1文章
21瀏覽量
9329
發(fā)布評(píng)論請(qǐng)先 登錄
【NCS隨筆】NCS使用CJSON庫
NCS放大器DAD3350使用場(chǎng)景與效果
NCS放大器DAD3350詳細(xì)信息
Android14在BLE中,當(dāng)MTU超過 517時(shí),如何處理數(shù)據(jù)傳輸?
NCS怎么添加.c.h文件到工程
更改最大數(shù)據(jù)包大小時(shí)無法識(shí)別USB設(shè)備如何解決?
nRF Connect SDK(NCS)/Zephyr固件升級(jí)詳解 – 重點(diǎn)講述MCUboot和藍(lán)牙空中升級(jí)

NCS更改MTU大小
評(píng)論