背景
前回、freedom-e-sdkをqemuで動かすことはできたので、次は実際のボードで動かそうと思い、SiFive HiFive1 Rev.Bを購入しようと思ったところ、Shippingが2013/1/1以降になてしまうということがわかりました。HiFive1 Rev.Bは、ESP32も搭載されているし、SiFive FE310の標準環境といえるのでこれはこれで購入をかけたのですが、その後、NuttX contributorで有名なAlanからSparkFun RED-V Thing Plusを紹介され、すぐに発注してみたところちょうど1週間で届きました。
HiFive1 Rev.Bとの違い
回路図を見ていて気付いたんですが、ESP32が搭載されていない、RGB LEDが搭載されていない、ピンヘッダのアサインが違う、といった大きな違いはありますが、搭載されているCPUはSiFive FE310-0002で、USB-JTAG(J-Link + UART)はNXP MK22FN128、QSPI-Flashは32MbitとHiFive1 Rev.Bと同じでした。なので、SparkFun RED-Vが動かせるようになれば、HiFive1 Rev.Bはそのまま動かせるようになりそうです。
freedom-e-sdkをSparkFun RED-V向けにビルドする
freedom-e-sdk/bspにはSparkFun RED-Vが存在しませんが、HiFive1 Rev.Bと同じということがわかったので、HiFive1 Rev.B向けにビルドしてみます。
$ make software PROGRAM=hello TARGET=sifive-hifive1-revb
ちなみに、sifive-hifive1-revb向けにビルドしたhello.elfは、qemuだと動きません。これは、エントリーポイントアドレスが違うからです。sifive-hifive1-revb向けには、エントリーポイントアドレスは0x20010000になっています。
$ riscv64-unknown-elf-readelf -a software/hello/debug/hello.elf
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
...
Entry point address: 0x20010000
qemuで動かすためには、エントリーポイントアドレスが 0x20400000 でなければなりません。
USB-JTAGとの接続
MK22FNにはJ-Link向けのfirmwareが書かれているようなので、J-Linkを使う必要があります。今までopenocd + ftdiが長かったため、恥ずかしながらJ-Linkは初めてなんですが、gdb server以外にも色々とツールが揃っていて便利そうだということは知っていました。openocdもinterfaceとしてJ-Linkもサポートしているので、openocd + J-Linkという構成でも良いんですが、せっかくなので、J-Linkのツールを使ってみることにしました。J-Linkのソフトウェアは https://www.segger.com/downloads/jlink/#J-LinkSoftwareAndDocumentationPackBeta からダウンロードして、インストールしておきます(無料です)。
JLinkGDBServerの起動
筆者の環境はMacBook Pro 2018(macOS Catalina)で、VMware Fusion + Ubuntu 18.04 x86_64もインストールしていますが、今回はJLinkGDBServerをmacOSで動かしてみることにしました。まずは、SparkFun RED-VとMacBook Proをつなげます。ここで注意があります。SparkFun RED-VにはUSB type-Cコネクタがついていますが、これはあくまでコネクタとしてtype-Cを使っているだけなので、MacBook ProのThunderbolt 3(USB-C)に直接type-Cでつなげることができません。その代わり、USB Hubなどを介して、type-A to type-Cで接続する必要があります。ケーブルを接続したら、まずはJLinkConfigを立ち上げて、ボードが正しく認識していることを確認します。
ボードが正しく認識されていたら、JLinkGDBServerを起動すると、Target deviceやTarget interfaceの設定項目が現れます。ここで、Target deviceとしてSiFive FE310を選び、また、Target interfaceとしてJTAGを選んでおきます。OKを選択するとJLinkGDBServerが起動して、gdbからの接続待ちとなります(補足:コマンドライン版では、JLinkGDBServer -device FE310 でOKです)。ログにはポート番号(デフォルトは2331)が出ているので、gdbで接続する際には、このポート番号を指定します。
picocomでシリアルコンソールに繋ぐ
USBで繋ぐと、USB serial用のデバイスファイルも作られます。macOSの場合、/dev/usb.modemXXXXX というファイルが現れます。ターミナルプログラムとしては、僕がよく使っているpicocomを事前にbrewでinstallしておきます。このとき2つのデバイスファイルが作られますが、1つ目はFE310のUART1につながっており、2つ目は、恐らくHiFive1 Rev.BのESP32向けだと思います(SparkFun RED-Vではどこにもつながっていないです)。理由は起動メッセージをみるとわかります。
gdbからhello.elfを書き込む
JLinkGDBServerのポートアドレスがわかったので、あとは gdb から target extended-remote でポート番号を指定し、load hello.elf すれば JLinkGDBServer経由でSparkFun RED-V上のQSPI-Flash (4MB)に書き込むことができます。あとは、continueすれば、Hello, World!がシリアルコンソール上に出ます。