Easy @Utkk it’s pretty simple with a single CLI command. See file riscv.mk
shown in Demonstrating AMO
make -f riscv.mk [romload | romrun | romdebug]
Discussion in more detail is at Demystifying OpenOCD
Basically, you define a bank item for each Flash device and/or memory range. You can use any name you wish, spi0 is a good choice. You can have as many banks as you want.
The SPI peripheral base address which is wired to the Flash memory is 0x10014000
, and the Flash memory device is mapped at address 0x20000000
, both are constants specified in the Data Sheet and User Manual for the FE310 SoC of the HiFive 1 Rev B board.
flash bank spi0 fespi 0x20000000 0 0 0 riscv.cpu.0 0x10014000
It’s a five-step procedure to write the Flash memory: First, turn off the write protection for the sector(s) you will write; then erase the desired sector(s); followed by writing and verifying those sectors; lastly and optionally turn on the write protection.
flash protect 0 0 4 off
flash erase_sector 0 0 4
flash write_bank 0 filename
flash verify_bank 0 filename
flash protect 0 0 4 on
The two numbers {0, 4}
above are the beginning and ending sector numbers of the Flash memory. Computing them for desired length of filename is a little tricky, to do a proper integer-based calculation. The number 4
the example steps is ENDSEC
below; the number 0
in the example is trivial, starting from beginning of Flash memory.
In tcl
script, for use in openocd files:
set secsz [expr 0x1000] ;# 4K sectors issi is25lp128d, typ. most NOR flash
set len [file size filename]
set endsec [expr (${len}/${secsz})+((${len}-(${len}/${secsz})*${secsz})>0)-1]
In /bin/bash
script, for use in, e.g., make files:
$(eval SECSZ=$(shell echo "ibase=16; 1000" | bc))
$(eval LEN=$(shell <filename wc -c))
$(eval ENDSEC=$(shell echo "(${LEN}/${SECSZ})+((${LEN}-(${LEN}/${SECSZ})*${SECSZ})>0)-1" | bc))
Where SECSZ
for the issi is25lp128d Flash memory chip is 4K, or 0x1000 bytes. It is also defined in …src/flash/nor/core.h:45 of the openocd library.