This post is a draft for Medium.
Is it possible to write pure modern C++ baremetal firmware from ground up for RISC-V?
The answer is a qualified yes.
- The toolchain using Platform IO supported modern C++ with a small configuration change.
- The startup code required some assembly, but was mostly was very readable C++.
- Drivers accessed via MMIO could be completely abstracted if it added value - or simply provide convenient access to hardware registers.
- We can specify system clock delays in human readable units with zero run time cost.
- Access to special system registers could be abstracted, and I propose we can abstract standard and custom instructions via C++ to take full advantage of RISC-V.
- Interrupts were not so simple, while we can use them as C++ lambda’s it’s not a zero-cost abstraction and the implementation was not straight forward.
How useful is C++ at this level? Zero cost abstractions can be built that make software development simpler, more efficient and also easier to verify.
- Object oriented abstractions can be made more efficient than traditional C abstractions via static polymorphism and compile time evaluation (constexpr/consteval).
- The same object oriented abstractions can also simplify verification by making interfaces interchangeable, which can simplify unit testing and mock interfaces. For example, we could replace the timer driver with a host emulation version. We could even replace the MMIO and system register classes with a mock and run all this code via host emulation.
On to the downsides, the standard library is not specialized for environments with low memory and no host operating system. The full features of the language are not available, and the freestanding subset has been defined as a subset of the standard hosted implementation. However, this is still a work in progress.
C++ has become very complex, so the learning curve is higher, and there is a greater chance of making mistakes that are hidden by abstraction and language complexity. The impact of such mistakes that are hidden by abstraction and language complexity is greater in the resource constrained and often safety critical environment of embedded systems compared to hosted software. Coding standards should be used.
RISC-V provides an open architecture to replace older proprietary cores. It probably wont replace ARM Cortex-* - a set of modern architectures designed for embedded and mobile systems - any time soon. But at the periphery where custom and legacy cores, even as old as the 8051, still find uses it I expect we will see appear and take hold. The benefit of a readily available core IP with different pricing models, maturing tool chains and infrastructure with investment from many companies using the open development model. The model has shown to be a success with Linux will and will make it a disruptive innovation.
As an open architecture we can also expect RISC-V will enable new innovation. This is by lowering the barrier to entry for extending the processor and integrating peripherals, such as accelerators, with the processor core. With this the opportunity to extend the ISA etc, C++ is a good tool to abstract such extensions to make them usable to software.
Subscribe via RSS