なひたふは、「Cosmo-Z」というZYNQ7030搭載のADCボードを作っているのですが、FSBLが起動しなくて約一週間も悩んでいました。
ZedBoardやMicroZEDなど、XILINXが全面的に協力しているボードなら簡単なことなのでしょうが、自作したボードでFSBLを起動することが、こんなに困難だとは思いもしませんでした。
そして今日ついにFSBLが安定して起動するようになりました。長かった・・
この1週間、ずっとFSBLをSDKでステップ実行したり、いろいろな部品を取り換えたりして試行錯誤していました。そんなFSBLが動かない場合の対処法を紹介します。
① QSPI ROMからのFSBL起動は難易度が高い。迷わずSDカードを選択せよ!
ZYNQは、NOR型フラッシュ、NANDフラッシュ、QSPI、SDカードなどから起動できます。
しかし、QSPIから起動できるとはいうものの、SPIモードではなく、必ずQSPIモードでのアクセスとなります。しかも、QSPIモードはROMベンダによって規格が微妙に異なるので、ZYNQで使えるSPI ROMの品種は非常に限られています。
例えば、MicronやNumonyx、SSTなどのSPI ROMは使えないようです。
SPIモードではアクセスできないので、結局のところ、1品種か2品種くらいしか該当品がありません。しかも入手困難です。あきらめて、SDカードブートにしたほうがよいでしょう。
② FSBL自体は読み込まれているか?
ZYNQの中のBOOTROMはSDカード内のBOOT.BINを読み出して実行します。FSBLは同じくBOOT.BINを読み出します。
一度目の、BOOTROMが読み出すBOOT.BINはたいてい成功しています。しかし、FSBLが読み出すBOOT.BINで失敗することがよくあります。
その理由は、
- カード検出信号が検出されていない
- SDIOのクロックの設定が速すぎる(?)
- IO電圧の設定が間違っている ※オシロで見ると信号が出てこない
です。つまり、FSBLが起動していないと思っても、実はFSBL自体は起動しているけど、二度目のBOOT.BINの読み出しで失敗しているということが結構あります。
③ FSBLのデバッグオプションをONにする
FSBLには様々なデバッグメッセージをUARTに出力するコードがあります。これを有効にするには、fsbl_debug.hに
#define FSBL_DEBUG_INFO
を追加すればいいのですが、それだけではうまくいかないことが多々あります。
そんな場合は、SDKでHelloWorld.cなど適当なアプリを生成して、その中にあるplatform_config.hと、platform.cと、platform.hを持ってきます。
そして、main.cで、先頭の#includeのところに、
#include "platform.h"
を追加します。
それから、main()の中のSlcrUnlock();の後に
init_platform();
を追加します。
fsbl_debug.hの、fsbl_printfのマクロ定義を
#define fsbl_printf(type, ...) \
{xil_printf (__VA_ARGS__); }
に変えます。
これで確実にデバッグメッセージをUARTに出力できるようになります。
TeraTermなどで見ると、起動に失敗したときにこんなメッセージが出ると思います。
Xilinx First Stage Boot Loader
Release 14.5/2013.1 Aug 17 2014-22:39:33
Devcfg driver initialized
Silicon Version 3.1
Boot mode is SD
SD: rc= 0
send_cmd: Error: (0x00038000) cmd: 0 arg: 0x0
send_cmd: Error: (0x00038000) cmd: 8 arg: 0x1AA
send_cmd: Error: (0x00038000) cmd: 55 arg: 0x0
send_cmd: Error: (0x00038000) cmd: 41 arg: 0x40300000
SD: Unable to open file BOOT.BIN: 3
SD_INIT_FAIL
FSBL Status = 0xA011
④ カードはDETECTされているか?
FSBL自体は起動したものの、FSBLがBOOT.BINを読んでくれない場合、No SD card presentとなってしまいます。
Xilinx First Stage Boot Loader
Release 14.5/2013.1 Aug 17 2014-22:39:33
Devcfg driver initialized
Silicon Version 3.1
Boot mode is SD
SD: rc= 0
No SD card present.
SD: Unable to open file BOOT.BIN: 3
SD_INIT_FAIL
FSBL Status = 0xA011
こうなる原因は、CD信号とWP信号がただしく読み出せていないためです。CDとWPは、カード検出と、ライトプロテクトの意味です。これらの信号がLレベルになっていないと、FSBLは正しく動作しません。
CDとWPは、SDカードが挿入されるとスイッチでGNDに接続されるピンなのですが、Cosmo-Zでは、CDとWPピンに直列に1kΩの抵抗を入れていました。すると、カードが挿入された状態で、信号線はほぼ0Vで、TTLレベルで見てもCMOSレベルで見ても明らかに0Vなのですが、ZYNQのFSBLはLと認識してくれません。
一方、ZedBoardでは、直列抵抗は499Ωです。
この抵抗が1kΩだとダメで、499Ω以下だと認識されます。オシロで見てもLレベルなので区別はつきませんが、ZYNQのソフトウェアは区別しています。
微妙ですね。
⑤ BOOTROMとFSBLではSDカードのアクセス方法が違うことに注意せよ
ZYNQは起動すると、内部にあるユーザから見えないROM「BOOTROM」から起動します。
このBOOTROMと、FSBLでは、SDカードのアクセスの方法が異なります。
◆BOOTROM
- ZED Boardで使われているようなES品のZYNQでは、1bitモードでSDカードにアクセスする。
- ZED Boardで使われているES品のZYNQでは、MIO0をCD(カード検出信号)として扱う
- 最近のプロダクション版ZYNQでは、4bitモードでアクセスする
- 最近のプロダクション版ZYNQでは、MIO47をCDとする
◆FSBL
- 4bit モードでSDカードにアクセスする
- CDとWPの割り当ては、ps7_init.cで設定されている。つまり、EDKで設定したMIOの任意のポートに割り当てられる
⑥ CDとWPピンは設定したか?
EDKでSDカードを有効にしても、デフォルトではCDとWPのピンが割り当てられていないので、FSBLはSDカードを認識しません。
この割り当てを設定するために0xF8000830番地のレジスタを直接操作すること
*(volatile unsigned long *)0xf8000830 = 0x002f002e;
のようなことを紹介するページもあるのですが、実は、そんなことはしなくても大丈夫です。EDKのPS設定画面で、SD0の設定を開き、CDとWPを然るべきMIOピンに割り当てます。
ZEDと同じ(ZYNQの標準)にするなら、CD=MIO47、WP=MIO46にします。
これで、上のコードと同じことが初期化ルーチン(ps7_init.c)内で安全に行われるようになります。
⑦ SDIOのクロックは50MHzにする
デフォルトでは125MHzになっているようなので50MHzにします。どんな周波数の範囲ならOKなのかはわかりませんが、50MHzにしておきます。
⑧ EDKでIOピンの設定を1.8Vにしたか?
PSの設定で、I/Oの電圧を設定するところがあります。これはShow I/O Standard Optionsをチェックしないと出てきません。
このチェックを入れて、Bank0とBank1の電圧を適切に設定します。
デフォルトでは3.3Vになっていますが、実際のボードが1.8Vだと信号が出てこないようです。
この設定が見つけられず、3日間くらい悩みました。これを確実に設定してください。
以上の設定で、ちゃんとFSBLはBOOT.BINを読み込んでくれるようになると思います。
まとめ
FSBLが動かない場合は
① デバッグを有効にして、No SD card presentと出ていれば、CDとWPの確認をする
② CD(MIO47)とWP(MIO46)の割り当てが正しければ、SDカードのSW端子でGNDへ引っ張る直列抵抗を確認する
③ SDIOクロックは50MHzになっているか確認する
④ I/O電圧は1.8Vになっているか確認する
これでちゃんと起動するようになると思います。
この記事が自作派ZYNQerの皆様のお役に立てば幸いです。
最近のコメント