Forum: Mikrocontroller und Digitale Elektronik Probleme mit printf auf STM32F4xx. Printf schluckt immer das letzte newline


von M. Н. (Gast)


Lesenswert?

Hallo,
ich habe hier einen ARM STM32F4, auf dem ich gerne printf nutzen würde, 
um Debug ausgaben zu machen. Dazu habe ich den Uart aktviert (tut). 
Dieses Modul stellt eine uart_send_string() funktion zur Verfügung. Tut 
auch.

Um printf zu nutzen habe ich nun die Systemaufrufe _sbrk (für Heap)  und 
_write angelegt. _write leitet alles auf die uart_send_string() funktion 
um.

Das Verhalten ist nun aber merkwürdig. Wenn ich ein printf("Hallo\n"); 
ausführe, werden zwei bytes an die uart_send_string() Funktion übergeben 
0xB9 und 0x0B. Unabhängig vom Inhalt des printf's.

Habe daraufhin mit     setvbuf(stdout, NULL, _IONBF, 0); Das Puffern 
deaktiviert.

Jetzt funktioniert printf einigermaßen. Es schluckt jedoch immer das 
'\n', wenn es das letzte Zeichen im String ist.

Ich liste mal einige Strings auf, wie ich sie in printf schreibe und was 
gesendet wird:

Hallo\n => Hallo
Hallo\nHallo\n => Hallo\nHallo
Hallo\nA => Hallo\nA

Es schluckt einfach immer das letzte newline-Zeichen. Ein weiteres 
printf danach oder ein fflush(stdout) helfen nicht. Das Zeichen ist weg.

Kann mir jemand erklären, warum das passiert? Werkle da jetzt schon 
einige Stunden rum.

Edit:

puts("Hallo\nHallo\n") tut was es soll.

Es könnte auch am Heap liegen. Dieser tut aber soweit. Habe einige 
mallocs in Betrieb, die alle funktionieren.

von Jim M. (turboj)


Lesenswert?

GCC ersetzt `printf('String\n');` durch denn equivalenten 
`puts('String');` Funktionsaufruf.

Das `puts()` soll laut Doku das trailing newline automagisch anhängen.

Schau mal in Deiner `_write()` Implementation nach, was bei einem 
ein-Byte `_write()` so passieren kann - ich tippe auf off-by-one Fehler.

Eine möglicher Würgaround wäre: `printf('%s','String\n');`

von M. Н. (Gast)


Lesenswert?

Jim M. schrieb:
> Das `puts()` soll laut Doku das trailing newline automagisch anhängen.

Tut es nicht. Allerdings schneidet es ein \n auch nicht ab. Das tut 
also.

Jim M. schrieb:
> Schau mal in Deiner `_write()` Implementation nach, was bei einem
> ein-Byte `_write()` so passieren kann - ich tippe auf off-by-one Fehler.

Habe einen Breakpoint in der _write Funktion und schaue mir den 
übergebenen String im Debugger an. Das \n fehlt auch hier. Gegen den 
off-by-one Fehler spricht, dass das letzte Zeichen ausgegeben wird, wenn 
es kein \n ist. "Hallo\nA" wird korrekt ausgegeben.

von M. Н. (Gast)


Lesenswert?

Okay. Ist mir jetzt etwas peinlich, habe es aber grade selbst 
herausgefunden.

Meine write Funktion sieht so aus:
1
int _write(int fd, const void *buf, int count) {
2
  uart_send_string((char*)buf, count);
3
  return 0;
4
}

Das sollte natürlich nicht null zurückliefern sondern so aussehen:
1
int _write(int fd, const void *buf, int count) {
2
  uart_send_string((char*)buf, count);
3
  return count;
4
}

Vielen Dank für eure Hilfe!

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.