Help us understand the problem. What is going on with this article?

TangPrimer(RISC-V)をArduinoIDEで開発する・・・OpenOCDの再コンパイル対応方法

TangPrimer(RISC-V)を

ArduinoIDEで

プログラム開発する

はじめに

SipeedからTangPrimerというRISC-V対応の格安FPGA基板が売り出されています。日本では秋月電子(http://akizukidenshi.com/catalog/g/gM-14786/)やShigezone(https://www.shigezone.com/?product=tang-primer)などから2,000円くらいで入手する事ができます。さっそく飛びつくように購入しました。

使い方に関してはSipeed社のTangPrimerに関するサイト(https://tang.sipeed.com/en/)にてFPGAへのVerilog記述論理合成書き込みまでは簡単に実行する事ができました。

しかし、目玉であるRISC-V(LicheeTang E203Core https://github.com/Lichee-Pi/Tang_E203_Mini )については、論理合成しFPGAへ書き込んだまでは良かったのですがRVデバッカを使用してFlashROMにソフトプログラムを書き込もうとしても、以下の様な不具合によって書く事が出来ませんでした。。

  • 購入したTangPrimerに実装されているFlashROMが、準備されていたOpenOCDに対応していない。デバイスIDエラーとなる。

  • 準備されているE203_Miniプロジェクトを論理合成したバイナリファイルではOpenOCDが動作しない。

今回、OpenOCDの対策調査の過程で『TangPrimerをArduino IDEでプログラム開発する』方法を見つけました。Sipeed社の手順ではRISC-VプログラミングにはLinux環境が必要なのですが、Arduino IDE対応によって全ての作業がWindowsベースで行えます。Linux環境の準備が面倒な方には朗報(?)になると思いますので、私が行ったOpenOCDの対応方法と共に以下に紹介させて頂きます。

1、開発環境の準備

写真にはUSBマイクロBケーブルは写ってません。また写真ではRVデバッガとPCを接続するUSB中継ケーブルを使用しています。

  • ArduinnoIDEを入手しインストールします(詳細については割愛させて頂きます「Arduino インストール」等で検索してください)。

 私の環境では、Arduino IDE Ver.1.8.12を使用ししています。

2、RVデバッガドライバーをインストールします。

ドライバは以下からダウンロードできます。

https://bigbits.oss-cn-qingdao.aliyuncs.com/Arduino_for_Licheetang_with_hbird_e203_mini/Driver/HBird_Driver.exe

  • RVデバッガをUSBポートに挿します。

ダウンロードした「HBird_Driver.exe」を実行します。

http://kume4618.world.coocan.jp/OpenOCD/picture/2_RVdb1.png

 「次へ」を押します。

http://kume4618.world.coocan.jp/OpenOCD/picture/3_RVdb2.png

 「完了」を押します。

http://kume4618.world.coocan.jp/OpenOCD/picture/4_RVdb3.png

上図のように、ドライバが二つインストールされていればOKです。

3、ArduinoIDEを起動して

TangPrimer開発環境をインストールします。

  • 「ファイル」→「環境設定」→「追加のボードマネージャのURL」に下記のURLを追加します。
 https://bigbits.oss-cn-qingdao.aliyuncs.com/Arduino_for_Licheetang_with_hbird_e203_mini/v0_1/package_licheetang_index.json

 追加する際は、「,」(カンマ)で前のURL記述とつなぎます。

http://kume4618.world.coocan.jp/OpenOCD/picture/5_Arduino1.png

  • ボードマネージャにLicheeTang HBird E203 Boardをインストールします。

「ツール」→「ボード」→「ボードマネージャ」(プルダウンメニューの上部)を選択すると下記のウィンドーが表示されるので、「LicheeTang」で検索

http://kume4618.world.coocan.jp/OpenOCD/picture/6_Arduino.png

ここで、「LicheeTang・・・」が表示されないときは、前述の「追加のボードマネージャのURL」への記述に問題がありますので確認してください。

  • 「LicheeTang HBird Board」を選択。

 「ツール」→「ボード」で表示されるプルダウンメニューから「LicheeTang HBird Board」を選択。

  • 書込装置に「LicheeTang OpenOCD」を選択。

  基本的には、ここまでの作業でTangPrimer(RISC-V)を開発出来るようになる筈です。

  しかし残念ながらOpenOCDのエラーによりコンパイルは出来てもFlashROMへの書き込みが出来ませんでした。

 注意:

  • 購入したTangPrimerのFPGAにはあらかじめRISC-V CPUが書き込まれております。もしTD(TangDynasty)で、RISC-Vプロジェクトの『Tang_E203_Mini』をダウンロードし論理合成しても、作成されたバイナリはFPGAに書き込まないでください。RVデバッガでの書き込みが出来なくなってしまいます。

 もし書き換えてしまった場合は、以下のサイトのバイナリファイルをダウンロードしてTDで書き込んでください。現時点でOpenOCD(対策後)の動作が確認できたのはこちらのファイルと、

https://dl.sipeed.com/TANG/Primer/SDK/LicheeTangNewIoMap_BitStream.bit

こちらのTDプロジェクトパッケージが使用可能です。特にverilogHDLで機能拡張したい場合は、下記のパッケージをTDで機能追加・編集・コンパイル・書き込みが可能です。

https://github.com/riktw/Tang_E203_Mini

また、Lichee-pi/Tang_E203_Miniを使用しても、下記の記載を修正すれば論理合成して、書き込み可能です。

project/e203egmini_new.sdc

project/e203egmini_new.sdc
9行目 create_clock -name clk_16M -period 62.5 [get_nets {CLKIN}]
→ 削除 #create_clock -name clk_16M -period 62.5 [get_nets {CLKIN}]←コメントアウト
追加 create_clock -name clk_16M -period 62.5 [get_nets {clk_16M}]
                              ^^^^^^^^^

ただし、TDのバージョンは4.6.3以降をご使用ください。

以下手順4にてOpenOCD対応方法を紹介させていただきますが、作り直したOpenOCDファイルを以下に保存しますので、手っ取り早くArduino IDEで動作させたい方はこちらを使用してみてください。

保存先URL https://github.com/Nanchite4618/LicheeTangOpenOCD

ダウンロードしたら、手順5の対応をしてください。

4、LicheeTang OpenOCDを再コンパイル

 デフォルトでインストールされているopenOCDは、現在入手可能なTangPrimerボードに実装されるFlashROM(XTX社製)に対応しておらずエラーとなりこのままでは書き込みができません。

このため、OpenOCDのソースをダウンロード、修正し再コンパイルする必要があります。

  • 先ずは開発環境となる、MSYS2(minGW)をインストールし、この環境を整えるところから行います。

 以下のURLからMSYS2のインストーラをダウンロードして下さい。

 (MSYS2のインストール初期設定は「Tech Blog」(https://blogs.osdn.jp/2018/01/30/msys2-mingw.html )さんを参考にさせていただきました。

  URL:http://www.msys2.org/

   64bit環境→msys2-x86_64-xxxxxxxx.exe

   32bit環境→msys2-i686-xxxxxxxx.exe      (xxxxxxxxはたぶん日付)

   それぞれ、インストーラを実行してMSYS2をインストールします。

・私の環境は64bitなので、64bit版のmsys2-x86_64-xxxxxxxx.exeを実行しました。

実行し終わると、スタートメニューには以下のようにMSYS2下に3つのショートカットが出来上がります。

http://kume4618.world.coocan.jp/OpenOCD/picture/7_MSYS2_1.png

64bit環境ではどれを使用しても問題ないようですが、私は64bit環境で作業を行いました。

  • 「MSYS2 MinGW 64bit」を実行します。以下の様なシェルウィンドーが起動します。

http://kume4618.world.coocan.jp/OpenOCD/picture/8_MSYS2_2.png

まず、パッケージャの準備をしていきます。

MSYS2には「ARCH Linux」由来のパッケージャ「pacman」が付属し、これを使用して色々なパッケージをインストールすることが出来ます。

始めに、パッケージデータベース一覧を最新のものにする処理を行います。

[パッケージデータベース更新コマンド]

pacman -Sy「Enter」

http://kume4618.world.coocan.jp/OpenOCD/picture/9_pacman1.png

 [パッケージをアップグレードするコマンド]

 pacman -Su「Enter」

http://kume4618.world.coocan.jp/OpenOCD/picture/10_pacman2.png

「インストールを行いますか?」の問いに対して、「Y」を押してから「Enter」をおします。

http://kume4618.world.coocan.jp/OpenOCD/picture/11_pacman3.png

途中で止まり、「terminate MSYS2 without returning to shell and check for updates again for example close your terminal window instead of calling exit 」と表示されシェルに戻れない状態となった場合は、

ウィンドー右上の「×」印をクリックし、ウィンドーを閉じて10秒程度待って下さい。「Processes are running insessiion:Close anuway?」というアラートウィンドーが表示されたら、「OK」をクリックして終了します。

そして、再度MSYS2を起動して、

pacman -Su「Enter」

を実行します。

終了後、再度「pacman -Su」「Enter」を実行し、「何も行うことがありません」と表示されることを確認します。

http://kume4618.world.coocan.jp/OpenOCD/picture/12_pacman4.png

* GCCのインストール

  ・mingw-w64-i686-toolchain : MinGWの32bit gccコンパイラ

  ・mingw-w64-x86_64-toolchain : MinGWの64bit gcc コンパイラ

 これらのうちのどちらかです。ご使用の環境からお選びください。

 私は「mingw-w64-x86_64-gcc」を選択しましたが、上記toolchainでないとコンパイルできない例もありましたので、tooolchainの方をインストールしてください。

 パッケージのインストールには「pacman」の「-S」オプションを使用します。

 pacman -S mingw-w64-x86_64-toolchain

http://kume4618.world.coocan.jp/OpenOCD/picture/13_too.lchain1.png

このまま「Enter」キーを押すと下図のようになります。

http://kume4618.world.coocan.jp/OpenOCD/picture/14_too.lchain2.png

上図に対して「Y」「Enter」を押します(インストール容量多いので要注意)。

インストールが終了したら、念のためgccの動作を確認しておきましょう。コマンドラインから

gcc –version「Enter」

http://kume4618.world.coocan.jp/OpenOCD/picture/15_gcc1.png

次に、libusbを導入します。コマンドラインから以下のコマンドを入力してください。このパッケージはopenOCD実行時に必要なライブラリを含んでいます。

pacman -S mingw-w64-x86_64-libusb「Enter」

http://kume4618.world.coocan.jp/OpenOCD/picture/16_libusb1.png

「インストールを行いますか?「Y/n」」に対して、「Y」を入力し「Enter」を押します。

上図ははlibusbの例で、このようにインストールが行われます。

同じようにmake、autoconf、automake、libtools、libftdi、gitも取ってきましょう。

pacman -S make autoconf  automake「Enter」
pacman -S libtool mingw-w64-x86_64-libftdi git
  • openOCDのコンパイル

 次に、openOCDのコンパイルを行います。コンパイラのバージョンが新しいせいか、途中でエラーが発生しますが、修正は簡単なので心配いりません。

 まず、適当な場所にディレクトリを作成します。

私の場合はPCの都合上「/d」に「/src/mk_openocd」を作成しました。

mkdir 「作成するディレクトリ名」「Enter」

この場所にワークディレクトリを作成した理由は、後の作業でエクスプローラでアクセスしやすい場所であるためです。

作成したら、そのディレクトリに移ります。

cd 「作成したディレクトリ名」「Enter」

 次にLicheeTang用のopenocdのソースを取ってきます。

URLは以下の通りです。

 https://github.com/Lichee-Pi/LicheeTang_openocd

 MSYS2では「git」が使用できるので以下のコマンドにより、ソース一式を取ってくることが出来ます。

重複しますが、この時にgitからファイルを受け取るディレクトリをWindowsのエクスプローラーから簡単に読める場所に展開することをお勧めします。

要するに、「~/」の直下等は避けた方が良いということです。

(ちなみにMSYS2の「~/」直下はWindowsから見ると、[MSYS64インストールフォルダ]/home/[各自名称]となります)

私の環境では「/d/src/mk_openocd」の下にダウンロードしました。

cd /d/src/src/mk_openocd「Enter」
git clone https://github.com/Lichee-Pi/LicheeTang_openocd.git「Enter」

http://kume4618.world.coocan.jp/OpenOCD/picture/16_opwnOCD_git1.png

「Enter」を押すと、ソースの取得が始まります。

http://kume4618.world.coocan.jp/OpenOCD/picture/17_opwnOCD_git2.png

 取得したソースのフォルダに移動します。

cd LicheeTang_openocd「Enter」

以下、このフォルダで作業を行います。

 次に、「configure」スクリプトを作成するため、以下のコマンドを実行します。

./bootstrap「Enter」

http://kume4618.world.coocan.jp/OpenOCD/picture/18_bootstrap.png

終了すると、下記のメッセージが表示されます。

http://kume4618.world.coocan.jp/OpenOCD/picture/19_bootstrap2.png

次に、「./conigure --enable-ftdi」「Enter」と入力して、「Makefile」を作成します。

./conigure --enable-ftdi「Enter」

http://kume4618.world.coocan.jp/OpenOCD/picture/20_configure1.png

PCの処理能力にもよりますが、自宅PC(corei5 8000番台)3~5分程度かかります。

ゆっくり待ちましょう。

http://kume4618.world.coocan.jp/OpenOCD/picture/21_configure2.png

最終的に上図の様な表示がなされ、シェルに戻ってきたら終了です。

次はいよいよopenocdのコンパイルですが、その前に大切なおまじないをする必要があります。

  • XTX FlashROMのデバイスIDを追加する作業が必要です。以下の通りに行います。

「LicheeTang_openocd/src/flash/nor/spi.c」をご使用のエディタで開いてください。

http://kume4618.world.coocan.jp/OpenOCD/picture/22_spi1.png

上図の通り「spi.c」の最下行付近(下の方でなくても良いかと思いますが分かりやすくするため)に以下の行を付け加えます。

これは、XTX FlashデバイスのデバイスIDや、各コマンド、セクタサイズ等が記されているものです。

FLASH_ID("xtx xt25f08", 0xd8, 0xc7, 0x0014400b, 0x100, 0x10000, 0x100000),

この行を追加することで、XTX Flashデバイスへの書き込みが可能となります。

  • openocdのコンパイル

 次にopenocdのコンパイルです。

コンパイルには以下のコマンドを入力します。

make「Enter」

http://kume4618.world.coocan.jp/OpenOCD/picture/23_make1.png

「Enter」キーを押すと、コンパイルが始まります。

これも非常に時間がかかるので、気長に待ちますが、途中エラーが発生してコンパイルが停止します。

「make」「Enter」とすると、以下の様な表示が次々と現れてきます。

http://kume4618.world.coocan.jp/OpenOCD/picture/24_make2.png

http://kume4618.world.coocan.jp/OpenOCD/picture/25_make3.png

早速エラーが出てコンパイルが停止しました。

要するに、「/d/src/mk_openocd/LicheeTang_openocd/src/jtag/drivers/libjaylink/libjaylink/../config.h」の83行目でマクロ「__USE_MINGW_ANSI_STDIO」が再定義されてますよ、という内容です。

ですので、よくご使用のエディターでファイルを開き、その部分を以下のように修正します。

修正前:

http://kume4618.world.coocan.jp/OpenOCD/picture/26_libjaylink1.png

修正後:

http://kume4618.world.coocan.jp/OpenOCD/picture/27_libjaylink2.png

エディタで修正・セーブしたら、再度「make」を実行します。

また、ディレクトリはWindowsのエクスプローラからも見えますので、Windowsのエディタも使用可能です。

http://kume4618.world.coocan.jp/OpenOCD/picture/28_libjaylink3.png

http://kume4618.world.coocan.jp/OpenOCD/picture/29_libjaylink4.png

私の場合はvi(gvim)を使用していますので、こんな感じになります。

では、「make」を再開します。

http://kume4618.world.coocan.jp/OpenOCD/picture/30_make4.png

暫くする再度コンパイルがエラーで停止します。

http://kume4618.world.coocan.jp/OpenOCD/picture/31_make5.png

スクリーンショットの画面で赤表示されている部分です。

該当のファイル「LicheeTang_openocd/src/flash/mflash.c」をとりあえず開いてみましょう。

結果から言うと、エラーのあった1162行目の矢印で示している部分を190→186に修正すればコンパイルは通るようになります。

「修正前」

http://kume4618.world.coocan.jp/OpenOCD/picture/32_mflash1.png

「修正後」

http://kume4618.world.coocan.jp/OpenOCD/picture/33_mflash2.png

この理由を少しお話しすると、単純にこの構造体の「reserved7」メンバのサイズが186Byteであるからです。宣言されているサイズ以上のデータを入れようとしていたため、エラーが発生しました。それにしても、このようなケースでエラー発生してバグを教えてくれる最近のgccはすごいですね。

では、コンパイルを再開します。

make「Enter」

しかしまた、コンパイルエラーが出ます。

また停止します。

http://kume4618.world.coocan.jp/OpenOCD/picture/34_make6.png

今度は、

「src/flash/nor/psoc5lp.c」の237行目です。

http://kume4618.world.coocan.jp/OpenOCD/picture/35_psoc5lp1.png

エラーメッセージ見ると、恐らく、NULL文字含めると3文字をコピーすることになるのですが、それを2文字しか指定されてないという意味になるかと思ってます(直訳は違います)。

http://kume4618.world.coocan.jp/OpenOCD/picture/36_psoc5lp2.png

これを下図のように修正します。

http://kume4618.world.coocan.jp/OpenOCD/picture/37_psoc5lp3.png

さらにさらにエラーは出ます。

http://kume4618.world.coocan.jp/OpenOCD/picture/38_make7.png

今度は「src/target/riscv/riscv-011.c」の1800行目です。

修正箇所は1687行目を以下のように修正します。

「修正前」

unsigned int reg;

    ↓

「修正後」

unsigned int reg = 0;

http://kume4618.world.coocan.jp/OpenOCD/picture/39_riscv-011_1.png

http://kume4618.world.coocan.jp/OpenOCD/picture/40_riscv-011_2.png

変数「reg」が初期化されずに関数の引数として渡されているというのです。

実際には直下のswitch文で色々な値が書き込まれていますが、default文に変数regへの記載がないため、このようなエラーが発生したのでしょう。

http://kume4618.world.coocan.jp/OpenOCD/picture/41_riscv-011_3.png

エラー修正はこれで終わりかと思います。

では、先に進めます。

make「Enter」

を実行します。

http://kume4618.world.coocan.jp/OpenOCD/picture/42_make8.png

このように、シェルに戻ってきたら終了です。

お疲れさまでした。

5、OpenOCDの置き換えと、ArduinoIDEを使用したTangPrimer基板へのプログラム書き込み

  • バイナリのコピー

 あとは出来上がったバイナリと「libusb-1.0.dll」をArduinoのopenocdが格納されているフォルダにコピーすれば作業は終了です。

上書きコピーでも問題ありませんが、念のため現在のopenocd.exeを名称変更しておきました。

フォルダは下記の場所にあります。

「C:\Users\[各自名称]\AppData\Local\Arduino15\packages\licheetang\tools\openocd\a1\bin」

エクスプローラで上記フォルダに移動し、「openocd.exe」を適当な名前に変更します。

http://kume4618.world.coocan.jp/OpenOCD/picture/43_openocd1.png

「openocd.exe」を「org-openocd.exe」へ名称変更しました。

新しく出来上がった「openocd.exe」を上記フォルダにコピーします。

新しくできた「openocd.exe」は、「LicheeTang_openocd/src」にあります。

http://kume4618.world.coocan.jp/OpenOCD/picture/44_openocd2.png

WindowsのエクスプローラーでArduinoのopenocdフォルダへコピーします。

http://kume4618.world.coocan.jp/OpenOCD/picture/45_openocd3.png

「libusb-1.0.dll」をArduinoのopenocdフォルダへコピーします。

http://kume4618.world.coocan.jp/OpenOCD/picture/46_libusb1.png

ArduinoIDEを使用してコンパイル・書き込みを行います

・ArduinoIDEを起動します。

下図のように

  ボードに「LicheeTang Hbird E203 Board」が選ばれ、

  書込装置に「LicheeTangOpenOCD」が

選ばれていることを確認します。

http://kume4618.world.coocan.jp/OpenOCD/picture/47_Arduino1.png

 私はソースをBigBitさんのサイトに書かれているものを利用させてもらいました(スケッチ例に記載されているソースは動作しませんでした)。

コンパイル・書き込みも終了すると、画面は下図のようになり、カラーLEDが1秒間隔づつ赤、緑、青の順で点滅すれば完成です。

http://kume4618.world.coocan.jp/OpenOCD/picture/48_Arduino2.png

Arduino IDEにおけるピンマップについては以下となります。

(BigBitさんのサイトでは、一部記載ミスがありました)

LEDピンは出力動作、他各ピンの入出力動作が確認ができました。

http://kume4618.world.coocan.jp/OpenOCD/picture/49_PinAssign.png

6、まとめ

・一通り、ArduinoIDEを使ってのTangPrimer基板への書き込みが出来る状態にまでの工程を説明させてもらいました。正直なところ、ここまで来るのには簡単な道筋ではありませんでした。仲間がいなければ到底こんなことできなかったし、先ずしようとも思わなかったでしょう。この場をお借りしてお礼を申し上げます。

7、今回参考にしたWebサイト

謝辞:参考にさせていただいたサイト皆様からの情報はとても有用で大変勉強になりました。

AutomakeやAutoconfの使用方法、MSYSでのパッケージ運用等この作業をする前は全く知りませんでした。また、何といってもBigBitさんのサイトに巡り合わなければ、この作業をすることもなかったでしょう。ありがとうございます。

また、重ね重ねになりますが、この作業の発端となったプロジェクトの立ち上げと勧誘、作業を文章で残そうと提案してもらったS氏、XTXのデバイスID関連の知恵を下さったW氏がいなければ、このような事になるには至らなかったでしょう。

本当に皆様ありがとうございます。

Tang Primer Docs

https://tang.sipeed.com/en/

RISC-V低成本体验——使用Arduino开发蜂鸟E203程序

https://blog.csdn.net/u013507936/article/details/86737964

OpenOCD動作が確認できているFPGAバイナリファイル

https://dl.sipeed.com/TANG/Primer/SDK/LicheeTangNewIoMap_BitStream.bit

LicheeTang E203Core

https://github.com/Lichee-Pi/Tang_E203_Mini

HBird_Driver.exeのバイナリファイル

https://bigbits.oss-cn-qingdao.aliyuncs.com/Arduino_for_Licheetang_with_hbird_e203_mini/Driver/HBird_Driver.exe

Arduinoの追加ボードマネージャのURL

https://bigbits.oss-cn-qingdao.aliyuncs.com/Arduino_for_Licheetang_with_hbird_e203_mini/v0_1/package_licheetang_index.json

MSYS2のインストール初期設定「Tech Blog」さんのURL

https://blogs.osdn.jp/2018/01/30/msys2-mingw.html

MSYS2さんのURL 

http://www.msys2.org/

LicheeTang用のopenocdのソース

https://github.com/Lichee-Pi/LicheeTang_openocd

Automakeでmakeする

http://www.02.246.ne.jp/~torutk/cxx/automake/automake.html

Autotoolsを使ってプロジェクトのMakefileを生成する @kagemikuさん

https://qiita.com/kagemiku/items/5aed05f7bd70d8035f54

LicheeTang_OpenOCDのソース

https://github.com/Lichee-Pi/LicheeTang_openocd.git

mingw-w64-x86_64-libusbライセンス調査

https://repology.org/project/libusb/packages

easy labo LGPL調査

http://easylabo.com/2015/04/rapid-prototyping/9048/

以上です。

Nanchite4618
Qiita初心者です。お手柔らかに。
https://ameblo.jp/nanchite4618/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away