Matter 17 · デバイス実装の実際 — プラットフォーム・Factory Data・省電力・TLV

Chapter 17

デバイス実装の実際 — プラットフォーム・Factory Data・省電力・TLV

この章がなぜ必要なのか——「動く」と「製品になる」の間に大きな溝がある.

評価ボードでサンプルが動いた。だが製品にするには、 メモリは足りるのか、電池は何年持つのか、量産で鍵をどう入れるのか—— ハードウェアの現実と向き合う必要がある。

この章は、その現実的な制約を整理する。 併せて、Matter の全ペイロードを支える TLV も扱う。

この章で使う既出の用語(定義は各リンク先). Matter(01 章 3 節)、アプリケーション層(01 章 3 節)、セキュリティ(01 章 2 節)、ネットワーク(01 章 3 節)、Client(02 章 5 節)、mDNS(03 章 4 節)、Wi-Fi(04 章 9 節)、BLE(05 章 1 節)、必要(05 章 5 節)、Exchange(06 章 5 節)、SAI(06 章 3 節)、SII(06 章 3 節)、SRP(06 章 2 節)、再送(06 章 3 節)、UniqueID(08 章 1 節)、イベント(08 章 8 節)、Read(09 章 1 節)、Write(09 章 1 節)、Critical(10 章 5 節)、MaxInterval(10 章 1 節)、Manage(11 章 8 節)、改竄(11 章 1 節)、署名(11 章 2 節)、証明書(11 章 5 節)、DAC(12 章 11 節)、トレーサビリティ(12 章 7 節)、委託製造(12 章 7 節)、ZAP(16 章 1 節)

1. SoC の選定

必要なリソースの目安

項目目安
Flash1 MB 以上(OTA の A/B 領域を取るなら 2 MB 以上)
RAM128 KB 以上(クラスタ数と Fabric 数で変動)
不揮発(設定用)数十 KB(Fabric 5 個で 5〜10 KB、14 章)
暗号アクセラレータほぼ必須(P-256、AES)
TRNG必須(11 章)
セキュアストレージDAC 秘密鍵の保護(12 章)

OTA が Flash 要求を倍にする. 更新中に失敗しても元に戻れるようにするには、 新旧 2 つのイメージを同時に保持する必要がある(18 章)。 外部フラッシュを追加する設計も一般的である。

「1 MB あれば足りる」で設計を始めると、OTA で詰む。 最初から 2 MB 以上、または外部フラッシュを前提にする。

主なプラットフォーム

ベンダー代表的な SoC対応
EspressifESP32-C3 / C6 / H2 / S3Wi-Fi、Thread(C6/H2)、BLE
NordicnRF52840 / nRF5340 / nRF54Thread、BLE
Silicon LabsEFR32MG24 / MG26Thread、BLE
Texas InstrumentsCC13xx / CC26xxThread、BLE
NXPK32W / RW61xThread、Wi-Fi、BLE
Realtek / Telink / Bouffalo / Infineon など各種各種

選定の観点:

最後の項目は軽視されがちだが極めて重要である。 前例のないチップで認証に挑むのはリスクが高い。

2. Factory Data

出荷時に個体ごとに書き込むデータ(12 章の再掲と実装)。

項目個体ごと
DAC 証明書 + 秘密鍵○
PAI 証明書、CD×(製品共通)
Discriminator○
SPAKE2+ の salt / iterations / 検証子○
VID / PID×
シリアル番号、UniqueID○
Rotating Device ID の鍵○
製造日、ハードウェアバージョン一部 ○

実装の形

方式 A: 専用のフラッシュパーティション
    ├── 起動時に読み込む
    └── ベンダーのツールで書き込む(esp-matter の mfg_tool など)

方式 B: セキュアエレメント
    ├── DAC 秘密鍵は SE の中。署名は SE に依頼する
    └── 証明書は SE 内または通常フラッシュ

方式 C: 開発時のみ — ビルドに埋め込む
    └── 製品では使ってはいけない
// SDK は DeviceAttestationCredentialsProvider を差し替えられる
class MyDacProvider : public Credentials::DeviceAttestationCredentialsProvider {
    CHIP_ERROR SignWithDeviceAttestationKey(const ByteSpan & message,
                                            MutableByteSpan & out) override {
        return SecureElementSign(message, out);  // ← SE に署名を依頼
    }
    // GetDeviceAttestationCert, GetProductAttestationIntermediateCert, ...
};

秘密鍵をメモリに読み出さずに署名できることが、SE の価値である. 「鍵をフラッシュから読んで、RAM 上で署名する」実装では、 RAM ダンプで鍵が漏れうる。

セキュアエレメントを使うなら、この Provider の差し替えが実装作業になる。

量産ラインでの書き込み

課題検討事項
書き込み時間1 個あたり数秒 × 生産数
並列化複数台同時に書き込めるか
トレーサビリティシリアル ↔ 証明書の対応記録
不良品の扱い発行済み証明書の失効
委託製造EMS に何を渡すか。鍵を渡さない方式を選べるか
セキュリティ書き込み装置とネットワークの保護

ここは製造技術部門との協業になる. ソフト屋だけで決められない。開発の早い段階で製造側と握ること。

3. 省電力 — ICD(Intermittently Connected Device)

電池機器は常時受信できない(04 章の SED)。 これを Matter のアプリケーション層で扱う仕組みが ICD である。

SIT と LIT

種別Idle 時間用途
SIT(Short Idle Time)15 秒以下下り方向の即応性が要る機器(ドアロックなど)
LIT(Long Idle Time)15 秒超(数分〜時間)センサーなど、上り方向が主の機器

ICD Management クラスタ (0x0046)

属性内容
IdleModeDurationアイドル状態の長さ
ActiveModeDuration起きている時間
ActiveModeThreshold通信後、これだけは起きている
RegisteredClientsCheck-In を送る相手
ICDCounterCheck-In のカウンタ
UserActiveModeTriggerHintユーザーが機器を起こす方法(ボタンを押す等)

Check-In プロトコル(LIT 向け)

LIT 機器は普段完全に寝ている
   ↓
定期的に起きて、登録されたクライアントに Check-In メッセージを送る
   ↓
クライアントが「用がある」と応答すれば、機器はしばらく起きている
   ↓
用がなければまた寝る

これで「数時間に 1 回しか起きない機器」でも制御できる. ただし応答は当然遅い。 UserActiveModeTriggerHint で「ボタンを押すと起きます」と伝え、 アプリが「機器のボタンを押してください」と案内するという UX になる。

電池寿命の見積り

\[ \text{平均電流} \approx I_{\text{sleep}} + \frac{t_{\text{active}}}{T_{\text{poll}}}\left(I_{\text{active}} - I_{\text{sleep}}\right) \]
\[ \text{寿命} \approx \frac{\text{電池容量} \times \text{有効率}}{\text{平均電流}} \]
パラメータ典型値
\(I_{\text{sleep}}\)1〜5 µA
\(I_{\text{active}}\)5〜10 mA(受信時)
\(t_{\text{active}}\)数 ms(Poll 1 回)
電池容量(CR2032)約 220 mAh
電池容量(単三 ×2)約 2000 mAh
有効率0.7〜0.8(自己放電、低温、電圧降下)

試算例(CR2032、ポーリング 5 秒、Active 6 ms、5 mA、Sleep 2 µA):

平均電流 \(\approx 2\ \mu A + \frac{0.006}{5}\times 5\ \text{mA} = 2 + 6 = 8\ \mu A\)

寿命 \(\approx \frac{220\ \text{mAh} \times 0.75}{0.008\ \text{mA}} \approx 20{,}600\) 時間 \(\approx\) 2.3 年

ポーリングを 1 秒にすると平均電流は約 32 µA になり、寿命は約 7 か月まで縮む。 ポーリング間隔が寿命を支配していることが分かる。

この見積りは必ず実測で検証すること。 電流計での実測なしに製品を出してはいけない。 通信の頻度、再送、OTA、起動時の突入電流など、計算に入らない要素が多い。

省電力の実装ポイント

項目内容
サブスクリプションの MaxInterval長くする(10 章)。機器が主導権を持てる
SII / SAI の広告正しく出す。出さないと再送で電池が減る(06 章)
不要な通信を減らす定期報告の頻度を最小限に
起動時間CASE Resumption で署名検証を省く(14 章)
送信電力必要以上に上げない
センサーの読み取り必要なときだけ

4. TLV — Matter のシリアライズ形式

すべてのペイロードは TLV(Tag-Length-Value)でエンコードされる。

構造

┌──────────────┬─────────┬────────┬───────┐
│ Control Byte │   Tag   │ Length │ Value │
└──────────────┴─────────┴────────┴───────┘
   1 byte        0-8 byte  0-8 byte  可変

Control Byte の上位 3 bit が Tag の形式、下位 5 bit が要素の型を示す。

Tag の形式

形式Tag のサイズ用途
Anonymous0配列の要素など
Context-specific1 byte構造体のフィールド(最も多い)
Common Profile (2/4 byte)2 or 4—
Implicit Profile2 or 4—
Fully Qualified (6/8 byte)6 or 8完全修飾(クラスタ ID を含む)

主な型

型内容
Signed Integer1, 2, 4, 8 byte
Unsigned Integer1, 2, 4, 8 byte
BooleanTrue / False(値は Control Byte に埋め込まれる)
Float / Double4 / 8 byte
UTF-8 String長さ 1, 2, 4, 8 byte
Octet String同上
Null値なし
Structure入れ子。End of Container で閉じる
Array同じ型の並び
List異なる型を含みうる並び
End of Container構造の終端

設計の要点:

エンコード例

{ 0: true, 1: 42 } という構造体(Context tag 0 と 1):

15          ← Structure 開始(Anonymous tag)
  28 00     ← Context tag 0, Boolean False … (True なら 29 00)
  24 01 2A  ← Context tag 1, UInt8, 値 0x2A = 42
18          ← End of Container

実際のバイト列は仕様書の Appendix A に多数の例がある. 独自にパーサを書くなら、まずそこの例で検証すること。

通常は SDK の TLVReader / TLVWriter を使うので、 手でエンコードすることはほぼない。 ただしログを読むときや、パケットキャプチャを解析するときに TLV が読めると圧倒的に速い(21 章)。

5. メモリ設計

RAM の主な消費要素

要素目安
Matter スタック本体数十 KB
セッション(CASE)1 セッション数百 byte × 同時数
Exchange数十 byte × 同時数
サブスクリプションパス数に比例
属性ストレージ(RAM 方式)クラスタ数に比例
イベントバッファ設計次第
ネットワークスタック(Thread / Wi-Fi)数十 KB
TLS/暗号のワーク領域数 KB

削減の手立て

手段効果
不要なクラスタを削る(ZAP)属性ストレージとコードサイズ
SupportedFabrics を減らす不揮発とセッション
サブスクリプション上限を減らすRAM
イベントバッファを小さくRAM(ただし Critical の保持と両立させる)
診断クラスタを削るコードサイズ
ログレベルを下げるコードサイズ(文字列が消える)

リリースビルドでログ文字列を削るのは効果が大きい. デバッグログの文字列だけで数十 KB になることがある。 ただしフィールドでの障害解析ができなくなるので、 「エラーコードだけ残す」といった折衷が現実的である。

6. 起動時間

ユーザーは電源投入後すぐ使えることを期待する。

フェーズ時間の目安
ブート数十 ms〜
Factory Data の読み込み数 ms
ネットワーク参加(Thread)数百 ms〜数秒
ネットワーク参加(Wi-Fi)1〜数秒
mDNS / SRP 登録数百 ms
CASE 確立(初回)数百 ms〜1 秒
CASE 確立(Resumption)数十 ms

停電からの復帰が実際の評価ポイントになる. 家中の Matter 機器が一斉に起動し、一斉に mDNS を出し、 一斉に CASE を張ろうとする。 ネットワークが輻輳して、復帰に数分かかることがある。

対策として、起動時にランダムな遅延を入れる実装が有効である。

7. 落とし穴

落とし穴対処
Flash 容量の見積り不足(OTA)最初から 2 面分を確保
電池寿命の机上計算のみ必ず実測する
ポーリング間隔の設定ミス寿命を支配する。慎重に決める
TRNG を使っていない暗号が無意味になる
DAC 秘密鍵を平文保存SE か暗号化領域
Factory Data の設計が遅い製造部門と早期に協議
SII/SAI を広告しない再送で電池が減る
起動時の一斉アクセスランダム遅延を入れる
セキュアブート未設定改竄ファームが動く
デバッグポート開放のまま出荷鍵が抜かれる

8. まとめ