www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik stdio retargeting probleme


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

Bewertung
0 lesenswert
nicht lesenswert
Hi Leutz,

kann mir hier jemand helfen?

Ich habe auf dem LPC2148 ein kleines retarget-system aufgesetzt, a la'
  FILE *fp_uart0=0;
  FILE *fp_uart1=0;  
  
  // initialises UART0 and gives a handle back
  fp_uart0 = th_fopen("uart0", "rw");
  if(!(fp_uart0))  return(-1);    // leave main if NULL-Pointer!
  
  // initialises UART1 and gives a handle back
  fp_uart1 = th_fopen("uart1", "rw");
  if(!(fp_uart1))  return(-1);    // leave main if NULL-Pointer!
was auch so weit funktioniert.
Damit kann ich dann
fprintf(fp_uart0, "text");

verwenden, da die fputc das eigendliche retargeting übernimmt und die 
fprintf den pointer scheinbar nur durchreicht:
int fputc(int c, FILE *f)
{
  f->functionpointer(c);  
  return(c);
}

Entweder habe ich die Funktionsweise des pointers stdout nicht 
verstanden, oder aber hier liegt was anderes im argen:
// Set up stdout
  stdout = th_fopen("uart0", "rw");
  if(!(stdout))  return(-1);    // leave main if NULL-Pointer!
Das funktioniert nicht,
error:  #137: expression must be a modifiable lvalue


aber
fprintf(stdout, "text"); 
funktioniert, bzw.
stdout->functionpointer=u0_putchar;
funktioniert auch ...

Die stdio im Keil/ARM-Compiler erstellt FILE als Typ von __FILE, was man 
dann selbst den eigenen Wünschen nach implementieren kann.
struct __FILE
{
    int handle;
    // Add whatever you want here
    int (*functionpointer)(int);
};

Weiss hier jemand Rat?

Eigendlich wollte ich weiterhin die fopen verwenden, und eine _sys_open 
implementieren. Leider schimpft der linker, trotz Implementierung der 
_sys_open, dass ich die nicht geschrieben hätte...


Leider findet man diesbezüglich auch nur recht spärlich Informationen im 
Netz...



Greetz,
/th.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Entweder habe ich die Funktionsweise des pointers stdout nicht
> verstanden, oder aber hier liegt was anderes im argen:// Set up stdout
>   stdout = th_fopen("uart0", "rw");
>   if(!(stdout))  return(-1);    // leave main if NULL-Pointer!
> Das funktioniert nicht,
> error:  #137: expression must be a modifiable lvalue
>
>
> aber
>   fprintf(stdout, "text");
> funktioniert, bzw.stdout->functionpointer=u0_putchar;
> funktioniert auch ...

dann wird wohl stdout als

  const FILE* stdout = .....;

irgendwo definiert sein, woduch er nicht mehr 'modifiable' ist.

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

Bewertung
0 lesenswert
nicht lesenswert
Hiho,


vielen Dank für den schnellen Hinweis!


kann man da nen override machen?
Ich möchte/muss den pointer verbiegen, aber nicht mit
stdio->functionpointer=u0_putchar;
verbiegen, sondern über (m)eine (th_)fopen mit
stdio = th_fopen(...);


Oder gibt es einen "redirect"-befehl, mit dem ich den stdio-pointer neu 
setzen kann?

Gerade gefunden:
#define stdout (&__CLIBNS __stdout)
   /* pointer to a FILE object associated with standard output stream */
in den Tiefen des Keil/ARM Compilersystems ;-)

Und was mich auch wundert, ist stdout vom Typ FILE oder FILE*? Meine 
Pointer sind alle vom Typ FILE*, und funktionieren.
extern FILE __stdin, __stdout, __stderr;
...
#undef __CLIBNS
    #ifdef __cplusplus
      namespace std {
      #define __CLIBNS ::std::
        extern "C" {
    #else /* ndef __cplusplus */
      #define __CLIBNS
    #endif /* ndef __cplusplus */
aus einem der standard-header.
Wenn ich's richtig lese, verschwindet das CLIBNS und das & bleibt als 
adressoperator zurück... also hätten wir die Typen
FILE __stdout 
FILE *stdout
? Von const oder so find ich allerdings nix, bekomme aber trotzdem die 
Meldung "unmodifiable L-Value"...



Ist das oben eigendlich stdio-konform angewandt, oder "vergewaltige" ich 
hiermit das system?


VG,
/th.

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

Bewertung
0 lesenswert
nicht lesenswert
kennt jemand ein gutes tutorial zu diesem thema?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thorsten De buhr wrote:
> Ich möchte/muss den pointer verbiegen, aber nicht mit
>
> stdio->functionpointer=u0_putchar;
> 
> verbiegen, sondern über (m)eine (th_)fopen mit
>
> stdio = th_fopen(...);
> 
>
>
> Oder gibt es einen "redirect"-befehl, mit dem ich den stdio-pointer neu
> setzen kann?

Wenn es wirklich ein const Pointer ist (worauf die Fehlermeldung
hindeuten würde), dann kannst du das const natürlich auch
wegcasten.
Aber ganz ehrlich:
Ich würde mich da nicht dran vergreifen.

>
> Und was mich auch wundert, ist stdout vom Typ FILE oder FILE*?

Ja das hat mich auch schon etwas gewundert.
Als ich das letzte mal an stdout, stdin, stderr drann war
(mindestens 15 Jahre her, auf einem PC) da waren das eigentlich
nur Zahlenwerte: 1, 2, 3

>
> extern FILE __stdin, __stdout, __stderr;
> ...
> #undef __CLIBNS
>     #ifdef __cplusplus
>       namespace std {
>       #define __CLIBNS ::std::
>         extern "C" {
>     #else /* ndef __cplusplus */
>       #define __CLIBNS
>     #endif /* ndef __cplusplus */
> 
> aus einem der standard-header.
> Wenn ich's richtig lese, verschwindet das CLIBNS und das & bleibt als
> adressoperator zurück... also hätten wir die Typen
>
> FILE __stdout
> FILE *stdout
> 

Dann wird das Keil wohl anders gelöst haben

> ? Von const oder so find ich allerdings nix, bekomme aber trotzdem die
> Meldung "unmodifiable L-Value"...

Schwer zu sagen. Diese Fehlermeldung würde eigentlich auf so etwas
hindeuten: Ein konstanter Pointer, der klarerweise nicht modifiziert
werden kann.

> Ist das oben eigendlich stdio-konform angewandt, oder "vergewaltige" ich
> hiermit das system?

Ich würde hier eher zu 'vergewaltigen' tendieren.

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

Bewertung
0 lesenswert
nicht lesenswert
Hmmm ...

ich denke eher nicht an "vergewaltigen, denn (Auszug aus der Doku):
fprintf(& __stdout, ...)

where __stdout has type __FILE.

also scheine ich doch gar nicht so weit weg vom richtigen weg zu sein?

Autor: Thorsten de Buhr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
any further ideas?

Autor: Bernd Schuster (mms)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hast du das problem schon lösen können?

Bernd

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.