Code Samples
These code samples relate to this article:
Note, this page is based on my article on Medium.
Cross Compiling to Bare Metal RISC-V with PlatformIO/Scons.
Platform IO is a development environment for embedded systems. It is built with Python and uses Scons as a build tool. Scons is itself a DSL built on Python. It is integrated with VSCode and this makes it a nice vendor independent and device independent embedded IDE.
Platform IO can give you RISC-V board support out of the box, what I’d like to cover here is:
- Customizing the build flags.
- Setting up post build tasks.
- Adding custom compilers.
- Adding custom targets/boards.
Choice of Board
To setup up a new project in Platform IO just select the board, framework and path for the files. For this exercise the choices are HiFive1 Rev B, Freedom E SDK and a custom path.
Customizing the Build Flags
Customization is done via the platformio.ini
file in the project top level directory. A build_flags
parameter has been added with options to target
for embedded C++17. In particular:
-
-nostartfiles
is used as this example includes a custom startup routine, -
-std=c++17
for all the needed modern C++ features, and -
-fno-threadsafe-statics
to prevent threadsafe code being emitted (these ensure static declarations are initialized only once).
The configuration build_flags
captures compiler, pre-processor and linker options, so -Wl,-Map,blinky.map
to generate a map file can be added here along side compiler options.
An example of build flags is:
build_flags =
-std=c++17
-O2
-g
-Wall
-ffunction-sections
-fno-exceptions
-fno-rtti
-fno-nonansi-builtins
-fno-use-cxa-atexit
-fno-threadsafe-statics
-nostartfiles
-Wl,-Map,blinky.map
Adding a Post Compile Action
To add post compile options we need to edit platform.ini
again, this time adding a helper script and additional targets.
The build system behind Platform IO is Scons. This is a Python based system, so the post build script is a python file.
The Scons environment is used to find the path to the output file,
${BUILD_DIR}/${PROGNAME}.elf
, and the toolchain objdump is found by
modifying the path to ${OBJDUMP}
. The env.subst()
will expand the
environment variables, and env.Execute()
will run the command.
The target is given a name disasm
via the
env.AddCustomTarget()
method. This ties into the platformio.ini
option targets = disasm
above.
Adding custom compilers
TODO
Adding custom targets/boards
TODO