mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik STM32 - printf


Autor: Mirco H. (mirq)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich möchte mittels printf() über die serielle Schnittstelle des 
MCBSTM32-Boards schreiben. Nutze die StdPeriph_Lib und Keil-IDE.
Entsprechend printf-Example habe ich einen Prototypen für putchar und 
die <stdio.h> included. Ergebnis sind 0 Compiler Errors und 0 Linker 
Errors, aber mein Programm bleibt hängen.
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)

int main(void)
{
  Init();
  while(1)
  {
    GPIOB->BSRR = GPIO_Pin_8;
    wait();
    //USART_SendData(USART1, (uint8_t) 65);
    GPIOB->BRR = GPIO_Pin_8;
    wait();
    printf("a");  
  }
}

void wait(void)
{
  for(i=0; i<0xFFFFF; i++)
  {
    a = a + i;
  }
}
  
PUTCHAR_PROTOTYPE
{
  /* Place your implementation of fputc here */
  /* e.g. write a character to the USART */
  USART_SendData(USART1, (uint8_t) ch);

  /* Loop until the end of transmission */
  while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
  {}

  return ch;
}

Wenn ich die pritnf("a")-Zeile auskommentiere und die andere in der 
while(1) einkommentiere funktioniert alles; LED toggelt und A wird 
gesendet. So wie oben passiert garnichts. Im Projekt sind 
stm32f10x_usart.c, stm32f10x_gpio.c, stm32f10x_rcc.c und misc.c.

Hat jemand einen Tip?

Grüße, Mirco

Autor: Random ... (thorstendb) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
schau mal bitte in die examples des MCBSTM32.
Dort findest du Code, der leicht lesbar ist und läuft, ohne driver 
library.

Ausserdem findest du in der datei "retarget.c" in einigen der Beispiele 
ein minimal retargeting, was du verwenden solltest.

Ebenso kannst du die ITM_Sendchar() Funktion aus der CMSIS verwenden, 
die daten kommen beim Debuggen im ITM/printf Viewer (View Menue) an. 
Terminalsequenzen sind auch möglich seit UV4, ausserdem gibt es ein paar 
neue interessante Terminal Modes.

Eingabe ist auch möglich (memory write), direkt im ITM window, entweder 
aktuelle CMSIS GetChar, oder:

volatile unsigned int ITM_RxBuffer;        // 0x5AA55AA5 is handshake value

// ITM Serial Window Input Watch and Init function
void ITMRx_InInit(void) {
  ITM_RxBuffer = 0x5AA55AA5;
}

int ITMRx_Getc(void) {
  int recChar=0;                    // zero is default if no new char recv
  
  if(ITM_RxBuffer != 0x5AA55AA5)
  {
    recChar = ITM_RxBuffer & 0xff; 
    ITM_RxBuffer = 0x5AA55AA5;  
  }
  return(recChar);
}

DL und Code zu mischen ist meist eine schlechte Idee, am besten die DL 
als Beispielcode nutzen.



VG,
/th.

Autor: Random ... (thorstendb) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Anmerkung:

die ITMRx_Getc() in meinem Beispiel ist non-blocking, d.h. sie liefert 
NULL oder ein valid char zurück.

Für die Verwendung mit scanf() muss im fgetc - retarget eine schleife 
eingebaut werden, die auf valid char prüft und erst dann (diesen) 
zurückliefert.


VG,
/th.

Autor: Star Keeper (starkeeper)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also mich wundert es etwas, dass du printf einfach so verwenden können 
sollst. Normalerweise sind ja für printf noch einige andere 
Basis-Funktion notwendig die der Entwickler implementieren muss, damit 
printf funktioniert. Ist das bei Keil schon alles geschehen?

Kannst du in das printf hinein steppen? Kommst du bei deiner 
putchar-Funktion an? Gibt es eventuell beim Ausführen von Printf eine 
Exception, die dein Debugger aber nicht fängt?

Autor: Random ... (thorstendb) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

So im Groben:
fopen --> lib  --> _sys_open
printf --> fputc --> lib --> _sys_write
scanf --> fgetc --> lib --> _sys_read
fclose --> lib --> _sys_close

Für ein einfaches Retargeting reicht es, die fputc zu überladen, 
use_no_semihosting zu verwenden und noch ein paar wenige 
Zusatzfunktionen, die von der libc benötigt werden, einzubauen
--> siehe retarget.c

Will man ein komplettes Konzept basierend auf den file streaming 
funktionen aufbauen, muss man auf die _sys_x - ebene runter (siehe 
RTAgent.c), und dort einen IO Layer einziehen.


VG,
/th.

Autor: Mirco H. (mirq)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Danke Thorsten für den Tip mit Retarget.c!
Dort kann man sehen dass FILE eine Struktur ist und wie sie 
initialisiert wird.
Habe in meinen Code noch die beiden folgenden Zeilen eingefügt. Dann hat 
alles funktioniert.
struct __FILE { int handle; /* Add whatever you need here */ };
FILE __stdout;


Bei meinem Projekt muss ich auf bereits bestehendem Code aufbauen und in 
diesem sind die std driver verwendet worden... Deshalb wollte ich es auf 
diese Weise lösen.
Danke für die ausführlichen Beschreibungen.

Grüße, Mirco

Autor: Axel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe das selbe Problem nur komme ich auch mit den angegebenen Hilfen 
nicht weiter. fputc habe ich schon überladen, mit dem ganz oben 
beschriebenen Code. Ich benutzt eine IAR Umgebung und habe alle 
wichtigen Header eingebunden. Zusätzlich auch noch DLIB_Config, 
DLIB_Default etc.
Dort wird dann FILE deklariert. Meine Fehler geschieht zur Laufzeit und 
zwar direkt nach dem Übergang in den Debug Modus derartig, dass ich 
keine Möglichkeit habe Breakpoints zu setzten.

Nun würde ich gerne wissen was ich hiermit anfangen kann:

Random ... schrieb:
> printf --> fputc --> lib --> _sys_write

Wo kann ich mir die Funktion fputc anschauen um eventuell weitere 
Informationen darüber zu erhalten.

Random ... schrieb:
> use_no_semihosting zu verwenden und noch ein paar wenige
> Zusatzfunktionen, die von der libc benötigt werden, einzubauen
> --> siehe retarget.c

Diese Retarget.c gibt es in meiner Entwicklungsumgebung nicht unter 
Beispielen. Wie kann ich use_no_semihosting vermenden?
Im Netz habe ich nur die üblichen Informationen (printf, scanf 
formatierung etc.) im Umgang mit stdio.h gefunden, kennt jemand 
vielleicht einen Link der darauf tiefer eingeht?

Ich bin ebenfalls gezwungen in diesem Projekt auf die Library 
zuzugreifen. Auf dem Demoboard funktionieren Ein- und Ausgabe wunderbar 
und deswegen bin ich hier am verzweifeln. Vielen Dank für eure 
Aufmerksamkeit schon mal vorab und viele Grüße
Axel

Autor: Axel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok, use_no_semihosting ist wohl keil IDE eigen. Die lib finde ich leider 
immernoch nicht! Gruß Axel

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.