ZephyrプロジェクトでのMTUサイズの変更方法
MTU(Maximum Transmission Unit)は、Bluetooth通信での最大データ転送サイズを決定します。特にBluetooth Low Energy(BLE)では、MTUの値がデータ送信効率や接続の安定性に大きく影響します。
MTUサイズが小さい場合の問題
- データ分割の増加:小さなパケットに分割されるため、送信回数が増えます。
- 転送効率の低下:分割と再構成がリソースを消費します。
- 接続安定性の悪化:小さなMTUはデータ損失を引き起こす可能性があります。
ホストとスレーブの両方が同じMTUサイズをサポートする必要があります。
ZephyrプロジェクトでのMTU設定
Zephyrプロジェクトでは、以下のKconfigパラメータでMTUサイズを制御します。
MY_BT_L2CAP_TX_MTU=247
MY_BT_BUF_RX_SIZE=251
MY_BT_BUF_TX_SIZE=251
これらの設定は、プロトコルスタックの初期化時に適用されます。
MTU自動更新の設定
接続後にMTUサイズを自動的に更新するには、次のKconfigパラメータを有効にします。
MY_BT_GATT_AUTO_UPDATE_MTU=y
これにより、接続後自動的にMTUサイズを申請します。ただし、すべてのアプリケーションでこの設定が必要とは限りません。
手動でのMTU更新
MTUサイズを手動で更新するには、次の設定とコードを追加します。
MY_BT_GATT_CLIENT=y
接続後のMTU更新を実装するためのサンプルコードです。
/* MTU交換 */
static struct bt_gatt_exchange_params mtu_adjust_params[MY_MAX_CONN];
static void adjust_mtu_callback(struct bt_conn *conn, uint8_t err,
struct bt_gatt_exchange_params *params)
{
LOG_INF("MTU交換状態: %u %s (%u)", bt_conn_index(conn),
err == 0U ? "成功" : "失敗", bt_gatt_get_mtu(conn));
}
static int adjust_mtu(struct bt_conn *conn)
{
uint8_t conn_index;
int err;
conn_index = bt_conn_index(conn);
LOG_INF("現在のMTU: %u", bt_gatt_get_mtu(conn));
mtu_adjust_params[conn_index].func = adjust_mtu_callback;
err = bt_gatt_exchange_mtu(conn, &mtu_adjust_params[conn_index]);
if (err) LOG_INF("MTU交換失敗: %d", err);
else LOG_INF("MTU交換進行中...");
return err;
}
接続完了時にadjust_mtu関数を呼び出します。
テスト手順
テストにはnRFのUARTサービスを使用します。
1. ログの追加
void mtu_update_log(struct bt_conn *conn, uint16_t tx, uint16_t rx)
{
LOG_INF("MTU更新: TX %dバイト, RX %dバイト", tx, rx);
}
static struct bt_gatt_cb gatt_callbacks = {
.att_mtu_updated = mtu_update_log,
};
メイン関数内でこのコールバックを登録します。
2. デフォルトMTUの確認
デフォルトのMTUサイズは23バイトです。このサイズを超えるデータ送信はエラーを返します。
3. MTUサイズの更新
接続後、ホスト側からMTUサイズを更新するか、スレーブ側からホストに申請します。