STM32: printf retarget - bitte um Erklärung

OP #3770651
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
Gast #3770677
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.
OP #3770684
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?
Gast #3770689
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.
Gast #3770883
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.
OP #3771601
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren