この記事はBitkey Developers Advent Calendar 2025の23日目の記事です。 デバイス開発部の @hu11911 が担当します。
要約
ZephyrでのFW更新やログ取得を支える mcumgr について、その核となる 「SMP(Simple Management Protocol)」 の役割をトランスポート層との関係性を踏まえて解説します。
単なる「DFUの手順」としてではなく、OS・ファイルシステム・統計情報などを共通の作法で扱うための「管理の共通配管」としての構造を整理していきます。
zephyrにおけるDFUを実現しようと考えているエンジニアの方々むけの内容です。
DFU(Device Firmware Upgrade)とは
DFUは一言でいえば「製品出荷後のデバイスにおいて、外部からファームウェアを書き換える仕組み」のことですね。
特にIoTの現場では、筐体を開けずに無線経由で更新を行う「OTA-DFU(Over-the-Air DFU)」が主流なわけですが、更新経路には主に「有線」と「無線」があり、それぞれ以下のような特徴があります。
有線(UART/USBなど) 物理接続のため、迅速かつ確実な転送が可能です。一方で、筐体に専用コネクタを露出させる必要があったり、分解してピンを立てるなど、作業者に専門性を要求するケースが少なくありません。
無線(BLE/Wi-Fiなど) ケーブル不要で圧倒的に利便性が高い反面、通信の切断やパケットの欠落といった「不安定さ」が常に課題となります。
また、実務のメンテナンスにおいては、単なるファームウェア更新(DFU)だけでなく、「内部ログの回収」「設定値の変更」「ファイル転送」といった操作も、無線越しにまとめて行いたいというニーズがほとんどです。
これら「無線環境での不安定なやり取り」を安全に制御し、多様なメンテナンス機能を一括で引き受けてくれる共通の窓口。それが mcumgr です。
mcumgrとは:外部操作の“共通窓口”
前述の通り、無線でのDFUには「便利だが不安定」という性質があります。「不安定な無線環境下で、いかに安全に多機能を管理するか」——この課題に対し、Zephyr RTOSが標準の解決策として用意しているフレームワークが mcumgr(Management Subsystem) です。
Zephyrの公式ドキュメントでは、mcumgrの役割を「デバイスをリモート管理(Remote Management)するための仕組み」と定義しています。単なるDFUの窓口に留まらず、デバイスのあらゆる側面を外部から操作するための「総合受付」として位置づけられています。
具体的には、以下のようなリソースを外部から操作可能です。
-
イメージ管理(DFU): 新しいファームウェアの転送、検証、および切り替え
-
ファイルシステム(FS): ログファイルの抜き出しや、設定ファイルの書き込み
-
OS状態の確認: デバイスの再起動(リセット)や実行中のタスク確認
-
統計情報の取得: エラー数やパケットカウントなどの統計データ確認
-
シェル(Shell): 遠隔からのコマンド実行
なぜZephyr以外でも広く使われるのか?
実はこのmcumgr、もともとは Apache Mynewt という別のRTOSプロジェクトで開発された管理ライブラリであり、それがZephyrにも移植されました。現在では、「Zephyrでリモート管理やOTAを実現するための標準解」として不動の地位を築いています。
便利ですね。
SMPとは:mcumgrが話す“共通の言語”
mcumgrという「窓口」があることは分かりました。では、外部のスマホやPCからその窓口へ、具体的にどういう形式でデータを送ればよいのでしょうか。
その答えが、SMP(Simple Management Protocol)です。
一言でいえば、SMPは「mcumgrの要求や応答をパッキングするための共通言語(ワイヤ形式)」です。
SMPの最大の役割は、「通信手段(トランスポート)」と「操作内容(コマンド)」を切り離すことにあります。これを階層図で見ると、SMPがちょうど「真ん中の層」を支えていることがわかります。
[ Management Groups ] <-- 「FW書き込み」「再起動」などの命令
|
[ SMP ] <-- 共通の「封筒」(ヘッダ + CBORデータ)
|
[ Transports ] <-- BLE / UART / UDP などの運び手
SMPという共通の封筒を使うおかげで、中身がDFUであってもログ取得であっても、また運び手がBLEであってもUARTであっても、デバイス側は同じロジックで要求を処理できるのです。
Bluetoothの「SMP」とは別物
ここで組み込みエンジニアが必ず通る混乱ポイントがあります。Bluetoothの規格にも「SMP(Security Manager Protocol)」という同名のプロトコルが存在しますが、両者は全くの別物です。
BluetoothのSMP: ペアリングや暗号化のためのセキュリティ用プロトコル。
mcumgrのSMP: デバイス管理のためのアプリ層プロトコル。
「BLEでSMPを使って更新します」と言ったときは、大抵は後者の話をしていることに注意してください。ややこしい。
SMPの中身:ヘッダとデータ
SMPのパケットは非常にシンプルで、「8バイトのヘッダ」+「データ(CBOR形式)」で構成されています。
ヘッダ: 「どの管理グループか」「どのコマンドか」「データの長さ」といった宛先情報が入ります。
データ(CBOR): JSONをバイナリ化したような形式です。テキストベースのJSONに比べてサイズが圧倒的に小さく、かつ構造的なデータをやり取りできるため、リソースの限られた組み込み機器には最適です。パケットサイズを極限まで削れるため、BLEのような低帯域な通信環境でも効率的にデータを運べるのが強みです。
この構成があるおかげで、受信側はパケットの頭を見ただけで「これはファイル操作の依頼だな」と判断し、適切な窓口へ振り分けることができるわけです。
導入前に知っておくべき「コスト」
ここまでSMPとmcumgrの構成を見てきましたがデメリットももちろんあります。
最後に、実務で採用する前に知っておくべきポイントを整理しておきます。
リソース(メモリ)をそこそこ食う
リソースが極限まで削られた安価なMCUだと、mcumgrを導入するだけで、メモリ(Flash/RAM)がカツカツになる可能性があります。
「2面待ち」のFlash設計が必要(DFUの場合
mcumgrで安全にFW更新を行うには、通常 MCUboot と組み合わせて「実行エリア」と「ダウンロードエリア」の2スロットをFlash上に用意する必要があります。つまり、「実質的にアプリの最大サイズがFlash容量の半分になる」という制約が生まれます。
(部品変更によりFlash自体の容量を増やすという回避策もありです。)
MCUbootの状態遷移がちょっとややこしい
「転送して終わり」ではなく、転送後に「テスト実行」をして、OKなら「確定(Confirm)」させる……といったMCUboot側の作法を理解していないと、「更新したのに再起動したら元に戻っちゃった!」という罠にハマりがちです。
まとめ:結局SMPってなんなの?
mcumgr: デバイスを外からいじるための「総合受付(フレームワーク)」
SMP: その窓口でやり取りするための「共通の封筒(プロトコル)」
DFU: その封筒を使って行われる「機能の一つ」
「SMPという共通の配管を通し、OS全体をリモート管理する」というZephyr流の設計思想に乗っかることで、開発者は「通信の不安定さ」や「データの整合性」といった泥臭い悩みから解放されます。
構成が理解できたら、あとはKconfigを叩いてこの便利な配管を開通させるだけ。
ぜひ皆さんも、mcumgrで快適なデバイス管理ライフ(?)を送ってみてください!
次回予告
いよいよ終わりが見えてまいりました、明日の24日目の株式会社ビットキー Advent Calendar 2025は、@kyoyababaと@bitkey_r_ikutaが担当します。