Five EmbedDev logo Five EmbedDev

An Embedded RISC-V Blog

Subscribe with RSS to keep up with the latest changes.

Rust CSR Access Macros

December 27, 2022|Code (toolchain,baremetal,rust)

Added CSR access macros for RISC-V to the respository.

There is a standard crate for RISC-V . that has a more canonical implementation for accessing CSRS. The purpose of this code is a to have a template generated implementation that closely matches the C header used for other examples riscv-csr-access:include/riscv-csr.h.

Testing Startup Constructors

November 19, 2022|Code (toolchain,baremetal,C,C++)

There were a few bugs in the code examples that have been fixed.

The loop in startup.c function _startup() that calling each entry from __init_array_start to __init_array_end was incorrect in Startup Code in C and Startup Code in C++. It has been fixed and tested.

To test it the main.c routine was updated to demonstrate the operation of the contructors called in _startup() before main() is called.


Example for VCD Tracing of RISC-V Software

September 04, 2022|Code (toolchain,vcd,simulation,debugging,tracing,baremetal,C)

In the previous post I added a fork of the RISC-V ISA simulator. In this post you can see how it can be used.

The source code for this example is on github, here:

This small program handles the mie, msi, mti and trap interrupts and updates some global variables when interrupts occur.


RISC-V Software Tracing with VCD and Spike

September 02, 2022|Toolchain (toolchain,vcd,simulation,debugging,tracing)

Viewing hardware and software interaction is much easier with a logic analyzer style trace. In almost every job I’ve had I’ve added a VCD tracer to the instruction set simulator. Both the “big picture” state flow can be seen, and the “little details” of bus/register/interrupt/io interaction can be seen.

For that purpose I’ve forked the RISC-V ISA Simulator,

About the fork

This fork adds a few features.

  • Tracing of registers and memory bus.
  • Time limit for simulation.
  • New commands to trace variables.
  • Two way symbol <-> address lookup.

This is an example of a firmware writing to the mtimecmp register:

mtimecmp write


Baremetal Example Updates

September 01, 2022|Code (toolchain,baremetal,C,csr,registers,cmake)

Updates have been made to the baremetal examples.

CMake Updates

  • The CMake file can now find riscv-none-elf-gcc as the xpack GCC executable has been renamed to riscv-none-elf-*.
  • Recent GCCs/binutils require the zicsr extension to be specified in -march to use CSR instructions.

Code Updates

  • Updated CSR access templates to test for zicsr extension.
  • Updated the CSR access header for the Baremetal C examples.
  • Fixed the CMakeLists.txt files to include -march=rv32imac_zicsr.
  • Updated the timer.h to allow USEC/MSEC intervals and different timer frequencies.
  • Added the baremetal-vcd-trace example.


August 18, 2022|Updates (,spec,quickref)

A few upates:

Simulating and Debugging with a Docker Containerized Toolchain

March 25, 2022|Toolchain (toolchain,docker,simulation,debugging)

Containerized Development

In a previous post I used docker to containerize building for a RISC-V target.

In this post I’ll simulate that target file in a containerized RISC-V ISA Simulator.

Spike ISA Sim

The official reference ISA simulator for RISC-V is spike. There are other more functional and performant open source and commercial simulators , however the aim of this post is to describe a solution for quick and easy debugging and simulation of the low level examples on this blog.

Spike implements a functional model of the RISC-V hart(s) and the debug interface. GDB must connect to OpenOCD, which will in turn connect to Spike’s model of the RISC-V serial debug interface. Spike’s Readme file describes how to do this, but it’s pretty tedious to load an example program.

The container example downloads and builds the appropriate source code and manages running the independent tools.

Docker Images

The docker files are in Assume it’s checked out to build-and-verify.


Stack and Global Pointer Quick Reference

March 06, 2022|Isa (registers,quickref)

Added some notes on the global pointer and stack pointer.

Example Bugs!

March 06, 2022|Code (toolchain,baremetal,C)

There were a few bugs in the code examples that have been fixed.

  • Global pointer needs to be written with norelax option set. (See quickref: Global Pointer)
  • For C++ the argument order to std::copy() was incorrect. (it matched memcpy() … target, source)

Building with a Docker container Toolchain

March 01, 2022|Toolchain (toolchain,docker)

Containerized Development

Modern development is moving towards packaging tools in containers. There are several benefits to containerizing development tools:

  • A simpler tool deployment process, the binary image with all dependencies can simply be pulled from a server and run.
  • An automated and consistent deployment process that can be shared between development machines and cloud based build servers.
  • A consistent set of tools for all team members.
  • The ability to build with General Purpose IDE’s rather than whatever tools a device vendor may provide.
  • Isolation of dependencies used for different devices and build targets.

For RISC-V there are a few more benefits:

I’ve put together a set of Docker images and Docker Compose build and run configurations with the aim of deploying them with GitHub’s workflows.

They are located here:


Extending PlatformIO

November 05, 2021|Toolchain (articles,toolchain,C)

Information about extending cross compilation with PlatformIO has been added.


Baremetal Vectored Interrupts in C for RISC-V

September 25, 2021|Code (articles,baremetal,C)

An example of using vectored interrupts in C.


Baremetal Timer Driver in C for RISC-V

September 24, 2021|Code (articles,baremetal,C)

An example of a timer driver in C has been added.


Baremetal Startup in C for RISC-V

September 24, 2021|Code (articles,baremetal,C)

An example of a startup code in C.


Machine Readable Specification Data

September 10, 2021|Toolchain (registers,spec,interrupts,opcodes)

As RISC-V is a new architecture so there will be new development at all layers of the software and hardware stack. Rather than write code based on human language specifications from scratch, a smarter way to work can be to translate a machine readable specification to code.

“Machine Readable” does not need to be an all encompassing formal model of the architecture, there are many convenient formats such as csv, yaml, xml and json that can be parsed and transformed using the packages available in most scripting languages.


Baremetal Timer Driver in C++ for RISC-V

August 13, 2021|Code (articles,baremetal,C++)

An example of a timer driver.


Baremetal Interrupt in C++ for RISC-V

August 13, 2021|Code (articles,baremetal,C++)

An example of using interrupts.


Baremetal Startup Code in C++ for RISC-V

April 13, 2021|Code (toolchain,baremetal,C++)

An example of baremetal bootstrap code for RISC-V in C++.


CMake Cross Compilation for RISC-V Targets

March 20, 2021|Toolchain (articles,toolchain,baremetal,cmake)

An example of cross compiling a baremetal program to RISC-V with CMake.


RISC-V Compile Targets, GCC

February 09, 2021|Toolchain (gcc,base_isa,extensions,abi)

Note to self: When compiling the riscv-toolchain for embedded systems, set the configure options!

The toolchain can be cloned from the RISC-V official github. Once the dependencies are installed it’s straight forward to compile.

$ git clone --recursive



November 18, 2020|Code (registers,code,baremetal,quickref)

For baremetal programming I’ll often need to access CSRs, e.g. mstatus.mie for critical sections, mcause in interrupts handlers, etc. Defining function wrappers for accessing these registers creates easier to understand code, however writing these wrappers is pretty tedious.

The quick reference on this blog is generated from a YAML description (csr.yaml). Using that with a web template engine script (generators/ and a template (templates/riscv-csr.h) code can be easily generated.



October 11, 2020|Updates (,spec)

The User ISA and Privileged ISA have been updated to tag draft-20201007-16f5002 in the upstream repo and re-generated as HTML.

The upstream changelog from git is:


RISC-V Instructions Quick Reference

May 16, 2020|Updates (isa,quickref)

Added details on how to call instructions from C, listed the CSR instructions, and linked the instruction groups.


RISC-V CSRs Quick Reference

May 16, 2020|Isa (csr,quickref)

Added details on how to access CSRs from C.


RISC-V CSRs Quick Reference

May 03, 2020|Updates (registers,quickref)

Updated CSR quick reference page

  • Linked debug registers.
  • Made table sortable.
  • Added feature/extension classification.

RISC-V Instructions/Extensions Quick Reference

January 21, 2020|Isa (registers,toolchain,quickref)

A few more quick reference pages:


January 02, 2020|Updates (,spec)

The User ISA and Privileged ISA have been updated to tag draft-20191228-a6c204f in the upstream repo and re-generated as HTML.

The upstream changelog from git is:


RISC-V Tools Quick Reference

October 29, 2019|Toolchain (toolchain,quickref)

An initial toolchain quick reference.


RISC-V Registers Quick Reference

October 29, 2019|Isa (registers,quickref)

A few more quick reference pages:

RISC-V Interrupts/Exceptions Quick Reference

August 26, 2019|Isa (interrupts,quickref)

I’ve made an attempt to understand and summarize RISC-V interrupts and exceptions. It mostly covers the machine mode interrupt model, entry and exit procedure. It also looks at supervisor mode, user mode and exceptions.



August 22, 2019|Updates (,spec)

The User ISA and Privileged ISA have been updated to tag draft-20190820-22bf021 in the upstream repo and re-generated as HTML.

This will include the ratified 1.11 spec and 1.12 draft.

The upstream changelog from git is:


RISC-V Compile Targets, GCC

June 26, 2019|Toolchain (gcc,base_isa,extensions,abi)

NOTE: Since this was written the riscv-toolchain-conventions document has been released.

Getting started with RISC-V. Compiling for the RISC-V target. This post covers the GCC machine architecture (-march), ABI (-mabi) options and how they relate to the RISC-V base ISA and extensions. It also looks at the multilib configuration for GCC.




May 15, 2019|Updates

I’ve setup this this blog to capture information I’ve found useful to develop RISC-V embedded firmware.

My experience is with bare metal RV32EC based systems. Previously I have worked with ARM Cortex-M0 and other processors, so initially I’ll capture the information needed to bootstrap such firmware and the gotchas that come from not yet thinking in RISC-V terms.

Some of the initial planned material is:

  • ISA information presented as easy to reference HTML.
  • Low level information for getting started with the RISC-V architecture.
  • Some evaluation of how RISC-V compares to other architectures.