Newlib minimal lauffähiges Beispiel
Hier stelle ich ein hochautomatisiertes und dokumentiertes Beispiel zur Verfügung, das Newlib in Aktion in QEMU zeigt .
Mit newlib implementieren Sie Ihre eigenen Systemaufrufe für Ihre Baremetal-Plattform.
Im obigen Beispiel haben wir zum Beispiel ein Beispielprogramm exit.c
:
#include <stdio.h>
#include <stdlib.h>
void main(void) {
exit(0);
}
und in einer separaten C-Datei common.c
implementieren wir das exit
mit ARM Semihosting :
void _exit(int status) {
__asm__ __volatile__ ("mov r0, #0x18; ldr r1, =#0x20026; svc 0x00123456");
}
Die anderen typischen Systemaufrufe, die Sie implementieren, sind:
write
Ergebnisse an den Host ausgeben. Dies kann entweder mit:
- mehr semihosting
- eine UART-Hardware
brk
für malloc
.
Schont das Baremetall, da wir uns nicht um Paging kümmern müssen!
TODO Ich frage mich, ob es realistisch ist, eine vorbeugende Planung der Ausführung von Systemaufrufen zu erreichen, ohne auf ein vollwertiges RTOS wie Zephyr oder FreeRTOS umzusteigen .
Das Coole an Newlib ist, dass es alle nicht-OS-spezifischen Dinge string.h
implementiert, die Sie mögen , und dass Sie nur die OS-Stubs implementieren können.
Außerdem müssen Sie nicht alle Stubs implementieren, sondern nur die, die Sie benötigen. ZB wenn Ihr Programm nur benötigt exit
, dann müssen Sie kein print
.
Der Newlib-Quelltextbaum enthält bereits einige Implementierungen, einschließlich einer ARM-Semihosting-Implementierung newlib/libc/sys/arm
, die Sie jedoch größtenteils selbst implementieren müssen. Es bietet jedoch eine solide Basis für die Aufgabe.
Die einfachste Möglichkeit, Newlib einzurichten, besteht darin, einen eigenen Compiler mit Crosstool-NG zu erstellen. Sie müssen lediglich angeben, dass Sie Newlib als C-Bibliothek verwenden möchten. Mein Setup erledigt das automatisch für Sie mit diesem Skript , das die newlib configs verwendet, die bei vorhanden sind crosstool_ng_config
.
Ich denke, C ++ wird auch funktionieren, aber TODO testet es.