Printf in BareMetal (PI4): Unterschied zwischen den Versionen

Aus C und Assembler mit Raspberry
KKeine Bearbeitungszusammenfassung
KKeine Bearbeitungszusammenfassung
Zeile 1: Zeile 1:
== printf ==
== printf ==


Bis hierhin haben wir vieles selbst gemacht. Wir haben einen Weg gefunden, wie der Raspberry Pi Texte auf den Bildschirm anzeigen kann. Allerdings hat unsere `DrawString`-Funktion nicht viele Vorteile. Viele kennen wahrscheinlich die `printf`-Funktion aus der Programmiersprache C. Diese Funktion kann formatierte Ausgaben erzeugen, bei denen auch Variablen eingebunden werden können. Da wir in einer Umgebung ohne Betriebssystem programmieren (BareMetal-Umgebung), können wir diese vorgefertigte Funktion nicht direkt nutzen und müssen sie selbst programmieren. `printf` ist eine sehr mächtige Funktion.
Bis hierhin haben wir vieles selbst gemacht. Wir haben einen Weg gefunden, wie der Raspberry Pi Texte auf den Bildschirm anzeigen kann. Unsere DrawString-Funktion hat jedoch nicht viele Vorteile. Viele kennen wahrscheinlich die printf-Funktion aus der Programmiersprache C. Diese Funktion kann formatierte Ausgaben erzeugen, bei denen auch Variablen eingebunden werden können. Da wir in einer Bare-Metal-Umgebung ohne Betriebssystem programmieren, können wir diese vorgefertigte Funktion nicht direkt nutzen und müssen sie selbst programmieren. printf ist eine sehr mächtige Funktion.


Bei einer kleinen Recherche im Internet habe ich herausgefunden, dass bereits einige Leute diese Funktion für ähnliche Projekte programmiert haben. Also kam schnell die Idee auf, eine solche Lösung in unser Projekt einzubinden.
Bei einer kleinen Recherche im Internet habe ich herausgefunden, dass bereits einige Leute diese Funktion für ähnliche Projekte programmiert haben. Also kam schnell die Idee auf, eine solche Lösung in unser Projekt einzubinden.


Ich habe mich für die `printf`-Version von Kustaa Nyholm entschieden, da diese einfach einzubinden ist und die Funktionen unterstützt, die wir für die weitere Entwicklung benötigen.
Ich habe mich für die printf-Version von Kustaa Nyholm entschieden, da diese einfach einzubinden ist und die Funktionen unterstützt, die wir für die weitere Entwicklung benötigen.


Die Bibliothek kann hier heruntergeladen werden: [http://www.sparetimelabs.com/tinyprintf/tinyprintf.php Tinyprintf]
Die Bibliothek kann hier heruntergeladen werden: [http://www.sparetimelabs.com/tinyprintf/tinyprintf.php Tinyprintf]


Das ZIP-Archiv enthält nur zwei Dateien. Die Datei `printf.c` speichern wir in unser Hauptverzeichnis und die Datei `printf.h` in das Include-Verzeichnis.
Das ZIP-Archiv enthält nur zwei Dateien. Die Datei printf.c speichern wir in unser Hauptverzeichnis und die Datei printf.h in das Include-Verzeichnis.


In der Datei `printf.h` ist beschrieben, wie man die Funktionen in sein eigenes Projekt einbindet.
In der Datei printf.h ist beschrieben, wie man die Funktionen in sein eigenes Projekt einbindet.


== Änderungen im Main-Programm ==
== Änderungen im Main-Programm ==
Zeile 43: Zeile 43:
</syntaxhighlight>
</syntaxhighlight>


In der Anleitung steht, dass man das `printf`-System initialisieren muss. Dies wird durch den Befehl `init_printf(0, putc);` durchgeführt.
In der Anleitung steht, dass man das printf-System initialisieren muss. Dies wird durch den Befehl init_printf(0, putc); durchgeführt.


Hier verwende ich anschließen printf um meinen Titel im Terminal anzuzeigen.
Hier verwende ich anschließend printf, um meinen Titel im Terminal anzuzeigen.


Zusätzlich müssen wir noch eine `putc`-Funktion erstellen, die einfach nur auf die `DrawCharAtCursor`-Funktion verweist:
Zusätzlich müssen wir noch eine putc-Funktion erstellen, die einfach nur auf die DrawCharAtCursor-Funktion verweist:


<syntaxhighlight lang="C">
<syntaxhighlight lang="C">
Zeile 59: Zeile 59:
== Warum nicht alles selbst programmieren? ==
== Warum nicht alles selbst programmieren? ==


Grundsätzlich möchte ich hiermit beschreiben, dass es manchmal keinen großen Sinn macht, alles selbst zu programmieren. Der Code, den ich hier für `printf` verwende, wurde bereits 2004 geschrieben. Also ein Code, der nun gut 20 Jahre alt ist. Und er funktioniert immer noch!
Grundsätzlich möchte ich hiermit beschreiben, dass es manchmal keinen großen Sinn macht, alles selbst zu programmieren. Der Code, den ich hier für printf verwende, wurde bereits 2004 geschrieben. Also ein Code, der nun gut 20 Jahre alt ist. Und er funktioniert immer noch!


Du kannst den Source-Code als ZIP-Datei mit folgenden Link downloaden: https://www.satyria.de/arm/sources/RPI4/C/7.zip
Du kannst den Source-Code als ZIP-Datei mit folgenden Link downloaden: https://www.satyria.de/arm/sources/RPI4/C/7.zip

Version vom 6. März 2025, 13:47 Uhr

printf

Bis hierhin haben wir vieles selbst gemacht. Wir haben einen Weg gefunden, wie der Raspberry Pi Texte auf den Bildschirm anzeigen kann. Unsere DrawString-Funktion hat jedoch nicht viele Vorteile. Viele kennen wahrscheinlich die printf-Funktion aus der Programmiersprache C. Diese Funktion kann formatierte Ausgaben erzeugen, bei denen auch Variablen eingebunden werden können. Da wir in einer Bare-Metal-Umgebung ohne Betriebssystem programmieren, können wir diese vorgefertigte Funktion nicht direkt nutzen und müssen sie selbst programmieren. printf ist eine sehr mächtige Funktion.

Bei einer kleinen Recherche im Internet habe ich herausgefunden, dass bereits einige Leute diese Funktion für ähnliche Projekte programmiert haben. Also kam schnell die Idee auf, eine solche Lösung in unser Projekt einzubinden.

Ich habe mich für die printf-Version von Kustaa Nyholm entschieden, da diese einfach einzubinden ist und die Funktionen unterstützt, die wir für die weitere Entwicklung benötigen.

Die Bibliothek kann hier heruntergeladen werden: Tinyprintf

Das ZIP-Archiv enthält nur zwei Dateien. Die Datei printf.c speichern wir in unser Hauptverzeichnis und die Datei printf.h in das Include-Verzeichnis.

In der Datei printf.h ist beschrieben, wie man die Funktionen in sein eigenes Projekt einbindet.

Änderungen im Main-Programm

Zuerst ändern wir unser Main-Programm:

// main.c

#include "led.h"
#include "screen.h"
#include "types.h"
#include "printf.h"

int main(void)
{
    LED_off();
    Init_Screen();
    init_printf(0, putc);

    SetFrontColor(0x80, 0xa0, 0xff);
    printf("*****************************************************************************************\n");
    printf("***                                                                                   ***\n");
    printf("***                               (c) by Satyria                                      ***\n");
    printf("***                                                                                   ***\n");
    printf("*****************************************************************************************\n\n");
    SetFrontColor(0xff, 0xff, 0xff);

    LED_Error(2);
}

In der Anleitung steht, dass man das printf-System initialisieren muss. Dies wird durch den Befehl init_printf(0, putc); durchgeführt.

Hier verwende ich anschließend printf, um meinen Titel im Terminal anzuzeigen.

Zusätzlich müssen wir noch eine putc-Funktion erstellen, die einfach nur auf die DrawCharAtCursor-Funktion verweist:

void putc(void* p, char c)
{
    //UartPutc(c);
    DrawCharAtCursor(c); //Verwendung von printf im Terminal
}

Warum nicht alles selbst programmieren?

Grundsätzlich möchte ich hiermit beschreiben, dass es manchmal keinen großen Sinn macht, alles selbst zu programmieren. Der Code, den ich hier für printf verwende, wurde bereits 2004 geschrieben. Also ein Code, der nun gut 20 Jahre alt ist. Und er funktioniert immer noch!

Du kannst den Source-Code als ZIP-Datei mit folgenden Link downloaden: https://www.satyria.de/arm/sources/RPI4/C/7.zip

Zukunft

Diesen Teil des Textes werde ich hier wieder löschen, wenn ich es geschafft habe, USB auf dem Raspberry Pi 5 zum Laufen gebracht zu haben. Während ich dies hier schrieb, bin ich bereits dabei, dies zu entwickeln. Aber leider bisher noch ohne Erfolg. Problematisch war bereits bei der Einführung des Raspberry Pi 4, dass es keine passenden Beschreibungen für die USB-Anbindung gab. Es gibt bisher nur ein einziges Projekt (Circle), welches das unterstützt. Allerdings ist dies recht schwierig, in ein eigenes Projekt umzusetzen, da dort sehr viele Abhängigkeiten existieren, die nicht einfach aufgelöst werden können. Relativ schnell hat hier René Stange vom Projekt Circle eine Umsetzung für den Raspberry Pi 5 veröffentlicht, aber auch hier ist das gleiche Problem wie beim Pi 4.

Dennoch habe ich mir vorgenommen, einen Weg zu finden, um zumindest eine Tastatur und Maus über die USB-Schnittstelle zur Verfügung zu stellen. Eventuell wird es einen Bibliothek, die man dann einfach einbinden kann. Dies sollte so einfach wie möglich sein, sodass dann viele Projekte darauf folgen können.


< Zurück (Das Terminal in C (PI4)) < Hauptseite > Weiter (xxx) >