DE0-Nano-SoCのベアメタルアプリをSDカードからブートするとき、FPGAのコンフィギュレーションも同時に行う場合の手順です。
ベアメタルアプリとFPGAコンフィギュレーション
FPGAのコンフィギュレーションは、HPSでFPGAのデータをFPGA Portionにロードすることで行います。具体的には、FPGAのデータをFPGA Portionにロードするようなプログラムを作り、通常処理の前にFPGAのコンフィギュレーションをプログラム的に行います。FPGAのコンフィギュレーション用データは、ベアメタルアプリのデータと結合して1つのバイナリにします。
FPGAコンフィギュレーションのサンプル
サンプルデータがQuartus II(SoC EDS)に格納されています。サンプルの場所はembedded/examplessoftware、ファイル名はAltera-SoCFPGA-HardwareLib-FPGA-CV-GNU.tar.gzです。このサンプルを参考に、自分のベアメタルアプリにFPGAデータのコンフィギュレーションプログラムを追加します。
プログラムの追加例
自分のベアメタルアプリのmain関数の先頭部分に、FPGAコンフィギュレーション用関数の呼びだしを追加します。この例ではfpga_configがFPGAコンフィギュレーション用の関数です。
int main(int argc, char** argv) { fpga_config(); // FPGAのコンフィギュレーション run(); // 本来のベアメタルアプリの処理 }
fpga_configの処理
FPGAデータをロードするfpga_configの処理内容は次の通りです。
- HPSのDMAコントローラのセットアップ
- SDカードに格納されたバイナリ中のFPGAコンフィギュレーションデータの確認
- DMAコントローラを使ったFPGAデータのロード
- AXIブリッジの有効化
具体的なコードは次の通りです。なお、fpga_config内で呼び出している関数socfpga_*は、Altera-SoCFPGA-HardwareLib-FPGA-CV-GNU.tar.gzに格納されているhwlib.cに定義されているものをそのまま流用しています。
void fpga_config() { ALT_DMA_CHANNEL_t channel; // DMAコントローラのセットアップ socfpga_dma_setup(&channel); // FPGAデータの確認 extern char _binary_soc_system_rbf_start; extern char _binary_soc_system_rbf_end; // 上記シンボルでFPGAイメージを解凍 const char * fpga_image = &_binary_soc_system_rbf_start; const uint32_t fpga_image_size = &_binary_soc_system_rbf_end - &_binary_soc_system_rbf_start; // FPGAデータのロード socfpga_fpga_setup_dma(fpga_image, fpga_image_size, channel); // AXIブリッジの有効化 socfpga_bridge_setup(ALT_BRIDGE_LWH2F); // Lightweight HPS-to-FPGA socfpga_bridge_setup(ALT_BRIDGE_H2F); // HPS-to-FPGA socfpga_bridge_setup(ALT_BRIDGE_F2H); // FPGA-to-HPS }
FPGAデータのロード関数socfpga_setup_dmaの内部では、Cyclone VのMSEL[4:0]の確認とalt_fpga_configure_dma関数によるFPGAデータのロードが行われています。DE0-Nano-SoCのMSEL[4:0]の設定は、ON/OFF/ON/OFF/ON(デフォルト)に設定する必要があります。
コンパイル
コンパイルは、Altera-SoCFPGA-HardwareLib-FPGA-CV-GNU.tar.gzの格納されているMakefileが参考になります。注意点は次のとおりです。
defineの追加
ALT_FPGA_ENABLE_DMA_SUPPORTをdefineする必要があります。defineしないと、一部の関数がリンクされません。
CFLAGS := -c -fmessage-length=0 -save-temps -O3 -Wall -std=c99 $(MULTILIBFLAGS) -I$(HWLIBS_ROOT)/include -I$(HWLIBS_ROOT)/include/$(ALT_DEVICE_FAMILY) -D$(ALT_DEVICE_FAMILY) -I . -DALT_FPGA_ENABLE_DMA_SUPPORT=1
.rbfの圧縮
FPGAのコンフィギュレーションデータ(.sof)は、.rbfに変換後、さらに.oに変換してアプリケーションのバイナリとリンクします。.rbfに変換するときには、圧縮オプションを有効にする必要があります。圧縮しないとうまくロードできませんでした。
SOC_SYSTEM = ../qtproject/soc_system.sof soc_system.rbf: $(SOC_SYSTEM) $(RM) cpf_option.txt echo bitstream_compression=on > cpf_option.txt quartus_cpf -c -o cpf_option.txt $< $@ $(RM) cpf_option.txt soc_system.o: soc_system.rbf $(OC) --input-target binary --output-target elf32-little --alt-machine-code 40 $< $@
実際にmakeを行うと、次のようなログが表示されます。この例ではhello-mkimage.binが最終的なバイナリです。このバイナリの中に、FPGAのコンフィギュレーションデータとベアメタルアプリが格納されています。
rm -rf cpf_option.txt echo bitstream_compression=on > cpf_option.txt quartus_cpf -c -o cpf_option.txt ../qtproject/soc_system.sof soc_system.rbf Info: ******************************************************************* Info: Running Quartus II 64-Bit Convert_programming_file Info: Version 15.0.0 Build 145 04/22/2015 SJ Web Edition Info: Copyright (C) 1991-2015 Altera Corporation. All rights reserved. :(中略) arm-altera-eabi-objcopy --input-target binary --output-target elf32-little --alt-machine-code 40 soc_system.rbf soc_system.o arm-altera-eabi-objcopy: this target does not support 40 alternative machine codes arm-altera-eabi-objcopy: treating that number as an absolute e_machine value instead arm-altera-eabi-g++ -TcycloneV-dk-ram-modified.ld -march=armv7-a -mfloat-abi=softfp -mfpu=neon-fp16 src/tex_cubes.o io.o hwlib.o alt_hps_detect.o alt_clock_manager.o alt_interrupt.o alt_globaltmr.o alt_timers.o alt_watchdog.o alt_cache.o alt_mmu.o alt_address_space.o alt_bridge_manager.o alt_dma.o alt_dma_program.o alt_fpga_manager.o ./pplib/pl_romtbl.o soc_system.o -o src/tex_cubes.axf arm-altera-eabi-objdump -d -x src/tex_cubes.axf > src/tex_cubes.axf.objdump arm-altera-eabi-nm src/tex_cubes.axf > src/tex_cubes.axf.map arm-altera-eabi-objcopy -O binary src/tex_cubes.axf src/tex_cubes.bin mkimage -A arm -T standalone -C none -a 0x100040 -e 0 -n "baremetal image" -d src/tex_cubes.bin hello-mkimage.bin Image Name: baremetal image Created: Thu Mar 15 10:15:50 2065 Image Type: ARM Linux Standalone Program (uncompressed) Data Size: 2293808 Bytes = 2240.05 kB = 2.19 MB Load Address: 00100040 Entry Point: 00000000 cp -f C:/Altera/15.0/embedded/examples/hardware/cv_soc_devkit_ghrd/software/preloader/uboot-socfpga/spl/u-boot-spl u-boot-spl.axf arm-altera-eabi-objdump -d u-boot-spl.axf > u-boot-spl.axf.objdump
実行ログ
出来上がったhello-mkimage.binを、ベアメタル用のSDカードに入れてDE0-Nano-SoCの電源をONにすると、FPGAコンフィギュレーション後に通常のアプリの処理が始まります。
U-Boot SPL 2013.01.01 (Jan 20 2016 - 07:19:29) BOARD : Altera SOCFPGA Cyclone V Board CLOCK: EOSC1 clock 25000 KHz CLOCK: EOSC2 clock 25000 KHz CLOCK: F2S_SDR_REF clock 0 KHz CLOCK: F2S_PER_REF clock 0 KHz CLOCK: MPU clock 925 MHz CLOCK: DDR clock 400 MHz CLOCK: UART clock 100000 KHz CLOCK: MMC clock 50000 KHz CLOCK: QSPI clock 3613 KHz RESET: COLD SDRAM: Initializing MMR registers SDRAM: Calibrating PHY SEQ.C: Preparing to start memory calibration SEQ.C: CALIBRATION PASSED SDRAM: 1024 MiB ALTERA DWMMC: 0 reading hello-mkimage.bin reading hello-mkimage.bin INFO: Setup DMA System ... INFO: Channel 0 allocated. INFO: Setup of DMA successful. INFO: FPGA Image binary at 0x1a62b8. INFO: FPGA Image size is 1960824 bytes. INFO: Setup FPGA System ... INFO: MSEL [10] configured correctly for compressed FPGA image. INFO: Setup of FPGA successful. INFO: Setup Bridge [2] ... INFO: Setup of Bridge [2] successful. INFO: Setup Bridge [1] ... INFO: Setup of Bridge [1] successful. INFO: Setup Bridge [0] ... INFO: Setup of Bridge [0] successful. RESULT: FPGA configuration completed successfully.
まとめ
FPGAコンフィギュレーションをHPSで行うと、Programmerで毎回.sofをロードする処理が不要になります。電源投入ですぐにアプリケーションが起動するので、期待以上に快適です。