ロビ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(緑,スタートの処理)は条件分岐先アドレス
目次に戻る