ADuC702x用 JTAG flash downloader


つーわけでこちらは JTAG経由のダウンローダな件。
転送速度は TP240 + wiggler clone で 4kB/s ほど。 けっこうメモ書き長いので使うだけなら途中ぜんぶすっとばして下の「ダウンローダ」の項へ。

原理

JTAG チェインを経由してできることは三つ。

これをくみあわせるとまず、

次に、 プログラム内から I/O 叩いてフラッシュに書き込む方法はマニュアルに載ってるので、この時点で 書き込む命令を順繰りに JTAG に乗せて等とすれば書ける。試したところ 0.5kB/s ほどで動いた。

さて。メモリに読み書きできるようになったら、ようやく

ということができるようになって、

ADuC7019/702x のフラッシュの消去単位は 512 バイト。 512 バイトずつメモリに送りこんでは、それをフラッシュに書き込むプログラムを実行、 という風にしてフラッシュに書き込むことができる。 こっちの方法でおよそ 3kB/s 〜 4kB/s になった。

... というのが表書きだが、最初のレジスタの読みかきのタイミングについて一言。

  1. 命令をデータバスに乗せ、
  2. 適当なサイクル待って、
  3. データをデータバスに乗せる/読み取る
  4. 命令が終るまで適当にサイクル回す。
てなことをすることになってるのはいいんだけど、 この「適当なサイクル」をどんだけ回すのかどこにも書いてなくて
「こうしないとうまくいかん。なんでやねん?」
的コメントに満ちあふれていたりする ──
JTAG から挿入する LDR/STR 命令とパイプライン
ロード命令:
    ldr  r0, [r1]
については、
       EXEC_Instruction(ldr_r0_r1);
       EXEC_Instruction(nop);
       EXEC_Instruction(nop);
       EXEC_Instruction(data);
       EXEC_Instruction(nop);
てな具合に、通常 ldr 命令をパイプラインに挿入した 3 サイクル後にデータを挿入するが、 ldr より前のパイプラインが詰まってると、挿入タイミングが後ろにずれる。 実際、たまにレジスタに 0xE1A00000 がロードされてる例を見かけた。 ldr のタイミングミスで、後続の NOP のビットパターンをロードしてしまってるんだな。 事実上 ldr は
       EXEC_Instruction(nop);
       EXEC_Instruction(nop);       // パイプラインフラッシュ。
       EXEC_Instruction(ldr_r0_r1);
       EXEC_Instruction(nop);
       EXEC_Instruction(nop);
       EXEC_Instruction(data);
       EXEC_Instruction(nop);
こういう形で使う。
JTAG から挿入する LDR 命令とバウンダリ
ロード命令:
    ldr  r0, [r1]
において、ロードする瞬間には暗黙のうちにアドレスバスに r1 が出力されるが、 この r1 の下位 2 ビットが 0 でない場合 (r1 が alignment してない場合)、 データバスに挿入した値を realignment してから r0 ロードにしてくれるので、 値が変わる (下位2ビットが 1/2/3 の各々について 8/16/24 ビット分だけ右ローテートした値がレジスタに入る)。

ただしく alignment されてることがわかってるのは PC だけなので、事実上 ldr は ldr r0, [pc] の形でしか使えない。
なお、str 命令のほうはアドレスに使うレジスタのバウンダリに無関係に正しい値が読みとれる。

THUMB 命令セットと ARM7TDMI

JTAG からプログラムを止めたとき、CPU は THUMB 命令を実行中である可能性がある。 この場合、ARM7TDMI (arm v4t) では JTAG 中に挿入する命令セットは THUMB になる。

何事かさせるのにいちいち二セット用意するのは面倒すぎるので、さすがにマニュアルでも

「ARM 命令セットに移る THUMB 命令を挿入し、そっちでお仕事。 復帰する時はまた THUMB から復帰する命令を挿入すればええ」
と書いてある。丁寧に最小セットも明示されている。

とっても言い訳っぽいが、実際ただの言い訳だと思う。 arm v5 以降では THUMB に居ても JTAG から挿入するのは ARMセットになった。 ついでに ARM ⇔ THUMB 間を渡り歩くサブルーチンコールが一命令にまとまって PC の扱いが綺麗になった。 ARM ⇔ THUMB interworking 的には arm v6 がとっても羨ましい。

arm v4t での実装は ARM から THUMB への復帰の時の PC のズレを(他のレジスタを非破壊のままで)補正するのが とてつもなくめんどい ... どーせダウンローダでは関係ねー、復帰先はリセットベクタで ARM セットだしぃと言う具合に今回は投げた。わはは。

ADuC7026 のフラッシュ書き込みステータス

のんびり gdb から remote gdb server 経由でかきこんでいるうちは気付かないことだが、 フラッシュ制御インターフェースのステータスレジスタ FEESTA の反応はとっても鈍い。

フラッシュに書き込むと、書き込み動作中は busy フラグが立って、書き込み動作終了後に 異常終了か正常終了のフラグが立つ、ことになっているが、 割り込みを使わない場合の実際の挙動はこんな感じ:

  1. FEESTA は 0x20 (平常状態)。
  2. FEECON に 0x2 (書き込み命令) を書き込む。
  3. 2 〜 3? クロックして FEESTA に BUSY が立つ (0x24)。
  4. 所定の時間(20us)経過後、BUSY が降り、フラグが全部立つ (0x23)。
  5. 次のクロックで正常終了を唱える (0x21)。
  6. もいっかい読みだすと平常に戻る (0x20)。
書き込み命令直後に BUSY フラグが消えるのを待つループをいれると BUSY フラグが立つ前にループを抜けてしまう。
パイプラインが効いてるだけという言い訳は聞かん(いや、これで正解だろうけど)。 正常終了であっても異常終了フラグが 1 になる瞬間があるんだから。 プログラム中から使うときは busy-loop でフラグを見たりせずに割り込み使うから困らないとはいっても、 JTAG からいじくってるときに割り込みなんて繁雑なことをするつもりはない。

いろいろ試行錯誤したがうまくフラグが捕まらないので、結局 20us を待つだけにして、 正常書き込みになったかどうかはベリファイに任せた。
消去のほうはというと、1 ページ(512 バイト)あたりで 20ms も待つことになっているが、 データ 1 ページ分を RAM に送り込むのには どーせそれ以上の時間(50ms)がかかるのでこちらも一々ステータスはチェックしていない。

0 番地とリセットと startup.s

パワーオンリセットで 0 番地から実行開始する。 当然、0 番地から飛んだ先に初期化ルーチンがある。

したがって ROM を 0x00000 に張り付けた状態で 0x00000000 に飛べばリセットに ... ならなかった。

もっともハマった点だったりする。 jtager で restart --pc=xxxx などとして止めた場所からの継続実行だとなんだか動くのに、 単なる restart (0x00000000 からの実行。リセット相当ということになっている)すると暴走する。PC の調整をまずったかと思った。

MMU を持たず、特権についてほとんど記述がない CPU 相手だったのが傷を深くした。 jtager が 0 へのジャンプをリセットと同一視していていかにも「これで良いんですっ」風なのも。 OS 使うやつももうすこし面倒見が良いしなぁ。

リセットからの初期化シーケンスだけは、スーパパイザモードにいないといけない。 スタートアップは割り込みハンドラや未定義命令違反などでのスタックの調整を含む。 ユーザーモードからは出来てはいけないことなのでただちに特権違反でシステムモードに入り、 しかるのちそのまま暴走する。

リセットするには 0x00000000 に飛ぶのではなく ちゃんと RSTSTA 叩いてソフトリセットしましょうという話。

逆に言うと、普段使うときも Keil や gcc 付属の startup.s では PC が 0x0 を嘗めるのがリセット(or watchdog) の代わりにならず、暴走する。 手持ちのコードではリセットルーチン冒頭で自分がスーパパイザモードでなければソフトウエアリセットするように直した。

Reset_Handler:  
                mov  r0, #0x80000000 
                mov  ip, r0, asr #15     /* 割り込み関連 MMR = 0xffff0000 */
                mov  r0, #0
                str  r0, [ip, #0x08]     /* 全割り込み禁止 ← これが特権違反にならねーってのがなんとも... */
                MRS   R0, CPSR
                AND   R0, R0, #0x1f
                SUBS  R0, R0, #0x13
                beq   IN_SUPMODE
                mov  r0, #4
                strb  r0, [ip, #0x230]    /* ソフトウエアリセット発生、スーパパイザモード移行 */
IN_SUPMODE:
                nop
.if PLL_SETUP
とっても快適。
もちろんダウンローダは書き込み後の再実行あたって 0x00000000 に飛ぶのでなくソフトリセットするようにしている。 startup.s の出来にローダが依存する訳にはいかない。

余談だが、gcc が C での unsigned int* base = (unsigned int *)0xffff0000; に対し 上の Reset_Handler: 冒頭二行のようなコードを返してきたときはちょっと感動した。 パイプラインがスムースなので ldr r0, =どっか より普通に速く、 JTAG からデータバスに挿入した時は圧倒的に速い。

コード小片

フラッシュ書き込みやらなんやら、プログラム小片をターゲット内に送り込むということはつまり、 ARM のコードを (ARM で動いてるのではない)ローダが内部に持ってるということである。

つまり

        .text
        .arm
write_page_hook: .word  _write_page_hook - _write_page
write_page_size: .word  _write_page_end  - _write_page
_write_page:
        mov     r0, #-2113929216
        mov     ip, #1  @ movhi
        mov     r4, r0, asr #15
        str     ip, [r4, #4]    @ movhi 
        nop
        mov     lr, #4  @ movhi
        ...
こういうのを
unsigned int write_page_hook = 0x51; /* 0x144(324) */
unsigned int write_page_size = 88;
unsigned int write_page_code[88] = { /* 352 bytes. */
        0xe3a09000,
        0xe3a00482,
        0xe3a0c001,
        0xe1a047c0,
        0xe584c004,
        0xe1a00000,
        0xe3a0e004,
          ...
こんな風に変換してローダソース中に持つということだ:
% arm-linux-gcc -c write_page.s
% arm-linux-ld -Ttext 0 -o fixed.o write_page.o
% arm-linux-objcopy -O ihex fixed.o write_page.hex
% ./ihex2struct write_page < write_page.hex  > write_page.c
バイナリをヘッダに直す ihex2struct なんてのはすぐ書けるだろうからどーでも良いとして、 ひとつだけメモ書き。

相対ジャンプの解決はリンカの仕事で、アセンブラがローカルに解決できるものでさえリンカ任せになる。 上の例で言えば write_page.o 内の相対ジャンプのオフセットは間違っている。 適当なセグメントページを固定してインクリメンタルリンカに流す。 text セグメントのページ頭の解釈はまだ間違ってる(間違ってても問題ない)が、相対ジャンプはこの時点で直る。

再初期化シーケンス

JTAG で割り込んでシステムを止めたとき、システムがどんな状態にあるかは動作クロック含めていっさい不明である。 コード小片の実行時間とかの見積りさえできない。とりあえず冒頭で:
  1. 全割り込み禁止
  2. PLL 再設定 (分周比 3; 5.2MHzで駆動)
  3. PORT0.3 に TRST 設定
  4. フラッシュへの書き込み許可
  5. フラッシュ制御インターフェースの空き待ち
なんぞしておいた。これで足りるかな。

OCDRemote, gdbice, jtag_gdbserver, openocd, JTAGER, H-JTAG, JTAG Tools

ARM7TDMI のレジスタやメモリ等の読み書きを JTAG のピンの上げ下げで読み書きする方法なんて決まり切っているもの (でもとってもめんどくさそうなもの...) を再発明する気力はない。

というところで見付けた wiggler ケーブルを使って ARM の JTAG と通信できるフリーの下位プログラム群。 上位のプロトコルとしては ARM remote debug protocol/inteface をしゃべるもの、 remote gdb protocol をしゃべるもの、自前でテキスト吐くものといろいろあるけど、 そっちは適当に話を合わせれば良いだけだから。

OCDRemote
remote gdb protocol を喋る。これだけソース非公開。 Win 用と linux 用とあるが、linux 用は wiggler ケーブルをサポートしない。 プログラムの run 中にレジスタを書き換えることができないのが難。
openocd
remote gdb protocol を喋る。 動作中のレジスタ書き換えはやっぱり禁止。 Configuration file はデフォルトではカレントディレクトリの openocd.cfg しか見ないので、試しに起動するときでも
# ./openocd -f openocd.cfg
などとすること。また、TCP ポートとして 3333 を使う。 OCDRemote の 8888 とは異なる。 ちなみに 3333 のが gdb 的には由緒正しかったはず。OCDRemote が 8000 番台に上げた気分も分かるが。

step 実行するのに使うブレークがデフォルトではソフトウエアブレークなことは気になる。 ハードウエアブレークに切替えるフラグは force_hw_bkpts とゆーらしーが未テスト。

また、配布ファイルに configure が含まれておらず、autoconf, automake 一式が要る。 これらを自前で用意するのは *.in が tool の version に煩いからヤなんだよな ...。 いろいろ組合せてみて 2.59 と 1.4 の組では動いた。わりと新しいセットが要るようだ。

jtag_gdbserver
remote gdb protocol を喋る。 動作中のレジスタ書き換えは禁止。ついでに I/O 書き換えも禁止。ぐは。
step 実行は正しくハードウエアブレークである。現在も開発続行中だが、どーせなら openocd のチームとリソース一本化してくれい。 起動は:
# ./jtag_gdbserver  -driver wiggler 192.168.63.21:3333
必ずクライアント(arm-*-gdb を起動するホスト)を指定する。gdb 上で
(gdb) monitor MemMap.MaxNum       = 1
(gdb) monitor MemMap.MaxEntrys[0] = 4
(gdb) monitor MemMap[0][0]        = rom,   16, 0x00000000, 62 KByte
(gdb) monitor MemMap[0][1]        = ram,   32, 0x00010000,  8 KByte
(gdb) monitor MemMap[0][2]        = rom,   16, 0x00080000, 62 KByte
(gdb) monitor MemMap[0][3]        = ram,   16, 0xFFFF0000, 64 KByte
(gdb) monitor UseMemMap[0]
てな具合にメモリマップを指定してようやく使えるようになる。 ある意味でまともだが繁雑な上に I/O マップの扱いが実装されとらんよーな。 それにアドレス毎にワード長が違う ADuC7026 の MMR のような奴を正しく扱わせるのは大変だ。
H-JTAG
ARM remote debug interface を喋る。win 用でソースも公開。 なお、wiggler variation に対応する。 OCDRemote が口煩いので今回は結局 wiggler ケーブルそのものを作らざるをえなかったが、 h-jtag をふくめ OCDRemote 以外は XiLINX パラレルケーブル等、他のピンアサインをもつパラレルケーブルを使うこともできる。
JTAG Tools
独自プロトコル。というか、ライブラリレベル。 けっこうきっちりとまとまっているように思えるが、 最大の難点は ARM7 をサポートしてないことであろう。いやぁ、まったく盲点だった。
GDB ICE
パラレルケーブルの I/F だが Wiggler とは微妙に異なり、Wiggler で使うにはソースの修正が少しだけ要る。 独自プロトコル、というほどのものはなく、レジスタとかを 100ms毎でひたすらテキストでダンプしつづけるだけ。こんな感じで:
#./tp_003 
IDCODE=3F0F0F0F
IceB Debug Control = 0x00000000  Status = 0x00000014
IceB Debug Control = 0x00000000  Status = 0x00000009
READ MEMORY AT 0x00000000:
e59ff018  e59ff018  e59ff018  e59ff018  e59ff018  e1a00000  e59ff014  e59ff014  
0000003c  00000738  000006f8  00000778  000007ac  00000678  000006b8  e3a00102  
e1a0c7c0  e3a00000  e58c0008  e10f0000  e200001f  e2500013  0a000001  e3a00004  
e5cc0230  e1a00000  e59f00d0  e3a01001  e5801404  e3a01000  e5801408  e3a010f4  
e580140c  eb00007f  e28fa008  e89a003f  e880003e  ea000005  fffff400  00001000  
00000000  00000000  00000000  00000000  e3a00b47  e321f0db  e1a0d000  e2400004  
e321f0d7  e1a0d000  e2400004  e321f0d1  e1a0d000  e2400080  e321f0d2  e1a0d000  
e2400080  e321f0d3  e1a0d000  e2400004  e321f010  e1a0d000  e24dab01  e59f1040  
e59f2040  e59f3040  e1520003  34910004  34820004  3afffffb  e3a00000  e59f102c  
e59f202c  e1510002  34810004  3afffffc  e59fe020  e59f0020  e12fff10  eafffffe  
ffff0000  00001078  00010000  00010000  00010000  000100e4  0000013c  000005d5  
e92d4030  e3e03cff  e51320fb  e3120004  e59fe088  e59f4088  0a00001e  e59e1000  

Program halted by user debug request: NO, is a breakpoint/watchpoint
BREAK/WATCH: BREAKPOINT
Register contents:
000005D5  00010010  FFFFF460  00000160  00000000  00000000  FFFF0000  00000000  00000000  00000000  000116F4  00011B70  00011B74  00011B50  000006A8  00000160  CPSR    = 0x20000092
IceB Debug Control = 0x00000000  Status = 0x00000004
IceB Debug Control = 0x00000000  Status = 0x00000019
...
本来 gdb と繋がる予定だったとこが名前から窺えるが、そこまで実装されてない。
基本中の基本しか実装されてないが、必要なものはすべてそろってる上に やってることは何気に jtager より高度である。もっともやっかいな PC の調整とレジスタの非破壊読み書きが きっちり出来てる。 さらにソースもバイナリもとっても小さい。自前で拡張するのによさげ。

... コード全体が小さすぎて -O3 するとコード全部を loop-unroll してくださってとっても大きくなる(26kB)。 -O2 までに留めるべきで、この時で 10kB 弱。やー、ちょっとびっくりした。

JTAGER
独自プロトコル。自前のコンソールをもつ:
#./jtager
*** Welcome to JTAGER-0.3.0 ......
*** Copyright (C) 2003-2004, Rongkai Zhan 

JTAGER is a free software, covered by the GNU General Public License, and you
are welcome to change it and/or distributecopies of it under certain conditions.
There is absolutely no warranty for JTAGER.

You can type 'help' command to get a list of all commands. You aslo can
type 'help ' command to get a verbose information about the command.
All commands are case-insensitive, and has GNU-style long command options.

Using parallel data port and status port -- 0x378 and 0x379
Jtag interface has been reset successfully!
target core type: ARM7TDMI
JTAGER:> halt
Requesting HALT target ... [OK]
The target is halted in THUMB mode.
JTAGER:> memdump --base=0x00080000 --size=16
00080000: E59FF018 E59FF018  E59FF018 E59FF018              |................|
00080010: E59FF018 E1A00000  E59FF014 E59FF014              |................|
00080020: 0000003C 00000738  000006F8 00000778              |<...8.......x...|
00080030: 000007AC 00000678  000006B8 E3A00102              |....x...........|
JTAGER:> reg
R0 = 0x0008005C         R1 = 0xE3A00102         R2 = 0xE1A0C7C0
R3 = 0xE3A00000         R4 = 0xE58C0008         R5 = 0xE10F0000
R6 = 0xE200001F         R7 = 0xE2500013         R8 = 0x0A000001
R9 = 0x00000000         R10 = 0x000116F4        R11 = 0x00000000
R12 = 0xFFFF0000        R13 = 0x00011B78        R14 = 0x061A0030
R15 = 0x00000330        PC = 0x00000330         CPSR = 0x40000092
SPSR = 0x40000010       
JTAGER:> 
ice (EmbeddedICE レジスタ操作)、reg (レジスタ操作)、memdump/memset (メモリ操作)、halt/restart (停止/再実行) と一通りそろっているので EmbeddedICE の動きの理解に良い。 ただ THUMB モードはサポートしていない。停止だけはできるんだけど。 あ、上のサンプルは THUMB サポートを実装したあとのもんで、本来は reg とかやっても「使えんよ」って返事がかえってくる。
また、memdump や restart などのコマンドがレジスタを保存するように出来てないので jtager 自身を ICE なデバッガとして使うことはできない。

ちゃんと言うと restart 時に R0 は reg で表示されてる値になっておらず、PC と同内容で上書きされている。つまり:

ldr r0, 再実行アドレス
mov pc, r0
的な動作をしている。

PC へのロードはレジスタからにしないと実行アドレスが激しくずれるので、これを直すのはけっこう神経を使う。 このあたりを直すつもりならいっそ gdbice のコードをまるごともってきたほうが良いと思う。
本来 flash メモリへの書き込み用ということもあるだろうが ... flash に書き込んだあとはリセットするだけだからレジスタの保管といった類の しちめんどくさい作業は要らないし。

今回使ったのはこの jtager で、もうすこし早く file の存在を知ってたら openocd にしてたかもしれないし、 ある程度 ARM の EmbeddedICE を理解した今なら gdbice を選択するだろうが、 上位プログラムなしに手でメモリダンプしてみたり EmbeddedICE レジスタを叩いたりできる jtager なしには どーせ何にもできない。

要するに、jtag を操るプログラム自身のデバッグには jtager が必要なのであって、 こいつに THUMB サポート突っ込んでしまったあとは いちいち他のプログラムを読むまでもなく jtager の細工に走ったのは当然の成行きというやつである。

Wiggler clone ケーブル

作った。
cable 1 cable 2
一つめは昔の XiLINX 用パラレルケーブルのピン配置を ARM 用に適当に入れ換えたもの。 「回路図書かないヨカン」などと書いて本気でほったらかしにしておいて 3 年ぶりに回路図書き起こしたのはここで使うためだというのはあっちでは秘密だ。
Wiggler とはコンパチでもなんでもないが、openocd や h-jtag など OCDRemote 以外では動く。 XiLINX ケーブルには TCK,TDI,TDO,TMS の 4 本だけで (Wiggler にはある) TRST の配線がないが、 ADuC7026 のほうが通常は TRST をサポートしてないから Wiggler でも XiLINXパラレルケーブルでもどーせおんなじ。 残る SRST は XiLINX ケーブルにも Wiggler にも、さらに今回の ADUC7026 基板にもないからおーるおっけー。

二つめのは OCDRemote での動作を見るためと、jtag の reset 動作を確実にするために nTRST や nSRST を配線したもの (このあたり、いかに reset に苦労していたか窺える;_;)。 Wiggler というよりは (TRST, SRST 両方の配線のある) Olimex の ARM-JTAG に近い: 回路図

コメントいくつか。

Wiggler variations
Wiggler clone とよく一つにまとめられるが、TRST、SRST の扱いでいくらかの変種が存在する。

nTRST nSRST
Wiggler not D0 nTRST or NC
ARM-JTAG not D0 D4
K9JTAG D4 not D0
jtag-arm9 NC not D0
buici not D0 NC
hri not D0 NC
ARM9 用では ARM7 用で TRST に配線していた D0 を SRST に配線するようになったんかね。
しかしまぁ、本気でどーでもいいんだな > TRST, SRST の配線。
配線必須ならバラけるはずがない。
SRAM の内容保持
パラレルポートから VHC244 を通り抜けさらに JTAG ポートやらなんやらに供給される 5V 電位が回り回って ADuC7026 の Vcc に 0.6V ほどの電圧を与え、 こいつのおかげで基板に供給する電源のスイッチを切っても CPU 内の RAM の内容が消えない。

ADuC7026 の根性を褒めるべきなんだろうが RAM の16 進ダンプ見つめても直したコードかバグってる旧コード(つまり新コードのロード失敗)かなんて分からんので けっこう邪魔であった。 なるほど世のケーブルのいくつかはケーブル切断時に /OE を上げ、積極的に各ピンを 0V に固定しているわけである。 次に作る時はそうしよう。

どんな風に桶屋がもうかってんのかは調べてないから不明。まあ可能性のあるルートは のきなみ抵抗が入ってるので突入電流で壊れるってことはなかろ。

ダウンローダ

冒頭でターゲットを初期化し、 書き込みルーチンなど幾つかのコードをターゲットに送り込んだあとはオプションに従って仕事する以上の内容はない。 使い方はこんなもんで。
[usage] jtal [-r] [-w] [-v] [-s] [-t] [-d] [-f hexfile] [< hexfile]
-r
Intex HEX format のファームイメージを受け取る。
-f
ファームイメージ名を指定する。指定しない場合は stdin から受け取る。
-w
フラッシュに書く。入力ファイルが無い場合は全データが 0xff とみなす(単に消去する)。
-v
フラッシュの内容をベリファイする。 入力ファイルが無い場合は全データが 0xff とみなす(消去されているかどうかを検証する)。 また -v -v と重ねると 1 ページ処理するごとに "*" とか "O" とかのインジケータを出す。
-t
物事のついでに転送速度の測定。
-s
一通り終ったあとターゲットをリセットしない。JTAG による halt モードのまま抜ける。
-d
一通り終ったあと jtager コンソールに移行する。-r と同時に使う場合は -f も指定すべきである。
-h
ヘルプメッセージを出す。
おぼえがきいくつか。

書いてみた:

# ./jtal -r -w -t  < DAC_thumb.hex  
Using parallel data port and status port -- 0x378 and 0x379
Jtag interface has been reset successfully!
target core type: ARM7TDMI
Requesting HALT target ... [OK]
The target is halted in ARM mode.

Setup time 162.776000 ms
Transfer rate 4.093544 kB/s  (1125.675000 ms)
Jtag interface has been reset successfully!
#
続いてフラッシュ全体を消去:
./jtal  -w -v -t 
Using parallel data port and status port -- 0x378 and 0x379
Jtag interface has been reset successfully!
target core type: ARM7TDMI
Requesting HALT target ... [OK]
The target is halted in THUMB mode.
OK, the flashrom is erased completely.

Setup time 162.804000 ms
Transfer rate 5.599897 kB/s  (11337.351000 ms)
Jtag interface has been reset successfully!
#
も一回書き込む。こんどは書き込み後にベリファイ:
#./jtal -r -w -v -t -f DAC2_thumb.hex   
Using parallel data port and status port -- 0x378 and 0x379
Jtag interface has been reset successfully!
target core type: ARM7TDMI
Requesting HALT target ... [OK]
The target is halted in ARM mode.
OK, new firmware is loaded.

Setup time 167.933000 ms
Transfer rate 2.744406 kB/s  (1679.052000 ms)
Jtag interface has been reset successfully!
#

ソース

ビルド

まだ ./configure && make 一発まで整理つかず。作るだけならば:
% zcat jtager-0.3.0.tar.gz |tar -xv
% cd jtager-0.3.0
% zcat ../jtal-0.3.0-k1.diff.gz | patch -p1
% ./configure
% make
% cd src
% cp jtager jtal

ターゲット内コマンド用ファーム src/target/arm7tdmi/*.s をいじった場合は:

% cd src/target/arm7tdmi
% cc ihex2struct -o ihex2struct
% ./s2h setup_pll
% ./s2h write_page
% ./s2h erase_page
% ./s2h reset
% ./s2h feeack
% cd ../..
% make
現状、*.s を変えても make は見てない。すまん。

References


[日記へ] [目次へ]