Flashing a RED-V

I trying to get started with Segger Embedded Studio for Risc-V. I have a “hello world”, but I am not able to get it flashed. I think I might have two options: the Sparkfun bootloader or via the onboard Segger J-Link.

Is there info on the Red-V bootloader anywhere? Like, what flash address range is it using so my builds don’t try to overwrite it? Or what commands could be used to get it to download an appropriate binary?

Alternatively, I would really rather just use the onboard Segger JTAG interface. But I am not sure if it is capable of flashing code into the QSPI flash chip, or is that something we need to do ourselves? It occurs to me that since the Red-V instruction flash is completely external to the processor, it might be significantly more complex for the J-Link debugger to arrange to get the flash written.

My initial experiments show that the basic Segger environment appears to not understand how to manage the external flash. I can load my program by stepping to the first instruction (F11), and it looks like my code loads because it appears in the disassembly window. But if I open a memory window at the same address as where my code should be (0x20000000, or the first address in the QSPI flash memory space), I see what appears to someone else’s bootloader. Maybe the Sparkfun bootloader?

OK, I found out on the Segger forum that J-Link interface does in fact know how to program the QSPI flash that needs to be associated with the FE310 processor on the Red-V. That’s really nice! Then, I figured out that a better starting point for a hello world would be to simply the HiFive B example “blinky”. It came in a far more ready-to-run fashion. It built and flashed and debugged just fine right from the get-go. Sweet! The LED doesn’t blink, but I see the program repeatedly getting to the interrupt handler where the LED should be getting toggled. Perhaps the Red-V and HiFive-B have their LEDs on different pins. I’ll check…

But where does the sparkfun bootloader live so I don’t overwrite it? At the moment, I just stuck my program way up in the flash address space.

From reading on the HiFive forums, it looks like the bootloaders on HiFive Rev B boards with 4 megabyte flash chips (like the Red-V) are designed for user code to start at 0x2001_0000.

It turns out that Segger Embedded Studio for Risc-V works pretty seamlessly with the Red-V and was really easy to set up. You can get a Red-V board going basically instantly by building a project for a HiFive rev B board. The peripherals are a bit different between the boards (the HiFive has an RGB LED for example), but the basics of getting the Risc-V processor configured for operation and booting to a C/C++ main() program work perfectly.

My only problem was that the default flash map puts the user program at 0x2000_0000. I made a new project, forgot to change that setting, and promptly overwrote my bootloader. Doh!

Hi @robin_hodgson,

I am facing a similar problem with both RED-V boards: RedBoard and ThingPlus.

I am following these tutorials:

Hookup guide: https://learn.sparkfun.com/tutorials/re … 1576205724

Hello world: https://learn.sparkfun.com/tutorials/re … ment-guide

However, when trying to run the program through run configurations in Freedom Studio, I get the following error:


Downloading 404 bytes @ address 0x20010000 - Verified OK

Downloading 15600 bytes @ address 0x20010200 - Verified OK

Downloading 5460 bytes @ address 0x20013EF0 - Verified OK

Downloading 3148 bytes @ address 0x20015444 - Verified OK

Downloading 12 bytes @ address 0x20016090 - Verified OK

Downloading 2768 bytes @ address 0x200160A0 - Verified OK

Comparing flash […] Done.

Writing register (pc = 0x20010000)

Reading all registers

Starting target CPU…

ERROR: Communication timed out: Requested 4 bytes, received 0 bytes !

ERROR: Can not read register 4224 (PC) while CPU is running

WARNING: Target connection lost.

Reading all registers

WARNING: Failed to read memory @ address 0x00000000


After that board disconnects and connects back. Same goes for when I try to copy the hex file to the board directly.

I read your comment but I do not follow it 100% as I am quite new to embedded development.

Could you please list here the steps you took to make the board work?

Thank you.

There is one major difference: I am using Segger Embedded Studio for RISC-V, not Freedom Studio. If you are interested in trying out Segger Studio, go download it from Segger. It is free for non-commercial use. Make sure to get the RISC-V version, not the ARM version. The RED-V board contains an onboard Segger hardware debugger, accessed through the USB connection. Segger Studio knows how to work the RED-V debugger, and there is nothing special you have to do.

Start by installing Segger Embedded Studio. Start the program. I can’t remember if the initial startup of Segger Studio starts the package manager. If not, select “tools/Package Manager”. Scroll down until you see the SiFive section. Click on the package “HiFive1 Rev B Board Support Package”, and install it.

Important Note: The “HiFive RevB” board is quite similar to a SparkFun RED-V, but they are NOT exactly the same. However, it is close enough to get up and running, and start building and downloading software. They both use an identical processor and Flash/SRAM memory layout which is 90% of the battle.

Now you should be able to click open/solution. On my machine, Segger wants to store the solutions in my user directory, so for me I would navigate to “C:\Users\robin\AppData\Local\SEGGER\SEGGER Embedded Studio for RISC-V\v3\packages\HiFive1_RevB”. Inside that directory should be a file called “HiFive1_RevB_Samples.emProject”. Select that file.

You should see a couple of projects appear under a new solution. One of the projects is called “Blinky”. Left click <Project “Blinky”> to highlight it, then select menu item project/options. A dialog window will appear. Under the “build” section, you will see an option for “Memory Segments”. If you click “memory segments”, three dots “…” will appear at the far right of the option’s value. Click the dots to change the value for Memory Segments. I think the proper value should be “FLASH RX 0x20010000 0x1FFF0000;SRAM RWX 0x80000000 0x00004000”. This is telling the linker to build your executable so that it starts at address 0x2010000. This new address is required to avoid overwriting the bootloader located in the first 64K of flash.

As written, Blinky won’t do anything on a RED-V because the RED-V’s LED is wired up differently. The HiFiveB uses an RGB led, but the SparkFun RED-V only has a single blue LED. As a brutal hack to just make sure things work, edit the Blinky.c, and after all the include files have been included, add a define to override the definition of the blue LED for the HiFiveB to be on pin 5, which is where it is on a SparkFun RED-V:

include <stdint.h>
#include "platform.h"
#include "encoding.h"

#define BLUE_LED_OFFSET 5

Finally, you are ready to build. You should be able to build that project now by hitting F7, or click the build menu, and select “Build Blinky”. Once built, you click F5 (or select Debug/Go). The beauty of using Segger Studio is that you can be sure that it knows exactly how to use the Segger debugger that is built onto the RED-V board. Hitting F5 will flash your executable, and start it running. By default, Studio sets a breakpoint at the first line of main(), so the system should stop right there. Try hitting F10 a few times to single step main(). At any point, you can hit F5 (go), and the blue LED should start blinking. While the program is running and the LED is blinking, you can find scroll to the lines in Blinky.c that say:

  // Toggle LED
  GPIO_REG(GPIO_OUTPUT_VAL) ^= (0x1 << BLUE_LED_OFFSET);

Right click in the grey area just to the left of the source line that is toggling the LED, shown above. You should see a red breakpoint dot appear. If there is no code associated with the source line, the debugger will ignore your attempt to set a breakpoint. For example, if you click in the grey area to the left of the comment line, nothing will happen because comments don’t generate code. Once the breakpoint is set, the debugger will stop on that line the next time the interrupt occurs which should be within a second. You can then hit F10 to singlestep execution and watch the LED toggle.

Well, that’s what should happen in theory. I’ve tried to recreate these steps from memory, so they may not be exactly right.

Finally, your modified Blinky program is a nice starting point for writing code. However, we did lie to the Segger tool and told it that we were using a HiFive RevB board, so again, the peripherals outside of the CPU on that board (like the LEDs) are not identical to the RED-V. However, the overall memory map and all on-chip peripherals are completely identical because the processor and its external flash chip are both completely identical. This means that all of the HiFiveB startup code to get the processor set up for operation is pretty much exactly what you need, even for a RED-V. So this Frankenstein setup is not a perfect long-term solution, but it should certainly get you going.

Hi @robin_hodgson,

Thank you very much for the detailed instructions which solved my problem. I followed them but with hello world first. When I connected the device and programmed it through Segger IDE, it first updated the driver for J-Link for each board, Redboard and ThingPlus. Both boards worked and the serial terminal displayed the output.

I repeated the same procedure with Blinky and it worked as well on both boards.

Finally, I repeated both examples for each board with Freedom IDE and this time they worked.

I do not know what was the exact problem, but I guess the driver update fixed them.

Thank you again!