Skip to content

Repository files navigation

FE310-Red-V-RISC-V-Flash-Loader

A flash loader for Red-V development board with FE310 RISC-V microcontroller

Basic Info:

MCU: FE310  
QSPI Flash: IS25LP032D  
Dev board: Sparkfun Red-V with on-board J-Link  
Loader usage example: OpenOCD  
Languages: RISC-V RV32IMAC Assembly, C  

The loader structure could be used to create further loaders for different MCUs or to support other QSPI Flash.

Loader building (see CMakeLists.txt):

Compilation: -march=rv32imac -mabi=ilp32 -nostdlib -nostartfiles -Wall -Wextra -Os  
Linking: -Wl,--nostdlib,-e,loader  

Usage/Inner workings:
The loader is a compiled into a binary that has executable code and a configuration table embedded into it. Alternatively, precompiled loader.bin can also be used as-is (compiled with parameters set as in the provided source code and examples). The user of the loader uses a host debugger tool (such as OpenOCD) to load the loader into RAM (Position-independent), and then sets the MCU program counter to the same load address and resumes execution. The loader initializes itself:

  • sets its own stack as set in the code (see headers)
  • switches MCU clock to PLL clock with external XTAL source
  • resets QSPI Flash (forcing the flash into the default single-line SPI mode regardless of its initial configuration)
  • halts at the breakpoint instruction waiting for commands

The loader halted the CPU and is ready to accept commands:

  • The host uses the debugger tool to set operation code and parameters right in the memory structure of loader. Parameters include:
    1. Command code
    2. Flash memory address (non-memory-mapped, starting from 0)
    3. Flash data length (read length/write length; ignored for erase)
  • If writing into flash, the host also writes data (max. 1 256-byte page at a time) into data buffer located at the configured location (header)
  • The host advances program counter of the MCU by 4 (past breakpoint, into a small nop field landing area)
  • The host resumes execution

The loader received command and resumed execution:

  • The loader detects non-zero command code, jumps to the specific handler and performs read/write/erase
  • Once the operation finished, the MCU resets the command code to zero, and halts at the same breakpoint instruction waiting for the next command
  • If reading from the flash, the data read from the flash is now in the data buffer in RAM. Read length is limited only by MCU RAM size.

Stack space used by the loader:
~220 bytes (256 bytes of dedicated stack space is more than enough)

Supported commands:

  • Read flash (any length as long as it fits into RAM)
  • Write flash (max. 1 x 256-byte page per command)
  • Erase 4KiB sector
  • Erase 64KiB sector
  • Mass erase

Provided OpenOCD scripts allow the user to read/write/erase data of arbitrary size, the script will handle sending as many commands as necessary.
WARNING: Erase length 0 means MASS ERASE
WARNING: OpenOCD script may occasionally fail to connect to the target. It seems pretty random. If it happens, try again. It typically succeeds within 1-3 attempts.
WARNING: The loader functions correctly, but is pretty slow (unfortunately, OpenOCD + J-Link is a slow combo)

Releases

Packages

Contributors

Languages