Picolibc Hello World Example
It's hard to get started building applications for embedded RISC-V and ARM systems. You need to at least:
- Find and install the toolchain 
- Install a C library 
- Configure the compiler for the right processor 
- Configure the compiler to select the right headers and libraries 
- Figure out the memory map for the target device 
- Configure the linker to place objects in the right addresses 
I've added a simple 'hello-world' example to picolibc that shows how to build something that runs under qemu so that people can test the toolchain and C library and see what values will be needed from their hardware design.
The Source Code
Getting text output from the application is a huge step in embedded
system development. This example uses the “semihosting” support
built-in to picolibc to simplify that process. It also explicitly
calls exit so that qemu will stop when the demo has finished.
#include <stdio.h>
#include <stdlib.h>
int
main(void)
{
    printf("hello, world\n");
    exit(0);
}
The Command Line
The hello-world documentation
takes the user through the steps of building the compiler command line, first using the picolibc.specs file to
specify header and library paths:
gcc --specs=picolibc.specs
Next adding the semihosting library with the --semihost option (this is an option defined in picolibc.specs which places -lsemihost after -lc):
gcc --specs=picolibc.specs --semihost
Now we specify the target processor (switching to the target compiler here as these options are target-specific):
riscv64-unknown-elf-gcc --specs=picolibc.specs --semihost -march=rv32imac -mabi=ilp32
or
arm-none-eabi-gcc --specs=picolibc.specs --semihost -mcpu=cortex-m3
The next step specifies the memory layout for our emulated hardware, either the 'spike' emulation for RISC-V:
riscv64-unknown-elf-gcc --specs=picolibc.specs --semihost -march=rv32imac -mabi=ilp32 -Thello-world-riscv.ld
with hello-world-riscv.ld containing:
__flash = 0x80000000;
__flash_size = 0x00080000;
__ram = 0x80080000;
__ram_size = 0x40000;
__stack_size = 1k;
INCLUDE picolibc.ld
or the mps2-an385 for ARM:
arm-none-eabi-gcc --specs=picolibc.specs --semihost -mcpu=cortex-m3 -Thello-world-arm.ld
with hello-world-arm.ld containing:
__flash =      0x00000000;
__flash_size = 0x00004000;
__ram =        0x20000000;
__ram_size   = 0x00010000;
__stack_size = 1k;
INCLUDE picolibc.ld
Finally, we add the source file name and target elf output:
riscv64-unknown-elf-gcc --specs=picolibc.specs --semihost
-march=rv32imac -mabi=ilp32 -Thello-world-riscv.ld -o
hello-world-riscv.elf hello-world.c
arm-none-eabi-gcc --specs=picolibc.specs --semihost
-mcpu=cortex-m3 -Thello-world-arm.ld -o hello-world-arm.elf
hello-world.c
Summary
Picolibc tries to make things a bit simpler by offering built-in compiler and linker scripts along with default startup code to try and make building your first embedded application easier.
