Conveniently flash QSPI, NAND, SDMMC using DS-5, JTAG and optional TFTP

Introduction

This page presents a script that uses the DS-5 debugger and U-Boot to program the NAND and QSPI flash on an Arria 10 Development board.

flash-programmer.png

This script can be useful for the following purposes:
  • Increased programming speed as compared to HPS Flash Programmer (quartus_hps) that is intended only for programming small files
  • Dealing with NAND bad block tables (current 16.1 version of quartus_hps does not manage and can overwrite NAND bad block tables)
  • Programming SD cards remotely, when they cannot be removed from the socket and programmed with an USB adapter
  • Programming eMMC boot cards

The script also supports QSPI, SD and eMMC and support for additional SoCs and boards can be relatively easily added.

The script supports downloading the image through JTAG or TFTP. TFTP is several times faster than JTAG. It is highly recommended to use TFTP image transfer when programming large eMMC or SD images.

Prerequisites

The following are required in order to run the script
  • Arria 10 Development Kit rev. B and C with
    • Arria 10 NAND Bootcard - for NAND operation
    • Arria 10 QSPI Bootcard - for QSPI operation
    • Arria 10 Micro SD Bootcard - for SD operation
    • Customer-provided Arria 10 eMMC Bootcard - for eMMC operation
  • SoC EDS 16.1, including the optional Quartus Prime Programmer
  • ARM DS-5 license - required because the script uses the debugger to download an instrumented version of the bootloader to the board and automate it

The deliverables includes the precompiled hardware designs and bootloaders necessary for the script operation. If these need to be modified to fit another board and/or recompiled, the following are also required:
  • Quartus Prime 16.1 - for compiling the hardware design
  • SoC EDS 16.1 - Linux version for compiling the bootloader

Operation

This section presents details on how to use the script.

A few important notes are:
  • The script needs to be executed from an Embedded Command Shell, both on Windows and Linux
  • The script assumes a single USB Blaster cable is connected to the host
  • Error detection in the script can be improved
  • The script tries to output as much information as possible about what it is doing:
    • Output of different commands: displayed in gray or magenta
    • Error messages: displayed in red
    • Bootloader console messages: displayed in yellow
  • The script creates the following temporary files:
    • ___tmp_quartus_hps.script - script used to detect the soc and flash memory by using quartus_hps
    • ___tmp_ds5-debugger-script.ds5 - ds-5 script used to automate u-boot loading and operation
    • ___tmp_ds5_uboot_console.txt - U-Boot console output

Installation

The script is delivered as an archive attached to this page. The archive needs to be extracted, then the script can be ran from an Embedded Command Shell. Th archive contains the following:

Item Description
a10_sdmmc_devkit_revb_design A10 SDMMC programmer support binaries for Rev B DevKit
a10_sdmmc_devkit_revc_design A10 SDMMC programmer support binaries for Rev C DevKit
a10_nand_devkit_revb_design A10 NAND programmer support binaries for Rev B DevKit
a10_nand_devkit_revc_design A10 NAND programmer support binaries for Rev C DevKit
a10_qspi_devkit_revb_design A10 QSPI programmer support binaries for Rev B DevKit
a10_qspi_devkit_revc_design A10 QSPI programmer support binaries for Rev B DevKit
flash_programmer.py Python programmer script

The following commands can be used on a Linux host machine:

cd~ 
wget https://rocketboards.org/foswiki/pub/Documentation/Arria10NANDFlashProgramming/flash_programmer.tgz
tar xzf flash_programmer.tgz
cd flash_programmer
~/altera/16.1/embedded/embedded_command_shell.sh
./flash_programmer.py --help

Use equivalent commands on a Windows host machine.

Basic Usage

The basic usage of the script is as follows:

# start an Embedded Command Shell
~/intelFPGA/16.1/embedded/embedded_command_shell.sh
# change current folder to the flash programmer folder
cd ~/flash_programmer
# call the programmer script
./flash_programmer.py            \
    [--board=board_name]         \
    [--soc=a10]                  \
    [--flash=nand|qspi|sdmmc]          \
    --operation=operation        \ 
    [--address=hex_address]      \
    [--size=hex_size]            \
    [--file=file_to_be_flashed]  \
    [--help]

Parameter Description
--board Target board. Currently defaults to 'devkit_revc' - the only board that is supported
--soc Target SoC. Currently only 'a10' is supported. The script will auto-detect the soc if not supplied
--flash Target flash. The 'nand', 'qspi' and 'sdmmc' are supported. The script will autodetect the flash based on BSEL if not supplied
--operation Requested operation: a combination of letters 's' - display flash information and exit, 'e' - erase, 'p' - program, 'v' - verify, 'E' - erase NAND using clean option, 'P' - program NAND using trimffs option
--address Target flash address: hexadecimal number, starting with '0x'
--size Target flash size: hexadecimal number, starting with '0x'
--file File to be used
--help Display help message
Important Notes:
  • 'size' can be omitted, and in that case the actual file size will be used
  • 'size' can be greater than the actual file size. In this case the programmer with pad the image with '0xff'.
  • 'address' can be omitted if beginning of flash is targeted (it defaults to '0x0')

TFTP Usage

Instead of downloading the flash image through JTAG, it can also be downloaded with the aid of a TFTP server, which is several times faster. The TFTP usage requires the following:
  • Installing or running a TFTP server on the local machine
  • Configuring the local firewall to allow TFTP connections
  • Additional local ethernet drop or local network switch
  • Existence of local network DHCP server

The following additional flash_programmer.py parameters need to be used to enable TFTP image transfer:

Parameter Description
--use-tftp Use 'yes' or 'true' to tell script to use TFTP
--tftp-sever IP Address of the local machine, where TFTP server runs
--tftp-folder Local folder where the TFTP serves the files from
--mac-address MAC address to be used by the board

Usage Examples

Example Description
./flash_programmer.py --flash=nand --operation=e
Erase the whole NAND flash chip. Targets thes default 'devkit_revc' board
./flash_programmer.py --flash=sdmmc --operation=pv --file=c:/emmc_image.img \
--use-tftp="yes" --tftp-server="192.168.10.105" --tftp-folder="c:/tftproot" \
--mac-address="B4:B5:2F:A0:93:4D"
Write image to eMMC Card, transferring image through TFTP. Targets the default 'devkit_revc' board
./flash_programmer.py --board=devkit_revb --flash=nand --operation=epv \
--address=0x100000 --size=0x2000000 \
--file=ghrd_10as066n2.rbf.mkimage
Erase 0x2000000 bytes (32MB) of NAND starting at address 0x100000 then write the file ghrd_10as066n2.rbf.mkimage padded with 0xff to 16MB, then read back and verify the result. Targets the 'devkit_revb' board

Here are some screenshots when the script is used to erase NAND flash as described in the first example above:

1. Command being issued, script detecting JTAG connection and which soc is used, then programming the FPGA: prog-erase-1.png

2. DS-5 script being created, and DS-5 debugger being invoked to execute that script: prog-erase-2.png

3. U-Boot console messages shown in yellow: prog-erase-3.png

4. U-Boot NAND erase complete and script exit: prog-erase-4.png

Performance

The following table presents the duration of several programming scenarios, to allow the user to assess suitability for their particular scenario:

Flash Size Verification Transfer Duration
QSPI 128MB yes JTAG 35min
^ ^ ^ TFTP 9min
NAND 80MB yes JTAG 13min
^ ^ ^ TFTP 9min
SDMMC 2GB no JTAG 2h30min
^ ^ yes ^ 2h40min
^ ^ no TFTP 34min
^ ^ yes ^ 44min

It is highly recommended to use TFTP image transfer when programming large eMMC or SD images.

Known Issues

These are the known issues:
  • In some situations the script can fail (for example due to incorrect parameters). In such cases the execution can be interrupted with the CTRL-C sequence
  • When the script was forcefully interrupted with CTRL-C, the console text color can remain set to the last color used by the script. This can typically be remedied by using the 'reset' terminal command.
  • On Windows, when the script was forcefully interrupted with CTRL-C, some of the temporary files may remain opened. If this happens, trying to run the script again will signal the error that the temporary file cannot be created. In such a case, the Embedded Command Shell window needs to be closed, and another one opened.

Rebuilding the Script Binaries

The script relies on pre-compiled versions of the Hardware Design and Bootloaders targeting A10 DevKit revisions B & C, NAND and QSPI.

The script determines the location of the pre-compiled binaries by concatenating the following items, with underscores in between:
  • soc
  • flash
  • board
  • 'design'

For the provided configurations, these folder names are:

Folder Description
a10_sdmmc_devkit_revb_design A10 SDMMC programmer support binaries for Rev B DevKit
a10_sdmmc_devkit_revc_design A10 SDMMC programmer support binaries for Rev C DevKit
a10_nand_devkit_revb_design A10 NAND programmer support binaries for Rev B DevKit
a10_nand_devkit_revc_design A10 NAND programmer support binaries for Rev C DevKit
a10_qspi_devkit_revb_design A10 QSPI programmer support binaries for Rev B DevKit
a10_qspi_devkit_revc_design A10 QSPI programmer support binaries for Rev B DevKit

For each configuration the following files are needed:

File Description
output_files/ghrd_10as066n2.sof FPGA configuration file
software/bootloader_extcfg_semihosting/devicetree.dtb Bootloader device tree binary
software/bootloader_extcfg_semihosting/uboot-socfpga/u-boot Bootloader executable

This section presents the complete instructions on how the binaries were obtained, in case modifications are needed, for example for targeting another board.

NAND

The commands for re-creating the NAND binaries for rev C board are listed below:

# Start an embedded command shell
~/intelFPGA/16.1/embedded/embedded_command_shell.sh
mkdir -p ~/flash_programmer
cd ~/flash_programmer

# Create NAND hardware design
mkdir a10_nand_devkit_revc_design
cd a10_nand_devkit_revc_design
tar xvzf ~/intelFPGA/16.1/embedded/examples/hardware/a10_soc_devkit_ghrd/tgz/*.tar.gz
make scrub_clean
sed -i 's/HPS_BOOT_DEVICE := SDMMC/HPS_BOOT_DEVICE := NAND/g' Makefile
make generate_from_tcl

# Build NAND hardware design
make sof

# Generate and build bootloader
mkdir -p software/bootloader_extcfg_semihosting
bsp-create-settings --type uboot --bsp-dir software/bootloader_extcfg_semihosting --preloader-settings-dir "hps_isw_handoff" --settings software/bootloader_extcfg_semihosting/settings.bsp --set uboot.external_fpga_config true
sed -i 's/BOOT_DEVICE := SDMMC/BOOT_DEVICE :=NAND/g' software/bootloader_extcfg_semihosting/config.mk
make -C software/bootloader_extcfg_semihosting
make -C software/bootloader_extcfg_semihosting clean
sed -i 's/#undef CONFIG_SEMIHOSTING/#define CONFIG_SEMIHOSTING/g' software/bootloader_extcfg_semihosting/uboot-socfpga/include/configs/socfpga_arria10.h
sed -i "s/putc('#');/{}/g" software/bootloader_extcfg_semihosting/uboot-socfpga/net/tftp.c
sed -i 's/puts("\\n\\t ');/{}/g" software/bootloader_extcfg_semihosting/uboot-socfpga/net/tftp.c
make -C software/bootloader_extcfg_semihosting

The commands for re-creating the NAND binaries for rev B board are listed below:

# Start an embedded command shell
~/intelFPGA/16.1/embedded/embedded_command_shell.sh
mkdir -p ~/flash_programmer
cd ~/flash_programmer

# Create NAND hardware design
mkdir a10_nand_devkit_revb_design
cd a10_nand_devkit_revb_design
tar xvzf ~/intelFPGA/16.1/embedded/examples/hardware/a10_soc_devkit_ghrd/tgz/*.tar.gz
make scrub_clean
sed -i 's/HPS_BOOT_DEVICE := SDMMC/HPS_BOOT_DEVICE := NAND/g' Makefile
sed -i 's/QUARTUS_DEVICE := 10AS066N3F40E2SG/QUARTUS_DEVICE := 10AS066N3F40E2SGE2/g' Makefile
sed -i 's/set FPGA_DEVICE 10AS066N3F40E2SG/set FPGA_DEVICE 10AS066N3F40E2SGE2/g' design_config.tcl
sed -i 's/set FPGA_DEVICE 10AS066N3F40E2SG/set FPGA_DEVICE 10AS066N3F40E2SGE2/g' ip/diffin/construct_diffin.tcl
sed -i 's/set_global_assignment -name DEVICE 10AS066N3F40E2SG/set_global_assignment -name DEVICE 10AS066N3F40E2SGE2/g' synth_v2.qsf
make generate_from_tcl

# Build NAND hardware design
make sof

# Generate and build bootloader
mkdir -p software/bootloader_extcfg_semihosting
bsp-create-settings --type uboot --bsp-dir software/bootloader_extcfg_semihosting --preloader-settings-dir "hps_isw_handoff" --settings software/bootloader_extcfg_semihosting/settings.bsp --set uboot.external_fpga_config true
sed -i 's/BOOT_DEVICE := SDMMC/BOOT_DEVICE :=NAND/g' software/bootloader_extcfg_semihosting/config.mk
make -C software/bootloader_extcfg_semihosting
make -C software/bootloader_extcfg_semihosting clean
sed -i 's/#undef CONFIG_SEMIHOSTING/#define CONFIG_SEMIHOSTING/g' software/bootloader_extcfg_semihosting/uboot-socfpga/include/configs/socfpga_arria10.h
sed -i "s/putc('#');/{}/g" software/bootloader_extcfg_semihosting/uboot-socfpga/net/tftp.c
sed -i 's/puts("\\n\\t ');/{}/g" software/bootloader_extcfg_semihosting/uboot-socfpga/net/tftp.c
make -C software/bootloader_extcfg_semihosting

QSPI

The commands for creating the QSPI binaries for revc C board are listed below:

# Start an embedded command shell 
~/intelFPGA/16.1/embedded/embedded_command_shell.sh
mkdir -p ~/flash_programmer
cd ~/flash_programmer

# Create QSPI hardware design
mkdir a10_qspi_devkit_revc_design
cd a10_qspi_devkit_revc_design
tar xvzf ~/intelFPGA/16.1/embedded/examples/hardware/a10_soc_devkit_ghrd/tgz/*.tar.gz
make scrub_clean
sed -i 's/HPS_BOOT_DEVICE := SDMMC/HPS_BOOT_DEVICE := QSPI/g' Makefile
make generate_from_tcl

# Compile QSPI hardware design
make sof

# Generate and build bootloader
mkdir -p software/bootloader_extcfg_semihosting
bsp-create-settings --type uboot --bsp-dir software/bootloader_extcfg_semihosting --preloader-settings-dir "hps_isw_handoff" --settings software/bootloader_extcfg_semihosting/settings.bsp --set uboot.boot_device QSPI --set uboot.external_fpga_config true
make -C software/bootloader_extcfg_semihosting
make -C software/bootloader_extcfg_semihosting clean
sed -i 's/#undef CONFIG_SEMIHOSTING/#define CONFIG_SEMIHOSTING/g' software/bootloader_extcfg_semihosting/uboot-socfpga/include/configs/socfpga_arria10.h
sed -i "s/putc('#');/{}/g" software/bootloader_extcfg_semihosting/uboot-socfpga/net/tftp.c
sed -i 's/puts("\\n\\t ');/{}/g" software/bootloader_extcfg_semihosting/uboot-socfpga/net/tftp.c
make -C software/bootloader_extcfg_semihosting

The commands for re-creating the QSPI binaries for rev B board are listed below:

# Start an embedded command shell 
~/intelFPGA/16.1/embedded/embedded_command_shell.sh
mkdir -p ~/flash_programmer
cd ~/flash_programmer

# Create QSPI hardware design
mkdir a10_qspi_devkit_revb_design
cd a10_qspi_devkit_revb_design
tar xvzf ~/intelFPGA/16.1/embedded/examples/hardware/a10_soc_devkit_ghrd/tgz/*.tar.gz
make scrub_clean
sed -i 's/HPS_BOOT_DEVICE := SDMMC/HPS_BOOT_DEVICE := QSPI/g' Makefile
sed -i 's/QUARTUS_DEVICE := 10AS066N3F40E2SG/QUARTUS_DEVICE := 10AS066N3F40E2SGE2/g' Makefile
sed -i 's/set FPGA_DEVICE 10AS066N3F40E2SG/set FPGA_DEVICE 10AS066N3F40E2SGE2/g' design_config.tcl
sed -i 's/set FPGA_DEVICE 10AS066N3F40E2SG/set FPGA_DEVICE 10AS066N3F40E2SGE2/g' ip/diffin/construct_diffin.tcl
sed -i 's/set_global_assignment -name DEVICE 10AS066N3F40E2SG/set_global_assignment -name DEVICE 10AS066N3F40E2SGE2/g' synth_v2.qsf
make generate_from_tcl

# Compile QSPI hardware design
make sof

# Generate and build bootloader
mkdir -p software/bootloader_extcfg_semihosting
bsp-create-settings --type uboot --bsp-dir software/bootloader_extcfg_semihosting --preloader-settings-dir "hps_isw_handoff" --settings software/bootloader_extcfg_semihosting/settings.bsp --set uboot.boot_device QSPI --set uboot.external_fpga_config true
make -C software/bootloader_extcfg_semihosting
make -C software/bootloader_extcfg_semihosting clean
sed -i 's/#undef CONFIG_SEMIHOSTING/#define CONFIG_SEMIHOSTING/g' software/bootloader_extcfg_semihosting/uboot-socfpga/include/configs/socfpga_arria10.h
sed -i "s/putc('#');/{}/g" software/bootloader_extcfg_semihosting/uboot-socfpga/net/tftp.c
sed -i 's/puts("\\n\\t ');/{}/g" software/bootloader_extcfg_semihosting/uboot-socfpga/net/tftp.c
make -C software/bootloader_extcfg_semihosting

SDMMC

The commands for creating the SDMMC binaries for revc C board are listed below:

# Start an embedded command shell 
~/intelFPGA/16.1/embedded/embedded_command_shell.sh
mkdir -p ~/flash_programmer
cd ~/flash_programmer

# Create SDMMC hardware design
mkdir a10_sdmmc_devkit_revc_design
cd a10_sdmmc_devkit_revc_design
tar xvzf ~/intelFPGA/16.1/embedded/examples/hardware/a10_soc_devkit_ghrd/tgz/*.tar.gz
make scrub_clean
make generate_from_tcl

# Compile SDMMC hardware design
make sof

# Generate and build bootloader
mkdir -p software/bootloader_extcfg_semihosting
bsp-create-settings --type uboot --bsp-dir software/bootloader_extcfg_semihosting --preloader-settings-dir "hps_isw_handoff" --settings software/bootloader_extcfg_semihosting/settings.bsp --set uboot.boot_device SDMMC --set uboot.external_fpga_config true
make -C software/bootloader_extcfg_semihosting
make -C software/bootloader_extcfg_semihosting clean
sed -i 's/#undef CONFIG_SEMIHOSTING/#define CONFIG_SEMIHOSTING/g' software/bootloader_extcfg_semihosting/uboot-socfpga/include/configs/socfpga_arria10.h
sed -i "s/putc('#');/{}/g" software/bootloader_extcfg_semihosting/uboot-socfpga/net/tftp.c
sed -i 's/puts("\\n\\t ');/{}/g" software/bootloader_extcfg_semihosting/uboot-socfpga/net/tftp.c
make -C software/bootloader_extcfg_semihosting

The commands for creating the SDMMC binaries for revc B board are listed below:

# Start an embedded command shell 
~/intelFPGA/16.1/embedded/embedded_command_shell.sh
mkdir -p ~/flash_programmer
cd ~/flash_programmer

# Create SDMMC hardware design
mkdir a10_qspi_devkit_revb_design
cd a10_sdmmc_devkit_revb_design
tar xvzf ~/intelFPGA/16.1/embedded/examples/hardware/a10_soc_devkit_ghrd/tgz/*.tar.gz
make scrub_clean
sed -i 's/QUARTUS_DEVICE := 10AS066N3F40E2SG/QUARTUS_DEVICE := 10AS066N3F40E2SGE2/g' Makefile
sed -i 's/set FPGA_DEVICE 10AS066N3F40E2SG/set FPGA_DEVICE 10AS066N3F40E2SGE2/g' design_config.tcl
sed -i 's/set FPGA_DEVICE 10AS066N3F40E2SG/set FPGA_DEVICE 10AS066N3F40E2SGE2/g' ip/diffin/construct_diffin.tcl
sed -i 's/set_global_assignment -name DEVICE 10AS066N3F40E2SG/set_global_assignment -name DEVICE 10AS066N3F40E2SGE2/g' synth_v2.qsf
make generate_from_tcl

# Compile SDMMC hardware design
make sof

# Generate and build bootloader
mkdir -p software/bootloader_extcfg_semihosting
bsp-create-settings --type uboot --bsp-dir software/bootloader_extcfg_semihosting --preloader-settings-dir "hps_isw_handoff" --settings software/bootloader_extcfg_semihosting/settings.bsp --set uboot.boot_device SDMMC --set uboot.external_fpga_config true
make -C software/bootloader_extcfg_semihosting
make -C software/bootloader_extcfg_semihosting clean
sed -i 's/#undef CONFIG_SEMIHOSTING/#define CONFIG_SEMIHOSTING/g' software/bootloader_extcfg_semihosting/uboot-socfpga/include/configs/socfpga_arria10.h
sed -i "s/putc('#');/{}/g" software/bootloader_extcfg_semihosting/uboot-socfpga/net/tftp.c
sed -i 's/puts("\\n\\t ");/{}/g' software/bootloader_extcfg_semihosting/uboot-socfpga/net/tftp.c
make -C software/bootloader_extcfg_semihosting

Adding Boards and/or SoCs

The script was designed to support additional Boards and SoCs (AV/CV/A10). The Python script should need no changes, but updated binaries must be provided.

Example 1: Add NAND write capabilities for A10 board named 'acme'. The following are needed:
  • Create a new folder named 'a10_nand_acme_design' with the hardware design and precompiled bootloader similar with the A10 devkit version
  • Invoke the tool with the new board:
    ./flash_programmer.py [--soc=a10] [--flash=nand] --board=acme --operation=... 

Example 2: Add QSPI write capabilities for CV board named 'thunder'. The following are needed:
  • Create a new folder named 'cv_qspi_thunder_design' with the hardware design and precompiled bootloader similar with the A10 devkit version
  • Invoke the tool with the new board:
    ./flash_programmer.py [--soc=cv] [--flash=nand] --board=thunder  --operation=... 

© 1999-2024 RocketBoards.org by the contributing authors. All material on this collaboration platform is the property of the contributing authors.

Privacy Policy - Terms Of Use

This website is using cookies. More info. That's Fine