Forum: Mikrocontroller und Digitale Elektronik STM32: printf retarget - bitte um Erklärung


von Jan B. (diphthong)


Lesenswert?

Hallo an alle,

bei diesem Beispielprojekt:

http://vedder.se/2012/07/get-started-with-stm32f4-on-ubuntu-linux/

(siehe „A simple example project“) wird anscheinend die Standard printf 
Funktion genutzt, um über die serielle Schnittstelle (hier: USART2) 
etwas auszugeben. Nun scheint das retargetting insgesamt ja recht 
kompliziert zu sein - hier läuft es aber anscheinend ausschließlich über 
die src/syscalls.c, konkret über die
1
int _write(int file, char *ptr, int len)
 Funktion. Wenn man da einen anderen USART in USART_SendData auswählt, 
funktoniert die printf AUsgabe zumindest nicht mehr. Ansonsten scheint 
nirgends im Projekt eine Information über das Retargetting gegeben zu 
sein.
Wenn ich nun aber die syscall.c in ein anderes Projekt übernehme (das 
lässt sich auch kompilieren), funktioniert die Ausgabe über printf nicht 
mehr - stattdessen hängt sich der Controller beim Funktionsaufruf auf.
Woran liegt das? Wenn das andere Projekt benötigt wird, stelle ich das 
hier auch nochmal zur Verfügung.

Danke und
Grüße
Jan

von so kenn ick es (Gast)


Lesenswert?

Was heisst denn retargetting für dich?

Ohne jetzt den Code zu sehen, kenne ich die Umlenkung der printf durch 
austauschen der untersten aufgerufenen Funktion. Oft putchar und 
getchar, die auf die HW zugreifen und angepasst werden müssen. Die 
anderen höher angesiedelten Funktionen enthalten keine HW spezifischen 
Anteile.

von Jan B. (diphthong)


Lesenswert?

So habe ich mir das vorgestellt. Hier nochmal die ganze _write Funktion:
1
int _write(int file, char *ptr, int len) {
2
  int i;
3
4
  for(i = 0;i < len;i++) {
5
    USART_SendData(USART2, (uint8_t)ptr[i]);
6
    while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET){};
7
  }
8
9
  return len;
10
}

Nur warum funktioniert das in dem einen Projekt und in dem anderen nicht 
bzw. wie sage ich der stdlib, dass ich meine eigene Sendefunktion nutzen 
möchte?

von Dr. Sommer (Gast)


Lesenswert?

Jan B. schrieb:
> stattdessen hängt sich der Controller beim Funktionsaufruf auf.
An welcher Stelle genau? Was sagt der Debugger? Tritt eine Exception 
auf? Wie sind deine UART's initialisiert? Hast du mal per Debugger 
festgestellt, ob deine _write überhaupt aufgerufen wird? Oder was 
printf() sonst aufruft?
Kompilierst du als C++, dann muss noch ein extern "C" an die Funktion 
dran.

von Prinz (Gast)


Lesenswert?

Hast du in der write Funktion einfach USART2 eingesetzt? Dann fehlt noch 
die Initialisierung. Such doch über das Projekt nach dem Text USART. 
Dann solltest du auch die Initialisierung finden und kannst sie um die 
USART2 erweitern.

von Jan B. (diphthong)


Lesenswert?

Problem war die fehlende Hardware VPF Unterstützung (-mfloat-abi=hard 
Flag im Makefile), danach wurden Strings nur bis zu einem bestimmten 
Zeichen gesendet und printf hat sich aufgehängt, im Linker script (.ld) 
musste der Speicher angepasst werden:
1
/* Specify the memory areas */
2
MEMORY
3
{
4
  FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 1024K
5
  RAM (rwx)       : ORIGIN = 0x20000000, LENGTH = 128K
6
  CCM (rwx)       : ORIGIN = 0x10000000, LENGTH = 64K
7
  MEMORY_B1 (rx)  : ORIGIN = 0x60000000, LENGTH = 0K
8
}
So funktioniert es. Kann man das so lassen, ist das soweit mit den 
Speicherbereichen korrekt?

Danke und
Grüße
Jan

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.