前回はexStickGE上でEthernetのIPコアと連携しechoサーバを動かしました.
今回はWebサーバ(HTTPサーバ)を動かしてみました.
FPGAのハードウェア部分は前回作成したのでそのまま使用します.
今回はソフトウェア側の作業です.
ソフトウェア側のプログラム
ソフトウェアはVitisを使用して作成しますが, ワークスペースも含め新規生成します.
Vitisを起動し新しくワークスペースを指定します.
今回はprjフォルダ以下vitis_websvとします.
初期画面が立ち上がったら左上のメニューバーから
File->New->Application Projectをクリック.
Nextをクリックし, xsaファイルを指定します.
Create a new platform from hardware(XSA)タブを選択し
Browseから以前生成したxsaファイルを選択, 次へ.
Application Project Detailsでプロジェクト名の指定をします.
今回はwebsvとしておきます.
次へ進みDomainでOSの指定ができますが, 今回はfreertos10_xilinxで実行します.
Templateで今回はFreeRTOS lwIP Echo Serverを選択し,
Finishでプロジェクトが生成されます.
テンプレートとしてFree RTOS lwIP Echo Serverを使用しましたが
後でソースコードは入れ替えます.
これで最低限のプロジェクトが生成されました.
ライブラリの設定
現状ではWebサーバを実現させるために必要なライブラリが
含まれていないので追加します.
左のExploererからtop_wrapper->platform.sprをダブルクリックで開きます.
表示されたウィンドウ内をたどっていくとBoard Support Packageの指定が
できるのでModify BSP Settings…をクリック.
Webサーバで返すコンテンツを格納するためのファイルシステムを実現する
xilffsにチェックを入れます.
ライブラリの設定をします.
まずはlwip211を選択.
temac_adapter_options->phy_link_speedを100Mbpsに設定.
次にxilffsを選択
fs_interfaceを2(RAM上にファイルシステムを展開)
use_lfnを1(8.3形式以外の形式に対応,詳しいことはFATやLFNで検索!)
ramfs_size->ramfs_start_addressを0x80000000
(0x80000000とramfs_sizeの3145728という数字は後々使うので覚えておきましょう)
以上でライブラリの設定は終わりです.
左下のAssistantからtop_wrapperを右クリックでBuildすれば
プラットフォームは完成です.
Webサーバのソースコード
ソースコードを追加します.
今回はXilinxが提供しているembeddedswを使用します.
適当な場所にダウンロードもしくはクローンします.
使用するのはThirdParty/sw_services/lwip211/examples以下のファイルです.
ワークスペース以下のwebsv/srcフォルダを開き3つのファイルを削除します.
- echo.c
- iic_phyreset.c
- main.c
その後以下のファイルをexamplesフォルダからコピーします.
- lwip_example_iic_phyreset.c
- lwip_example_platform_config.h
- freertos_lwip_example_ws_platform_fs.c
- freertos_lwip_example_web_utils.c
- freertos_lwip_example_ws_http_response.c
- freertos_lwip_example_webserver.c
- freertos_lwip_example_webserver.h
- freertos_lwip_example_ws_main.c
freertos_lwip_example_ws_main.cを開き
先頭に以下のインクルードの宣言を追記します.
#include "platform_config.h"
また, IPアドレスの設定項目があるので必要に応じて変更してください.
ビルド
ソースコードの準備ができたのでビルドをします.
左のAssistantからwebsv_systemを右クリックでBuildをクリック.
ただし今の状態だとコンパイルできてもリンクができず実行ファイルは生成されません…
エラー文は以下の通りで必要なメモリに対して用意されてるメモリが足りず
bss領域がオーバーフローしていることがわかります.
'Building target: websv.elf' 'Invoking: MicroBlaze gcc linker' mb-gcc -Wl,-T -Wl,../src/lscript.ld -LD:/exstickge_samples/exStickGE_microblaze/prj/vitis_websv/top_wrapper/export/top_wrapper/sw/top_wrapper/domain_microblaze_0/bsplib/lib -mlittle-endian -mcpu=v11.0 -mxl-soft-mul -Wl,--no-relax -Wl,--gc-sections -o "websv.elf" ./src/freertos_lwip_example_web_utils.o ./src/freertos_lwip_example_webserver.o ./src/freertos_lwip_example_ws_http_response.o ./src/freertos_lwip_example_ws_main.o ./src/lwip_example_iic_phyreset.o ./src/lwip_example_ws_platform_fs.o -Wl,--start-group,-lxil,-lfreertos,-lgcc,-lc,--end-group -Wl,--start-group,-lxil,-llwip4,-lgcc,-lc,--end-group -Wl,--start-group,-lxilffs,-lxil,-lgcc,-lc,--end-group c:/xilinx/vitis/2020.1/gnu/microblaze/nt/x86_64-oesdk-mingw32/usr/bin/microblaze-xilinx-elf/../../libexec/microblaze-xilinx-elf/gcc/microblaze-xilinx-elf/9.2.0/real-ld.exe: websv.elf section `.bss' will not fit in region `microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem' c:/xilinx/vitis/2020.1/gnu/microblaze/nt/x86_64-oesdk-mingw32/usr/bin/microblaze-xilinx-elf/../../libexec/microblaze-xilinx-elf/gcc/microblaze-xilinx-elf/9.2.0/real-ld.exe: region `microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem' overflowed by 3319336 bytes collect2.exe: error: ld returned 1 exit status 'Finished building target: websv.elf' ' ' 'Invoking: MicroBlaze Print Size' mb-size websv.elf |tee "websv.elf.size" mb-size: 'websv.elf': No such file 'Finished building: websv.elf.size' ' '
解決するにはメモリを節約するか増やす方法がありますが,
前者は簡単にできるものではなく相当な手間が必要になるかと思います.
幸いにもDDR3メモリがあるので有効活用します.
メモリ領域の割り当てを変えるにはリンカスクリプトを変更します.
左のExploererからlscript.ldをクリックして開きます.
まずメモリの割当を変更します.
右のAdd Memory…をクリックして新しく項目を増やします.
名前はmig_progmemとでもしておきます.
mig_7series_0_memaddrの領域をとりあえず半分にするため
Sizeを0x4000000に設定.
その半分をmig_progmemに割り当てるため
Base Addressを0x84000000
Sizeを0x4000000に設定します.
次に作成した領域に今回はbss領域を割り当てます.
下の欄から.bssがmicroblaze_0_local~となっているので
作成したmig_progmemに変更して保存すれば完成です.
先程と同様にBuildしてあげれば今度はちゃんと実行ファイルが生成されます.
動かしてみよう
実際に動かすのですが, Webサーバとして振る舞うには
htmlファイルや画像ファイルなどが必要です.
今回はxilffsで指定したようにRAM上に展開されます.
事前にRAM上にデータを転送しておくのですが
そのデータの作成はexamples以下README.txt以下に
Creating FAT image on Linuxとして書いてあるので
オリジナルのコンテンツで試してみたい場合は読んでみてください.
気をつけなければいけないのはhtmlファイルの拡張子はhtmで統一してください.
(これもまたFAT8.3形式関連の制約です. LFNに対応させたのでソースコードを
改良すれば.htmlにも対応できるはずです)
今回は用意しておいたデータを使用します.
実際に動かしていきます.
前回同様にシリアル通信用の接続を行い, LANケーブルを接続します.
ここでTera Termなどシリアル通信送受信ソフトウェアも立ち上げておきます.
次にwebsv_systemでデバッグするための設定を追加します.
上のバーから虫のマークの隣の黒い三角をクリックし,
Debug Configurations…をクリック.
新しい設定を追加するため左のメニューからSingle Application Debugを
ダブルクリックします.
Debugger_websv-Defaultが作成されます.
これで準備は完了です.右下のデバッグをクリックし開始します.
FPGAへデータが書き込まれ, MicroBlazeが動き始めます.
最初のエントリーポイントで停止するので, ここでRAM上にデータを書き込みます.
メニューバーからXilinx->Dump/Restore Memoryをクリック.
まずは書き込み対象を選択するためにSelectをクリック.
環境により多少異なりますがMicroBlaze #0を探して選択しOKをクリック.
次に書き込むファイルと場所, サイズを指定します.
先にRestore Memoryを選択してからBrowseでimgファイルを指定.
Memory Detailsでは書き込む先頭(DDR3メモリの位置)とそのサイズを指定します.
xilffsのライブラリ設定時の値やリンカスクリプトの編集時にも見たと思いますが
Start Addressを0x80000000
Sizeを3145728に設定します.
この状態でOKをクリックすれば書き込まれます.
ただし書き込み完了のダイアログ等は出てこないので適当な時間待つか,
先にエントリーポイントから実行を進めてしまえば問題ありません.
転送が終わるまで進むことはないようなので大丈夫です.
動作が開始したらシリアル通信でIPアドレスなどが出力されるので
ブラウザでアクセスしてみましょう.
実際に動くことが確認できました!
まとめ
今回はWebサーバをMicroBlaze上で動かしました.
メモリ不足で実行ファイルが生成されない問題があったので
DR3メモリも使用することで解決を図りました.
Webサーバ上のコンテンツはRAM上に展開されているので
ファイルシステムの設定と実際にRAM上へ展開する方法
についても紹介しました.
Webサーバとして振る舞うことができるので, FPGA内部の状態を
取得するようなプログラムを作成することで外部から
簡単に制御するようなことも可能であることから
Webサーバとして使用することは実用性が高いと考えます.
コメント
[…] 今回は前回, 前々回のプロジェクトを引き続き使用するのですが, 現状では, ハードウェア側でキャッシュが有効になっていません. まずはキャッシュを有効にしてからDhrystoneを動かします. […]