serparser
シリアル書式入出力 (mwx::serial_parser)
シリアル書式の入出力のために用います。内部に解釈済みのバイナリ系列を保持するバッファを持ち、入力時は1バイトずつ系列を読み出し書式に従い内部バッファに格納し、系列の解釈が完了した時点で完了状態になるものです。反対に出力時は内部バッファから所定の出力書式に従いバッファを出力します。
メモリバッファ取り扱い方法(alloc
)に応じて3種類のクラス名が定義されています。
定数(書式種別)
begin()
の初期化のパラメータで渡す書式の種別です。ここではアスキー形式とバイナリー形式の2種類があります。
定数
種別
uint8_t PARSER::ASCII = 1
アスキー形式
uint8_t PARSER::BINARY = 2
バイナリー形式
バイナリ形式の取り扱いはアスキー形式に比べ、必要なツールや確認方法を含め一般に取り扱いが煩雑になります。通常はアスキー形式をお使いください。
形式について
アスキー形式
アスキー形式は、バイナリで構成されたデータ列を文字列で表現する方法です。
例えばバイト列で 00A01301FF123456
をアスキー形式で表現すると、以下のようになります。先頭は :
で B1
がチェックサム、終端は [CR:0x0d][LF:0x0a]
となります。
:00A01301FF123456B1[CR][LF]
終端のチェックサムを省略できます。チェックサムからCRLFの系列をX
に置き換えます。文字化けによる誤ったデータ系列には弱くなりますが、実験などでデータを送付したいときに便利です。
:00A01301FF123456X
定義
======
元データのバイト数
バイト数
解説
ヘッダ
1
:
(0x3A) コロンを指定します。
データ部
N
2N
元データの各バイトをアスキー文字列2文字(A-F は大文字)で表現します。
例えば 0x1F は 1
(0x31) F
(0x46) と表現します。
チェックサム
2
データ部の各バイトの和を8ビット幅で計算し2の補数をとります。つまりデータ部の各バイトの総和+チェックサムバイトを8ビット幅で計算すると0になります。
チェックサムバイトをアスキー文字列2文字で表現します。
例えば 00A01301FF123456
では 0x00 + 0xA0 + ... + 0x56 = 0x4F となり、この二の補数は0xB1 です。(つまり 0x4F + 0xB1 = 0x00)
フッタ
2
[CR] (0x0D) [LF] (0x0A) を指定する。
バイナリ形式
通常はアスキー形式を利用してください。
マイコン間通信での実装を考えるとバイナリ形式のほうが効率的ですが、実験などでの送受信の確認にはバイナリ通信に対応した特別なターミナルなどを準備する必要があり、チェックサムの計算も必須です。アスキー形式より利用の難易度は高くなります。
バイナリ形式は、バイナリで構成されたデータ列にヘッダとチェックサムを付加して送付する方法です。
例えば 00A01301FF123456
をバイナリ形式で表現すると、以下のようになります。
0xA5 0x5A 0x80 0x08 0x00 0xA0 0x13 0x01 0xFF 0x12 0x34 0x56 0x3D
定義
======
元データのバイト数
形式におけるバイト数
解説
ヘッダ
2
0xA5 0x5A
を指定します。
データ長
2
データ長はビッグエンディアン形式の2バイトで、MSB (0x8000) を設定した上、データ部の長さを指定します。
例えばデータ部の長さが 8 バイトなら0x80 0x08
を指定します。
データ部
N
N
元データを指定します。
チェックサム
1
データ部の各バイトの XOR を計算します。
例えばデータ部が 00A01301FF123456
なら 0x00 xor 0xA0 xor ... 0x56 = 0x3D となります。
フッタ
(1)
チェックサムが事実上の終端です。無線モジュールからの出力では 0x04
(EOT) が付加されます。
メソッド
宣言, begin()
宣言にはメモリの確保クラスを指定します。この指定は煩雑であるため、上述のように別名定義を行っています。
クラス名(別名定義) メモリ確保
内容
serparser_attach
すでにあるバッファをbegin()
にて指定する
serparser_local<N>
Nバイトのバッファを内部に確保する
serparser_heap
begin()
メソッドのパラメータで指定したサイズをヒープに確保する
メモリ確保クラスに応じたbegin()
メソッドを呼び出します。
serparser_attach
ty
で指定する形式で、p
で指定したバッファを用います。バッファの最大長はmax_siz
で、バッファの有効データ長をsiz
で指定します。
この定義は、特に、データ列を書式出力したい場合に用います(>>
演算子参照)
serparser_local<N> - 内部にバッファを確保する
ty
で指定する形式で初期化を行います。
serparser_heap - ヒープに確保
ty
で指定する形式で、siz
で指定したサイズをヒープに確保して初期化します。
一度確保したヒープ領域は解放できません。
get_buf()
内部バッファを返す。バッファは smplbuf<uint8_t, alloc>
型となります。
parse()
入力文字を処理する。書式入力の入力文字列を1バイト受け取り書式に従い解釈します。例えばASCII書式では:00112233X
のような系列を入力として受け取りますが : 0 0 ... X
の順で1バイトずつ入力し、最後の X
を入力した時点で書式の解釈を完了し、完了済みと報告します。
parse()
のパラメータは入力バイト、戻り値は解釈完了であればtrue
を戻します。
parse()
で読み出し完了になったとき、次のparse()
を実行すると読み出し中のステータスに戻ります。
例
operator bool()
true
ならparse()
により読み出しが完了した状態で、false
なら解釈中となります。
例 (parse()の例は以下のように書き換えられる)
<< 演算子
内部バッファを書式形式でストリーム(Serial)に対して出力します。
例
最終更新