www.mikrocontroller.net

Forum: Compiler & IDEs printf bei armgcc


Autor: Tilo L. (katagia)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Ich will printf verwenden, um per Uart Daten auszugeben.

Die Datenausgabe mit meiner eigenen Funktion UartWrite() funktioniert 
problemlos.

Leider hat mir google verschiedenste Lösungen angeboten, die alle nicht 
taten.

Ich habe in meinem Hauptprogramm die Funktion int __putchar(int ch) 
definiert. Sie wird allerdings von printf nicht aufgerufen.

Ich habe auch int putchar(int ch) versucht, dann erhalte ich folgende 
Fehlermeldung, die ich gar nicht verstehe:

main.c:9: error: expected identifier or '(' before '--' token
make: *** [main.o] Error 1

Ich habe bisher mit printf etc. noch nicht gearbeitet und stehe ein 
wenig auf dem Schlauch.

Wer weiß, wo mein Fehler liegt bzw. wo ich Hilfe finden könnte?

Vielen Dank,

Tilo

Autor: Teplotaxl X. (t3plot4x1)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da ich bedauerlicherweise nicht über eine Glaskugel verfüge, kann ich 
dir auch nicht weiterhelfen. Zeig doch bitte mal den ganzen Code her.

Autor: Tilo L. (katagia)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#include "ADuC7020.h"
#include "uart.h"
#include <stdlib.h>
#include <stdio.h>

void IRQ_Function(void);      // IRQ Funktion

int __putchar(int ch) {
  return UartPutChar(ch);
}

int main (void)  {
  IRQ = IRQ_Function; // Weise IRQ Funkion zu
  UartInit(115200); // Initialisiere Uart mit 115200Baud

  while (1) {
    printf("Hallo printf test.");
  }
}

void IRQ_Function (void) {
  if (IRQSTA & UART_BIT) { // Uart
    UartIrq(); // Zeichen wurde empfangen
  }
}

Das ist der vollständige Code. Durch den Aufruf von UartPutChar() kann 
direkt ein Zeichen gesendet werden.

Autor: Martin Thomas (mthomas) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Üblicherweise werden die stdio-Funktionen der newlib, die in den meisten 
Packeten mit arm-elf/eabi-gcc die libc ist, per sogen. syscalls mit der 
Hardware verbunden. Vgl. newlib Dokumentation, Implementierungsbeispiel 
z.B. newlib-lpc.

Autor: Tilo (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Danke für den Hinweis!

Ich habe mir die newlib-lpc angeschaut. Für jemanden, der die newlib 
noch nie verwendet hat, ist das erst einmal ein ganz schöner Brocken. 
Ich habe auch einiges an Dokumentation gefunden, nur die geht meist 
davon aus, dass man schon weiß, wo man hin will.

Ich habe mal die newlib-lpc angehängt. Ich habe mich am Beispiel test3.c 
orientiert.
  /**** Device table.  List of device drivers for newlib.  ****/
const struct device_table_entry *device_table[] = {
  &com1,  /* stdin  */
  &com1,  /* stdout */
  &com1,  /* stderr */
  0 };  /* end of list */

Es wird ein Array (Array aus Pointern) *device_table mit 4 Einträgen vom 
Typ device_table_entry erzeugt. "com1" ist in der uart0_int.c definiert. 
Dort sind die einzelnen Funktionen hinterlegt. device_table_entry ist in 
dev_cntrl.h hinterlegt. Soweit habe ich auch verstanden, wie die 
einzelnen Codeteile zusammenhängen.

Ein paar Dinge sind mir aber noch unklar:

1. Wo klinkt sich die newlib ein? Erwartet newlib, dass es ein Array mit 
dem Namen *device_table gibt?

2. Der Eintrag in die Tabelle für den uart sieht in uart0_int.c so aus:
/************************** com1_int ************************************/
/*  Device table entry used to add this device.        */
const struct device_table_entry com1_int = {
  "com1",        /*  Device name.    */
  uart0_open,        /*  Open method.    */
  uart0_close,      /*  Close method.    */
  uart0_read,      /*  Read method.    */
  uart0_write,      /*  Write method.    */
  uart0_ioctl,      /*  Ioctl method.    */
  0 };        /*  No per-instance data.  */
static _ssize_t uart0_write (
    struct _reent *r,      /*  Re-entrancy structure, used to make  */
        /* thread safe.        */
    int file,       /*  File handle.  Used to distinguish  */
        /* multiple instances.      */
    const void *ptr,    /*  Pointer to data to write.    */
    size_t len,      /*  Amount of data to write.    */
    SUB_DEVICE_INFO *info)  /*  Per instance information, only one  */
            /* instance so not used.    */
{
[...]

In den Kommentaren zu dieser Funktion ist als Datentyp immer von "Byte" 
die Rede. Wo ist das festgelegt? Könnte als Datentyp nicht auch short 
oder long von der newlib verwendet werden?


3. In diesem Beispiel wird stdin, stdout und stderr auf "com1" gelegt. 
Gehen wir davon aus, ich will zusätzlich ein Device per SPI ansprechen:
  /**** Device table.  List of device drivers for newlib.  ****/
const struct device_table_entry *device_table[] = {
  &com1,  /* stdin  */
  &com1,  /* stdout */
  &com1,  /* stderr */
        &spi1,
  0 };  /* end of list */

Wie kann die Ausgabe von newlib von stdout auf spi1 umgebogen werden?

Vielen Dank,

Tilo

Autor: mthomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
zu 1: Die Implementierung der syscalls in newlib-lpc "erwart" ein Array 
um zum hander die passenden Funktionen zu suchen. newlib-lpc (oder 
libsysbase von devkitpro) bietet wahrscheinlich schon ein paar mehr 
Möglichkeiten als benötigt. Man kann write etc. auch einfacher 
implementierung v.a. wenn man nur stdio/printf nur dazu verwenden will 
ein paar Ausgaben auf einen uart umzuleiten. Vgl. z.B. den Code zu 
"uVision+Codesourcery" von keil.com oder ein paar meiner Bespiele auf 
www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects

zu 2: verstehe die Frage wahrscheinlich nicht wirklich. Die syscalls 
fuer stdio-support sind dazu gedacht, einen Bytestream 
auszugeben/einzulesen.

zu 3: ja, "umbiegen" von stdout auf SPI (oder was auch immer) 
funktioniert im Prinzip - habe das aber nie selbst ausprobiert. 
Interface der Hardwarefunktionen fuer SPI-Ausgabe analog dem für UART 
implementieren und Adressen in einer device_table_entry structure 
eintragen.

Autor: Tilo L. (katagia)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
zu 1:
Ich hab schon funktionierende Funktioenen. Wie geschrieben, ich würde es 
jetzt gerne mal mit schon vorhandenen Libraries versuchen

zu 2:
OK, das wollte ich wissen. Hätte ja sein können, dass z.B. ein 
Short-Stream zugelassen ist.

Nochmals Danke für deine Hilfe!

Tilo

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.