ロビ2のプログラムコマンド解析
2019年4月27日
12月27日改訂
2023年12月22日改訂
ロビ2も完成して1ヶ月が経とうとしていますがまだサーボの設定値の問題や音声認識ボードの不具合など結構トラブルが収束していないようです。
ロビ2のSDカードを見て驚かれた方もいらっしゃると思いますがロビ1のプログラムである拡張子RM4のファイルがひとつも入っていません。
ロビ2ではSTARTUP.BINというファイルに全部のプログラムが集約されています。
従来各動作(認識語に対応)別にプログラムが作られていてそれをメインプログラムから呼び出す形式になっていました。
この構造は変わっていないのですが各機能プログラムもSTARTUP.BINに含まれていてそりをメインプログラムの部分から呼び出すようになっています。
従来のRM4形式のプログラムはテキスト形式のファイルでメモ帳などで開けて文字データで記述されているのでどういった内容の処理をしているのか分かりやすい構造になっていました。
これに反してSTARTUP.BINはバイナリ形式で単に数値の羅列で我々にとって意味のない数値で数値の意味を知らないと内容が全然分かりません。
この我々にとって訳の分からない数値は実はロビのマイコンボードにとっは処理のしやすい形式なのです。
ロビ1の時もRM4ファイルを読み込んでこのバイナリ形式のプログラムに変換してからマイコンボードで処理をしていたと思います。
そのためロビ1の時は我々はこの数値の意味を知らなくてもRM4ファイルを変更するだけでプログラムを書き換える事ができました。
しかしロビ2では画像認識ボードとのやりとりやQ-boからのBluetooth信号の処理などが増えてメモリが必要となり従来マイコンボードでやっていたRM4形式からバイナリ形式の変換ができなくなったのかも知れません。
またこの変換時間がなくしてプログラムの処理スピードの向上を図ったのかも知れません。
いずれにせよ今まで知らなくてもよかったこの数値ですがロビ2のプログラムをいじろうとすなら意味を知っておく必要がありそうです。
16進数とリトルエンディアン
ロビのプログラムコマンドを理解する上で重要な事は16進数とリトルエンディアンです。
この解説でも全て数値は16進数で表示しています。
ロビのマイコンのメモリの単位は通常のコンピュータと同じバイト(何ギガバイトというやつ)で全ての数値がこのバイト(8ビット)が基本になっています。
そこで表す数値は16進数で表した方が理解しやすいのです。
1バイトで表せる数値は10進数では0〜255となりますが16進数では0x00〜0xffとなります。
頭の0xは16進数である事を表します。
なお16進数では0から9は10進数と同じ数字を使いますが11〜15はアルファベットのa〜f(大文字も可)で表して1バイトはちょうど16進表示の2桁となります。
ロビのメモリのアドレスや定数は4バイトで表します(一部例外がありますが)
もうひとつ分かりにくいのはリトルエンディアンという方式です。
コンピューター(インテル系)の世界では割と当たり前なのですがこれもコンピュータの都合(処理しやすい)に合わせたものです。
ほとんどのアドレスや定数を4バイトで表すといいましたが16進で表すと8桁となります。
例えば0x0001a2f3とアドレスをリトルエンディアンで表すとf3 a2 01 00となります。
リトルエンディアンというのは1バイト単位で順番を逆に並べるのです。
実際にファイルにはその順番でアドレスが書かれています。
慣れないと分かりにくいですが理屈はともかくロビのマイコンはそういうものだという事を理解してください。
ちなみにそのまま並べるのがビッグエンディアンといいます。
コマンド体系
ロビのマイコンコマンドは大きくは次のように分けられます。
最初の桁でその分類を表します。(除く一部コマンド)
| ジャンプ系 | 0x8* |
| レジスタ操作系 | 0xc* |
| 計算(判定)系 | 0xd* |
| その他 | 0x9* |
以下に各コマンドの詳細を記述しますがRM4と対応が取れないコマンドについては記述されていません。
ジャンプ命令
ID 0x81
DATA 飛び先アドレス
RM4表記 jump adr="0x12345678"
バイナリ表記 81 78 56 34 12
サブルーチンコール
ID 0x82
DATA サブルーチンアドレス(STARTUP.BIN内のアドレスに変換される)
RM4表記 call filename="xxxx.RM4"
バイナリ表記 82 78 56 34 12
サブルーチンリターン
ID 0x83
DATA なし
RM4表記 return
バイナリ表記 83
条件分岐
ID 0xe0
DATA 飛び先アドレス
RM4表記 jump adr="0x12345678"
バイナリ表記 e0 78 56 34 12
判定(0xd9〜0xde)と組み合わせる
定数ロード
ID 0xc4
DATA 定数
RM4表記 const data="0x12345678"
バイナリ表記 c4 78 56 34 12
メモリ読込み(1バイト)
ID 0xc8
DATA メモリアドレス
RM4表記 mem_r size="1" adr="0x12345678"
バイナリ表記 c8 78 56 34 12
メモリ読込み(2バイト)
ID 0xc9
DATA メモリアドレス
RM4表記 mem_r size="2" adr="0x12345678"
バイナリ表記 c9 78 56 34 12
メモリ読込み(4バイト)
ID 0xca
DATA メモリアドレス
RM4表記 mem_r size="4" adr="0x12345678"
バイナリ表記 ca 78 56 34 12
メモリ書込み(1バイト)
ID 0xcc
DATA メモリアドレス
RM4表記 mem_w size="1" adr="0x12345678"
バイナリ表記 cc 78 56 34 12
メモリ書込み(2バイト)
ID 0xcd
DATA メモリアドレス
RM4表記 mem_w size="2" adr="0x12345678"
バイナリ表記 cd 78 56 34 12
メモリ書込み(4バイト)
ID 0xce
DATA メモリアドレス
RM4表記 mem_w size="4" adr="0x12345678"
バイナリ表記 ce 78 56 34 12
加算(算術演算)
ID 0xd0
DATA なし
RM4表記 add
バイナリ表記 d0
減算(算術演算)
ID 0xd1
DATA なし
RM4表記 sub
バイナリ表記 d1
乗算(算術演算)
ID 0xd2
DATA なし
RM4表記 mul
バイナリ表記 d2
徐算(算術演算)
ID 0xd3
DATA なし
RM4表記 div
バイナリ表記 d3
剰余(算術演算)
ID 0xd4
DATA なし
RM4表記 mod
バイナリ表記 d4
論理積(ビット演算)
ID 0xd5
DATA なし
RM4表記 and
バイナリ表記 d5
論理和(ビット演算)
ID 0xd6
DATA なし
RM4表記 or
バイナリ表記 d6
排他的論理和(ビット演算)
ID 0xd7
DATA なし
RM4表記 xor
バイナリ表記 d7
論理否定(ビット演算)
ID 0xd8
DATA なし
RM4表記 not
バイナリ表記 d8
演算の対象はひとつの値(定数またはメモリ)でふたつの値を記述した場合は後の値が対象となる
0と等しい(判定)
ID 0xd9
DATA なし
RM4表記 eq
バイナリ表記 d9
0と等しくない(判定)
ID 0xda
DATA なし
RM4表記 ne
バイナリ表記 da
条件ジャンプ(0xe0)と組み合わせる
0より大きい(判定)
ID 0xdb
DATA なし
RM4表記 gt
バイナリ表記 db
条件ジャンプ(0xe0)と組み合わせる
0以上(判定)
ID 0xdc
DATA なし
RM4表記 ge
バイナリ表記 dc
条件ジャンプ(0xe0)と組み合わせる
0より小さい(判定)
ID 0xdd
DATA なし
RM4表記 lt
バイナリ表記 dd
条件ジャンプ(0xe0)と組み合わせる
0以下(判定)
ID 0xde
DATA なし
RM4表記 le
バイナリ表記 de
条件ジャンプ(0xe0)と組み合わせる
無操作(NOOP)
ID 0xc0
DATA なし
RM4表記 改行、スペース
バイナリ表記 c0
WAIT(1バイト)
ID 0x88
DATA( 待機時間(1/60秒単位)
RM4表記 wait data="0x12"
バイナリ表記 88 12
DATAは1バイト(符号なし)で指定
WAIT(2バイト)
ID 0x89
DATA 待機時間(1/60秒単位)
RM4表記 wait data="0x1234"
バイナリ表記 89 34 12
DATAは2バイト(符号なし)で指定
WAIT(4バイト)
ID 0x8a
DATA 待機時間(1/60秒単位)
RM4表記 wait data="0x123456"
バイナリ表記 8a 56 34 12 00
DATAは4バイト(符号なし)で指定
メモリ転送
ID 0x90
DATA1 転送アドレス
DATA2 転送バイト数(1バイト)
DATA3〜 データ1,データ2,...
RM4表記 mem_w size="2" adr="0x12345678"
0x9abc,0xdef0,....
バイナリ表記 90 78 56 34 12 nn bc 9a f0 de ....
データは2バイト単位で指定したバイト数リトルエンディアン(前半バイトと後半バイト逆転)で記述
サーボ動作待機
ID 0x8c
DATA 0x00000b43
RM4表記 wait size=1" adr="0x0b43"
バイナリ表記 8c 43 0b 00 00
メモリ転送で0x0b00に書込んだ時間がサーボの動作スピードとなる
音声ファイル再生
ID1〜ID5 0x90, 0x00, 0x04, 0x00, 0x00
DATA1 ファイルパスバイト数(1バイト、最後の0x00分も含む)
DATA2 ファイルパス(最後は0x00を付加)
ID6〜ID12 0x90, 0xe0, 0x01, 0x00, 0x00, 0x01, 0x01
RM4表記 play filename="voice\048.wav"
バイナリ表記 90 00 04 00 00 0e 76 6f 69 63 65 5c 30 34 39 2e 77 61 76 00 90 e0 01 00 00 01 01
ファイル読込み
ID1〜ID5 0x90, 0x00, 0x06, 0x00, 0x00
DATA1 ファイルパスバイト数(1バイト、最後の0x00分も含む)
DATA2 ファイルパス(最後は0x00を付加)
ID6〜ID11 0x90, 0xd8, 0x01, 0x00, 0x00, 0x04
DATA3 読込みメモリアドレス
ID12〜ID18 0x90, 0xd0, 0x01, 0x00, 0x00, 0x01, 0x01
RM4表記 fread filename="ADDON\REMOTE.LOG" adr="0x12345678"
バイナリ表記 90 00 06 00 00 11 41 44 44 4f 4e 5c 52 45 4d 4f 54 45 2e 4c 4f 47 00 90 d8 01 00 00 04 78 56 34 12 90 d0 01 00 00 01 01
ファイル書込み
ID1〜ID5 0x90, 0x00, 0x06, 0x00, 0x00
DATA1 ファイルパスバイト数(1バイト、最後の0x00分も含む)
DATA2 ファイルパス(最後は0x00を付加)
ID6〜ID11 0x90, 0xd8, 0x01, 0x00, 0x00, 0x04
DATA3 書込みメモリアドレス
ID12〜ID18 0x90, 0xd0, 0x01, 0x00, 0x00, 0x01, 0x02
RM4表記 fwrite filename="ADDON\REMOTE.LOG" adr="0x12345678"
バイナリ表記 90 00 06 00 00 11 41 44 44 4f 4e 5c 52 45 4d 4f 54 45 2e 4c 4f 47 00 90 d8 01 00 00 04 78 56 34 12 90 d0 01 00 00 01 02
実際のバイナリプログラム
実際のSTARTUP.BINのマイコンコマンドのファイルダンプとそれに対応したRM4形式を記載します。
ポーズ
ポーズデータ(サーボとLED)をメモリに転送する処理
RM4表記
<mem_w size="2" adr="0x0a00">
0x0000,0x0000,0x0000,0x0050,0x0000,0x003c,0x0000,0x003c,0x0000,0x003c,0x0000,0x0050,0x0000,0x0050,0x0000,0x003c,
0x0000,0x003c,0x0000,0x003c,0x0000,0x0050,0x0000,0x0050,0x0000,0x0032,0x0000,0x0032,0x0000,0x0032,0x0000,0x0032,
0x0000,0x0032,0x0000,0x0032,0x0000,0x0032,0x0000,0x0032,0x0000,0x0032,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00af,0x0046,0x0000,0x00af,0x0046,0x0000,0x0000,0x0000
</mem_w>
<mem_w size="2" adr="0x0b00">0x0033</mem_w>
<wait size="1" adr="0x0b43"/>
0x00005f37の0x90(赤)はメモリ転送のコマンドID
0x00005f38〜0x00005f3bの0x00000a00(緑)は転送先アドレス
0x00005f3cの0x80(橙)は転送バイト数
0x00005f3d〜0x0x00005fbcは転送データ
0x00005fbdの0x90(赤)はメモリ転送のコマンドID
0x00005fbe〜0x00005fc1の0x00000b00(緑)は転送先アドレス
0x00005fc2の0x02(橙)は転送バイト数
0x00005fc3〜0x0x00005fc4は転送データ
0x00005fc5の0x90(赤)はサーボ動作待機のコマンドID
0x00005fc6〜0x00005fc9の0x00000b43(緑)はサーボ動作待機の固定アドレス
条件分岐
音声認識で取得した値を判定して対応する個所に飛ばす処理
RM4表記
<calc>
<mem_r size="2" adr="0x0e5c"/>
<const data="44"/>
<sub/>
<eq/>
<jump adr="0x0001787d"/>
</calc>
0x00017332の0xc9(赤)はメモリ読込み(2バイト)のコマンドID
0x00017333〜0x00017336の0x00000e56c(緑,音声認識値取得メモリ)は読込みアドレス
0x00017337の0xc4(赤)は定数ロードのコマンドID
0x00017338〜0x0001733bの0x0000002c(緑,音声認識語「スタート」)はロードデーター
0x0001733cの0xd1(赤)は減算のコマンドID
0x0001733dの0xd9(赤)は等価(=0)判定のコマンドID
0x0001733eの0xe0(赤)は条件分岐のコマンドID
0x0001733f〜0x00017342の0x0001787d(緑,スタートの処理)は条件分岐先アドレス
目次に戻る