Interface増刊 S1C17702基板 デバッグモニタ 調査記録


Interface増刊「すぐに使える!液晶搭載マイコン・モジュール」の付属基板には、デバッグモニタのファームウェアが搭載されています。
本基板(以下S1C17702基板と呼ぶことにします)のデバッグモニタは、統合開発環境のデバッガ(gdb)が、S1C17702基板と通信するためのものです。
デバッグモニタを通じてS1C17702基板と通信することによって、レジスタやメモリを読み書きしたり、ブレークポイントを設定したりします。

S1C17702基板のデバッグモニタは、P/ECEにたとえると、おおよそ、緊急カーネルに相当する役割です。
(P/ECEの緊急カーネルとは、SELECT+下ボタンを押しながらリセットしたときに使われる、復旧用の最小限カーネルのことです。)
P/ECE開発環境には、緊急カーネルのソースも含まれていて、緊急カーネルの内部動作をソースから理解することができました。
一方、S1C17702基板の開発環境には、デバッグモニタのソースが含まれていないようです。
gdbを使わずにS1C17702基板と直接通信できたら、便利そうなので、デバッグモニタの通信プロトコルを調査してみることにしました。

最初、S1C17702基板のフラッシュメモリをダンプして、逆アセンブルして調査しないといけないかな、と考えていました。
でも、実際には、もっと簡単でした。
S1C17702基板の開発環境には、復旧時のセルフバックアップ用実行ファイルが含まれています。(「C:\EPSON\C17WBIF\selfbackup\SimpleGDBServer.elf」)
実はこれが、デバッグモニタの実行ファイルそのもののようです。
SimpleGDBServer.elfには、ソースコードデバッグ用の情報が含まれていて、objdumpで逆アセンブルすると、元のC言語ソースにかなり近い情報が得られます。
たとえば、関数名や引数型、さらに、ローカル変数の名前までわかります。

そんなわけで、ほとんどC言語ソースを読んでいるのに近い感覚で、調査できました。
デバッグモニタを調査した結果を、「S1C17702基板 デバッグモニタ 擬似コード」として、まとめてみました。
C言語っぽいですが、あくまで擬似コードなので、そのままコンパイルすることはできません。
また、通信設定や、コマンドリファレンスを、以下にまとめました。(でも、説明不足なので、擬似コードの方が判り易いかも知れません。(^^;)


S1C17702基板のファームウェアは、大きく分けると、二つの機能が含まれているようです。
ひとつは、上述のデバッグモニタの機能です。
もうひとつは、セルフバックアップのマスタ側の機能です。
後者について説明すると、万一S1C17702基板のファームウェアが壊れて起動しなくなった場合、正常なS1C17702基板をもう一台使って、修復することが可能です。
これを、セルフバックアップ機能と呼びます。(本誌の、p.29〜34に説明されています)

セルフバックアップの実行中、壊れた側は、S1C17702 CPUの機能だけを使って、動作します。
正常な側は、壊れた側のS1C17702 CPUの機能を外部から制御するプログラムを実行して、壊れた側が修復するのをサポートします。
この、「壊れた側のS1C17702 CPUの機能を外部から制御するプログラム」が、セルフバックアップのマスタの機能です。

ちなみに、P/ECEにも似たような修復手順があって、P/ECEラボラトリさんの、「瀕死のP/ECEを救え」のページで説明されています。
P/ECEの場合、セルフバックアップのマスタの機能に相当するプログラムは、独立したアプリケーションプログラムでした。
修復を行うときに、正常な側のP/ECEにロードして、実行する方法をとっていました。

一方、S1C17702基板の場合、セルフバックアップのマスタの機能に相当するプログラムが、ファームウェアの中に書き込まれています。
ようするに、S1C17702基板は、他の壊れたS1C17702基板を修復サポートするプログラムを、常に内蔵しているわけです。
しかし、実際にセルフバックアップを実行することは、滅多に無さそうです。
そこで今回は、セルフバックアップのマスタ機能に相当する部分は、調査しませんでした。
デバッグモニタの機能と、セルフバックアップのマスタ機能は、ほとんど完全に分離しているため、デバッグモニタの調査には支障ありませんでした。


通信設定

通信ツールを、このように設定してください。下図は、Tera Term Proの設定例です。

注意 :

  1. ポート番号は、環境によって異なります。S1C17702基板が接続されているポートを、選択してください。

  2. S1C17702基板のJP1とJP5を実装し、ショートしている場合は、通信ツールがDTRとRTSをOnするように設定してください。
    JP1とJP5を実装していないか、オープンの場合は、DTRとRTSがOnであるのと同じですので、気にする必要はありません。

    DTRは、S1C17702基板の外部ブレーク信号を制御するようになっていて、DTRがOffのときに外部ブレークがかかります。
    RTSは、S1C17702基板のリセット信号を制御するようになっていて、RTSがOffのときにリセットがかかります。
    DTRとRTSを両方ともOnにしないと、S1C17702基板が実行状態になれません。

    Tera Term Proの場合は、何も設定しなくても、ポートを開けばDTRとRTSがOnになるので、気にしなくて大丈夫です。
    通信ツールの中には、下図のように、手動でDTRとRTSをOn/Offするものもあるので、その場合には注意してください。


デバッグモニタのコマンド

通信ツールを使って、S1C17702基板のデバッグモニタと、直接、コマンドの送受信を行うことができます。
各コマンドの内容は、S1C17702基板 デバッグモニタ 擬似コードを参照してください。
以下のリファレンスも、あわせて参照してください。

注意 :

  1. 以下のリファレンスでは、読み易さのために、文字列を改行しています。
    実際には、改行せずに、一行で送受信してください。

  2. 方向は、PC側から見た送受信方向です。
    「送信」は、PCが送信し、S1C17702基板が受信することを意味します。
    「受信」は、S1C17702基板が送信し、PCが受信することを意味します。


g : レジスタ読み出し

書式 : g

コマンド送受信例 :

方向
文字列
説明
送信 $
g
#67
パケットヘッダ
コマンド種別
チェックサム
受信
+
$
00000000
00000000
01000000
04410000
00000000
00000000
00000000
00000000
c00f0000
aa800000
02000000
#5f
(nul)
ACK
パケットヘッダ
%r0 = 0x000000
%r1 = 0x000000
%r2 = 0x000001
%r3 = 0x004104
%r4 = 0x000000
%r5 = 0x000000
%r6 = 0x000000
%r7 = 0x000000
%sp = 0x000fc0
%pc = 0x0080aa
%psr = 0x02
チェックサム
終端
送信
+
ACK


G : レジスタ書き込み

書式 : G(%r0)(%r1)(%r2)(%r3)(%r4)(%r5)(%r6)(%r7)(%sp)(%pc)(%psr)

コマンド送受信例 :

方向
文字列
説明
送信 $
G
45230100
ab896700
01efcd00
67452300
cdab8900
2301ef00
89674500
efcdab00
c02f0000
00000100
1f000000
#90
パケットヘッダ
コマンド種別
%r0 = 0x012345
%r1 = 0x6789ab
%r2 = 0xcdef01
%r3 = 0x234567
%r4 = 0x89abcd
%r5 = 0xef0123
%r6 = 0x456789
%r7 = 0xabcdef
%sp = 0x002fc0
%pc = 0x010000
%psr = 0x1f
チェックサム
受信
+
$
OK
#9a
(nul)
ACK
パケットヘッダ
成功
チェックサム
終端
送信
+
ACK


m : メモリ読み出し

書式 : m(アドレス),(データ長)

コマンド送受信例 :

方向
文字列
説明
送信 $
m
009000,80
#2a
パケットヘッダ
コマンド種別
アドレス,データ長
チェックサム
受信
+
$
2025413c7d0f20015c3edc3e5c3c0490
02077f982a101b9002097f9826105c3c
dc3c5c3ddf1b383db83c383c10290181
92290041009c8098ed5fe41b0090020e
7f981310183c088090280fb807b887b0
83a02040009d80990940289e5c3eee5f
251804640090010e7f985c3cc51b383c
0464b83e383e20015c40749c5f409c9c
#ba
(nul)
ACK
パケットヘッダ
データ







チェックサム
終端
送信
+
ACK


M : レジスタ書き込み

書式 : M(アドレス),(データ長):(データ)

コマンド送受信例 :

方向
文字列
説明
送信 $
M
001800,40:
00000000111111112222222233333333
44444444555555556666666677777777
8888888899999999aaaaaaaabbbbbbbb
ccccccccddddddddeeeeeeeeffffffff
#50
パケットヘッダ
コマンド種別
アドレス,データ長:
データ



チェックサム
受信
+
$
OK
#9a
(nul)
ACK
パケットヘッダ
成功
チェックサム
終端
送信
+
ACK


c : 実行

書式 : c

コマンド送受信例 :

方向
文字列
説明
送信 $
c
#63
パケットヘッダ
コマンド種別
チェックサム
受信
+
ACK
デバッグブレークが発生したら…
受信
$
S02
#b5
(nul)
パケットヘッダ
SIGINT
チェックサム
終端
送信
+
ACK


s : ステップ実行

書式 : s

コマンド送受信例 :

方向
文字列
説明
送信 $
s
#73
パケットヘッダ
コマンド種別
チェックサム
受信
+
$
S05
#b8
(nul)
ACK
パケットヘッダ
SIGTRAP
チェックサム
終端
送信
+
ACK


! : 最後に発生したデバッグブレークの要因を取得

書式 : !

コマンド送受信例 :

方向
文字列
説明
送信 $
!
#21
パケットヘッダ
コマンド種別
チェックサム
受信
+
$
S05
#b8
(nul)
ACK
パケットヘッダ
SIGTRAP
チェックサム
終端
送信
+
ACK

備考 : ? と同じです。


? : 最後に発生したデバッグブレークの要因を取得

書式 : ?

コマンド送受信例 :

方向
文字列
説明
送信 $
?
#3f
パケットヘッダ
コマンド種別
チェックサム
受信
+
$
S05
#b8
(nul)
ACK
パケットヘッダ
SIGTRAP
チェックサム
終端
送信
+
ACK

備考 : ! と同じです。


L : フラッシュ書き込み

書式 : L(セクタ番号)

コマンド送受信例 :

方向
文字列
説明
送信 $
L
10
#ad
パケットヘッダ
コマンド種別
セクタ番号
チェックサム
受信
+
$
OK
#9a
(nul)
ACK
パケットヘッダ
成功
チェックサム
終端
送信
+
ACK


d : エコーバック

書式 : d(任意の文字列)

コマンド送受信例 :

方向
文字列
説明
送信 $
d
Hello, world!
#ed
パケットヘッダ
コマンド種別
任意の文字列
チェックサム
受信
+
$
d
Hello, world!
#ed
(nul)
ACK
パケットヘッダ
エコーバック

チェックサム
終端
送信
+
ACK


チェックサム誤りの例

コマンド送受信例 :

方向
文字列
説明
送信 $
g
#00
パケットヘッダ
コマンド種別
チェックサム(誤り)
受信
-
NAK


コマンド種別誤りの例

コマンド送受信例 :

方向
文字列
説明
送信 $
a
#61
パケットヘッダ
コマンド種別(誤り)
チェックサム
受信
+
$
#00
(nul)
ACK
パケットヘッダ
チェックサム
終端
送信
+
ACK


Sun Dec 20 16:16:22 JST 2009 Naoyuki Sawa (nsawa@piece-me.org)