Forum: Mikrocontroller und Digitale Elektronik LPC2xxx: UART + printf()


von Jürgen E. (sid)


Lesenswert?

Hallo, (ich bins schon wieder)

normalerweise verwende ich zu Debug zwecken ganz gerne den UART. Und
damit man "schöne" Ausgaben erhält, und diese möglichst einfach,
verwend ich (zumindest am AVR) printf() indem ich einfach mit
fdevopen() der stdout Kanal in eine UART Sende Funktion "umpippe".

Doch das scheint am ARM nicht so einfach zu gehen...
Ich habe zwar eine printf() Funktion die ich anpassen und mit rein
kompilieren könnte, doch ist das wohl nicht die feine englische Art.
Und das ioctl() aus der lpc-newlib will ich auch nicht unbedingt
nehmen, da ich den UART selber initialisieren will (und so).

Doch auf der Seite von mthomas (der in der Beziehung ein ziemlich
krasser Guru zu sein scheint - *fett respekt alter...*) hab ich was
ganz interesantes gefunden: Das Bsp. nennt sich lpc2129_adc_stdio.
Da drinnen gibt es eine Datei die nennt sich syscalls.c In der werden
die Känle "umgepippt" in Funktionen die man eintragen kann. Doch
dummerweise wird diese Datei in keiner anderen includiert. Sie steht
nur kurz im Makefile drinnen.

Lange Rede kurzer Sin:
Wo ist der Trick dabei? Oder bin ich einfach nur Blind?
Weil die Datei einfach mit zu kompilieren und zu linken reicht nicht!
Irgendwo fehlt da noch ein kleiner Trick. Mein Prozessor bleibt einfach
beim printf() momentan stehen.

THX
Jürgen

von Ppp M. (sanic)


Lesenswert?

Hallo Jürgen,

das printf() kannst du von Ulrich Radigs Seite verwendet.
In der ARM-Sektion findest du bei seinem SD/MMC-Card Code eine .c Datei
wo ein printf() drin ist.
Das verbraucht bei mir minimal Platz und funktioniert super.
Mit dem Umpipen und dem ganzen anderen Kram hatte ich nur Probleme und
es hat pervers viel Platz eingenommen.

Grüße,
Patrick

von mthomas (Gast)


Lesenswert?

syscalls definiert Funktionen mit bekanntem Namen, die von der Library
unter genau diesen Namen erwartet werden. Die Library sucht unter den
gesetzten Namen (in der Lib. in der Art "extern <bekannter Name>
deklariert). Daher kein Include irgendwo sondern nur "Bereitstellung
der Objekte". UART kann man "von Hand" initialisieren man muss die
write-Funktion und sbrk (printf braucht malloc, malloc braucht sbrk)
wie  bei syscall.c bereitstellen. Bei newlib iprintf verwenden, falls
man kein FP braucht - Speicherbedarf ist deutlich kleiner als bei
"normalem" printf mit floating-point-supprot (aber immer noch hoch).
Bei newlib-lpc ist all dies noch einfacher und gut "vorgekaut": Man
kein einen Stream per Devicenamen offenen ("COM1"/"COM2"). Mein
Beispiel "adc-stdio" ist nur eine stark reduziert Fassung der
newlib-lpc-Variante.
Deutlich kompakter sind die "mini-frintfs" wie z.B. die, auf die
Patrick verwiesen hat. Gute Variante findet man auch bei Holger
Klabunde (google findet) und eine lizenzfreie recht alte Version
irgendwo in den Tiefen des circuit cellar Artikel-Archivs.

von Jürgen E. (sid)


Lesenswert?

Ok, ihr habt mich überzeugt... Ich nutze jetzt eine eigene printf()
Funktion zum Debugen....


THX

von Danielb (Gast)


Lesenswert?

Jürgen, kannst du bitte deine printf() Funktion posten?

Gruß
Daniel

von Jürgen E. (sid)


Angehängte Dateien:

Lesenswert?

Puh... Lang ists her...

Im Anhang ist das drinnen was du suchst. Einfach den UART
initialisieren (mit UART_0Init(parameter) oder so) und dann kannst du
auch schon printf() nutzen.

MfG
Jürgen

von Danielb (Gast)


Lesenswert?

Dankeschön :)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.