自作センサプロトコル
STX(固定 2 バイト)+ Type + Length + Payload + CRC-16/CCITT という独自バイナリプロトコルを題材にしたサンプル。可変長 Payload の扱いと、CRC を応答へ自動付与する仕組みを試せます。
TCP 9500CRC-16/CCITT長さ前置(補正 +2)ビッグエンディアン
概要
固定スタートバイト+種別+長さ+可変ペイロード+チェックサム、という典型的な独自バイナリセンサを再現します。
可変長 Payload を「長さ元」フィールドで扱う方法、チェックサムを応答テンプレートに自動埋め込みする {crc:Crc16Ccitt} 記法、そして長さフィールドと実バイト数のずれを吸収する「長さ補正」の設定を学べます。
{crc:Crc16Ccitt} で CRC を自動付与する 1 ルールファイル構成
| ファイル | 内容 |
|---|---|
sensor-proto/sensor-proto.commsim | プロジェクト本体(構造体定義・構造体ルールを含む) |
sensor-proto/sensor-proto.commsim-struct | 構造体定義のみを切り出した可搬ファイル(別プロジェクトへのインポート用) |
機器構成
単一の TCP サーバセッション。センサクライアント(CommSim.Sample のシナリオ「センサ」等)が接続して Read 要求を送ります。
センサクライアントテスト対象アプリ
⇄
CommSimセンサスタブ(9500)
通信フロー
Read 要求(Type=0x01)に対し、値 100 を載せた Read 応答(Type=0x81)を返します。
- Client →Read 要求
AA 55 01 01 00 B0 B9Type=01 / ch0 - ← CommSimRead 応答
AA 55 81 02 00 64 B6 91値 100 + CRC 自動
フレーム内訳
要求例 AA 55 01 01 00 B0 B9 の解釈:
AA 55 : STX(固定スタートバイト)
01 : Type(0x01 = Read)
01 : Length(Payload バイト数)
00 : Payload(チャンネル 0)
B0 B9 : CRC-16/CCITT(先頭からの計算値)想定プロトコル
先頭 STX に続き、Type・Length・可変 Payload・末尾 CRC。Length は Payload のバイト数を示します。
AA 55STX 2B
Type1B 判別
Length1B
Payload可変
CRC162B CCITT
| フィールド | 型 / 役割 | 備考 |
|---|---|---|
| Stx | u16 | 固定 0xAA55 |
| Type | u8 / 判別 | 1=Read / 129(0x81)=ReadResponse |
| Length | u8 / 長さ | Payload のバイト数 |
| Payload | hex | Length の値だけ読む(可変長) |
| Crc | u16 / チェックサム | CRC-16/CCITT(先頭から) |
使用する機能
設定内容
プロジェクト設定
| 既定データ形式 | RawHex(バイナリ HEX) |
| エンディアン | Big |
| フレーミング方式 | 長さ前置(LengthPrefixed) |
| 共通ヘッダ長 / 長さ ofs / size | 4B / 3 / 1 |
| 長さ基準 / 補正 | ボディ長 / +2(末尾 CRC 2 バイト分) |
長さ補正 +2 は、Length が「Payload のバイト数」を示すのに対し、フレーム末尾に CRC(2 バイト)が付くため、実受信バイト数が
Length + 2 になるのを補正しています。ヘッダ/トレーラを持つ独自プロトコルでも、この補正で正しく切り出せます。構造体定義(Sensor Request)
| フィールド名 | 型 | 役割 | 備考 |
|---|---|---|---|
| Stx | u16 | なし | 固定値 0xAA55 |
| Type | u8 | 判別 | 1 = Read / 129 = ReadResponse |
| Length | u8 | 長さ | Payload のバイト数 |
| Payload | hex | なし | Length フィールドの値だけ読む(可変長) |
| Crc | u16 | チェックサム | CRC-16/CCITT(先頭バイトから計算) |
バイナリ構造応答
| ルール | 条件 | 応答テンプレート(HEX) |
|---|---|---|
| Read(0x01) → 値100 応答(0x81) | なし(1 種類) | AA 55 81 02 00 64 {crc:Crc16Ccitt} |
応答の値(ここでは 100)を変えても、{crc:Crc16Ccitt} が先頭から直前までを自動計算して末尾に付与するため、CRC を手計算する必要はありません。
設定の考え方
| 設定 | なぜそうするか |
|---|---|
| 長さ補正 +2 | Length フィールドが「Payload のバイト数だけ」を示す一方、フレーム末尾に CRC(2 バイト)が付くため。長さフィールドの値と実際の残りバイト数がずれる場合は、長さ補正でその差を吸収する。 |
| Payload を可変長(Length フィールドを長さ元に指定)にする | チャンネル数などで Payload 長が変わるプロトコルを 1 つの定義で扱うため。固定長にすると長さ違いのメッセージで分解が崩れる。 |
応答テンプレートで {crc:Crc16Ccitt} を使う | 応答の値を変えても CRC を手計算せずに済むから。テンプレートが先頭から直前までを自動計算して末尾に付与する。 |
| 構造体ルールを条件なし 1 本にする | Read 要求 1 種類 → 固定の値応答なので、フィールド条件で分岐する必要がないため。 |
開き方:
samples/sensor-proto/sensor-proto.commsim を「ファイル」→「ファイルから開く…」(Ctrl+O)。起動後、Read 要求 AA 55 01 01 00 B0 B9 を送ると応答が返ります。動作確認手順
- CommSim で
samples/sensor-proto/sensor-proto.commsimを開く(メニューバー「ファイル」→「ファイルから開く…」)。 - セッション「センサプロトコル スタブ」の「起動」ボタンをクリックし、待ち受け状態にする。
- クライアントから Read 要求
AA 55 01 01 00 B0 B9を送る(CommSim.Sample のシナリオ「センサ」の「デモ送信」でも可)。 - ログペインに受信(Rx)が表示され、フィールド分解(Stx・Type・Length・Payload・Crc)が確認できる。
- 同タブに送信(Tx)として
AA 55 81 02 00 64 B6 91が表示される。
HEX を手入力する場合は、送信欄でデータ形式を「RawHex」に設定してから入力してください。
実行ログサンプル
Rx AA 55 01 01 00 B0 B9
[Stx=0xAA55] [Type=1(Read)] [Length=1] [Payload=00] [Crc=0xB0B9]
Tx AA 55 81 02 00 64 B6 91このサンプルには採取ログ
logs/sample-sensor-proto.commsimlog を同梱しています。メニュー「ツール」→「ログビュワーを開く…」で開くと、上記のやり取りを実セッションのログとして確認できます。