Hello World example

This example shows a simple hello-world firmware image, with a single thread and a single compartment. This uses the debug facilities to write a message directly to the UART.

The xmake.lua file contains the build instructions for this example. This file contains two libraries (one providing memcpy, the other clz) that can be used by multiple compartments, and a single compartment (beyond the RTOS components).

The code for the compartment is all in hello.cc. This file first imports the debug facilities:

using Debug = ConditionalDebug<true, "Hello world compartment">;

The ConditionalDebug template is intended to allow the first argument to be an expression that may include macro definitions so that debugging can be selectively enabled for subsets of a program at build time. For now, we're just enabling it unconditionally so that we can use its log method to write to the UART.

This will, indirectly, use the MMIO_CAPABILITY macro, which imports a memory-mapped I/O device, the target platform's default UART. Our example compartment will be granted direct access to the UART, which it can then use from its entry point function, say_hello.

Note that the definition of this function uses a macro to indicate the compartment that it is in ("hello"). This macro is normally used on function definitions, rather than declarations, and allows the compiler to either export the function when it is defined or insert cross-compartment calls when it is used when compiling code for another compartment.

We also include the SDK header fail-simulator-on-error.h. This defines a simple compartment error handler that reports any unexpected errors and ends the simulation with exit code 1 (FAILURE). This is necessary because the default behaviour would silently exit the thread, potentially hiding errors.