mikrocontroller.net

Forum: Compiler & IDEs Keine Formatierung mit printf() auf C167


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Andy (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,

 ich versuche mittels printf() eine Ausgabe zu drucken. Dies 
funktioniert auch, allerdings funktioniert die Formatierung nicht 
richtig.
Beispiele:
printf("huhu\n") -> huhu
printf("test %d", 5) -> test 3568
Ich verwende den Tasking compiler auf einem C167 Prozessor, Modell 
small.
Laut Doku unterstützt das small Modell keine Formatierung, also habe ich 
noch die Library fmtiosm.lib dazugelinkt. Das hat nicht nicht geholfen.
Hab auch noch beim Compiler die Option "-libfmtiom" gesetzt, brachte 
aber auch keine Verbesserung.
...
Compiling cc166 -c -libfmtiom -c -v -WaEX -s -A1 -x -w68 -w91 -w27 -DSERIAL_DEBUG -DCMX -DTASKING -DCAN_MSG_LS_IN1 -DPreFront -DHW_V2 -DC166 -D_16BIT -I. -IC:/ND/ILX/Raph52/Share\LangC\oxf  -IC:/ND/ILX/Raph52/Share\LangC  -IC:/ND/ILX/Raph52/Share\LangC\osconfig\cmx -IC:/ND/ILX/Raph52/Share\maketmpl -Ic:\nd\cmx\tsk-c166 -D_DEBUG -Ms -O1 -g -o simio.obj simio.c
+ C:\ND\tsk_v8_5\c166\bin\c166 simio.c -o cc3008b.src -e -s -A1 -x -w68 -w91 -w27 -DSERIAL_DEBUG -DCMX -DTASKING -DCAN_MSG_LS_IN1 -DPreFront -DHW_V2 -DC166 -D_16BIT -I. -IC:/ND/ILX/Raph52/Share\LangC\oxf -IC:/ND/ILX/Raph52/Share\LangC -IC:/ND/ILX/Raph52/Share\LangC\osconfig\cmx -IC:/ND/ILX/Raph52/Share\maketmpl -Ic:\nd\cmx\tsk-c166 -D_DEBUG -O1 -g -Ms
+ C:\ND\tsk_v8_5\c166\bin\l166 LOC TO Net52_Online.out PTOG wst1main.obj C7SegmDisplay.obj CConfig.obj CDriveEncoder.obj CEEPROM.obj ... PSS_CA_Rulers.obj PSS_CB_Plates.obj PKG_Main.obj PSS_Z_Utilities.obj PKG_CanController.obj PKG_Can.obj c166_interrupts.obj simio.obj serio.obj WST1CMXa.OBJ cmx_166_init.obj C:\ND\TSK_V8_5\C166\lib\ext\fmtiosm.lib c:\nd\cmx\tsk-c166\liba66s.lib C:/ND/ILX/Raph52/Share\LangC\lib\WST1oxfds.lib ext\fmtiosm.lib ext\c166s.lib  ext\fp166s.lib ext\rt166s.lib GENERAL LSY "MEMORY(RAM(4000h-0dfffh)," "ROM(0000h-03FFFh,010000h-03BFFFh))" "IRAMSIZE(2048)" "RE(ME(0E000h-0EFFFh))" "RE(ME(0F200h-0F5FFh))" "HS(20000)" "SS(C166_US(512))"

Hat mir eventuell jemand einen Tipp, wie ich einfache Formatierungen 
hinbekomme bzw. was ich falsch mache? Vielen Dank.


Grüße, Andy

von Wegstaben V. (wegstabenverbuchsler)


Bewertung
0 lesenswert
nicht lesenswert
Andy schrieb:
> printf("test %d", 5) -> test 3568

schon mal mit %i versucht anstelle von %d ?
teste auch mal, was bei %u passiert (mit 5, +5 und -5)

von Andy (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,

 ich habe mal folgenden code eingefügt:
printf("I-002: Start of CntInfo debug\n\0");
printf("test d: %d\n\0", 7);
printf("test s: %s\n\0", "huhu");
printf("test i: %i\n\0", 19);
printf("test +u: %u\n\0", 37);
printf("test -u: %u\n\0", -98);
und dabei folgende Ausgabe erhalten:
I-002: Start of CntInfo debug
test d: 26138
test s: 
test i: 26138
test +u: 26138
test -u: 26138

Grüße, Andy

von Bernd (Gast)


Bewertung
-2 lesenswert
nicht lesenswert
Ich würde statt Konstanten mal echte Variablen versuchen.
printf will doch nach dem Formatstring einen Zeiger auf das Argument 
bzw. die Argumente haben. Ich könnte mir vorstellen, das das bei C auf 
dem Mikrocontroller schief gehen kann.

Selbst auf dem Host klappt nicht alles 100%ig:
I-002: Start of CntInfo debug
test d: 7
test s: huhu
test i: 19
test +u: 37
test -u: 4294967198

von foobar (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Es scheint, dass die Varargs (stdarg.h) nicht funktionieren.  Das kann 
bei bestimmten Architekturen unter anderem daran liegen, dass der 
Compiler keinen Prototypen für die vararg-Funktion (wie z.B. printf) 
gesehen hat.  Hast du stdio.h included?  Evtl selbst mal nen Prototype 
angelegt? ("extern int printf(const char *, ...);").  Schreib mal ne 
eigene vararg-Funktion (mit Pointern und ints) zum Testen.  Was macht: 
printf("a %s %d %s\n", "b",42,"c"); und printf("a %d %s", 42, "b");

von Dirk B. (dirkb2)


Bewertung
0 lesenswert
nicht lesenswert
Bernd schrieb:
> Ich würde statt Konstanten mal echte Variablen versuchen.

Wo ist da bei Call-by-Value der Unterschied.

> printf will doch nach dem Formatstring einen Zeiger auf das Argument
> bzw. die Argumente haben.

Nein. Es sei denn, es sind Strings. Und selbst Stringliterale zerfallen 
in eine Adresse auf das erste Zeichen


Bernd schrieb:
> Selbst auf dem Host klappt nicht alles 100%ig:I-002: Start of CntInfo
> test -u: 4294967198

Was erwartest du bei einem unsigned int (%u) und negativen Werten (-98)?

von Markus F. (mfro)


Bewertung
0 lesenswert
nicht lesenswert
Andy schrieb:
> Laut Doku unterstützt das small Modell keine Formatierung,

Doku richtig lesen, das steht da nicht. Da steht:

> This SMALL version does not contain the required functionality to handle
> precision specifiers and floating point I/O

Formatierung wird also sehr wohl unterstützt (auch bei SMALL), lediglich 
precision specifiers und floating point nicht.

Bis zum Beweis des Gegenteils würde ich davon ausgehen, daß

#include <stdio.h>

vergessen wurde.

von Andy (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Hallo zusammen,

 vielen Dank für eure zahlreichen Antworten.
Das Problem ist nun gelöst. Des Rätsels Lösung war, wie foobar 
geschrieben hat, tatsächlich ein fehlender #include von <stdio.h>.
Habs zwar includiert, aber in einer Datei, wo ein printf ohne 
Formatierung verwendet wurde. Habs jetzt mal nochmals in der Datei 
includiert, in der die printf Formatierung verwendet wurde und es 
funktionierte. :-)

Ausgaben für folgenden Code:
printf("a %s %d %s\n", "b",43,"c");
printf("a %d %s\n", 42, "b");

Ausgabe ohne stdio.h:
a  3 
a 24968 …ú
Ausgabe mit stdio.h
a b 43 c
a 42 b

Vielen Dank nochmals...


Grüße, Andy

von Dirk B. (dirkb2)


Bewertung
0 lesenswert
nicht lesenswert
Andy schrieb:
> Habs zwar includiert, aber in einer Datei, wo ein printf ohne
> Formatierung verwendet wurde. Habs jetzt mal nochmals in der Datei
> includiert, in der die printf Formatierung verwendet wurde und es
> funktionierte. :-)

Jede .c Datei wird für sich alleine compiliert. Die weiß nicht, was in 
anderen Dateien abgeht.
Um an diese Informationen bereitzustellen, gibt es die Header-Dateien.

Wenn du in einer Datei etwas aus einem anderen Modul brauchst, gibt es 
ein include.


Erst danach werden die (aus den .c entstandenen) Object-Dateien zusammen 
gebunden (gelinkt).

von Dirk B. (dirkb2)


Bewertung
0 lesenswert
nicht lesenswert
Andy schrieb:
> tatsächlich ein fehlender #include von <stdio.h>

Das muss aber eine Warnung vom Compiler geben.
(Beim Aufruf von printf oder anderen Funktionen aus stdio.h)

Wenn nicht, daa musst du den Warnlevel erhöhen.

Behandele Warnungen wie Fehler (beseitige deren Ursache)

von Markus F. (mfro)


Bewertung
0 lesenswert
nicht lesenswert
Andy schrieb:
> Das Problem ist nun gelöst.

... und für ein Fleißsternchen darftst Du uns noch erklären, *warum 
genau* das ohne
#include <stdio.h>

nicht funktioniert ;) .

Wenn Du das in Gänze verstanden hast, hast Du eine Menge über C gelernt.

von Blume (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Einfach mal so in den Raum geworfen
Es ist keine gute Idee (Embedded) SW zu testen so lange noch Warnungen 
ausgegeben werden oder man mit der Quelltext Formatierung noch nicht 
zufrieden ist. Bzw. man sich noch nicht an die Code Styles hält

von S. R. (svenska)


Bewertung
0 lesenswert
nicht lesenswert
Blume schrieb:
> Es ist keine gute Idee (Embedded) SW zu testen so lange
> noch Warnungen ausgegeben werden oder man mit der Quelltext
> Formatierung noch nicht zufrieden ist.

Im Rahmen der Möglichkeiten teste ich während der Entwicklung 
ununterbrochen. Nichts ist schlimmer, als Probleme mit falschen Annahmen 
(versuchen) zu lösen. Daher achte ich auf zügige Turnaround-Zeiten 
(Dateiänderung -> Ergebnis im Log).

von MaWin (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Welcher Compiler, welche Version?

von Rolf M. (rmagnus)


Bewertung
0 lesenswert
nicht lesenswert
Markus F. schrieb:
> Wenn Du das in Gänze verstanden hast, hast Du eine Menge über C gelernt.

Nicht über C selbst, sondern darüber, wie Compiler intern 
Funktionsaufrufe umsetzen. Auf C-Ebene ist es einfach nur undefiniertes 
Verhalten.

von Andy (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

@MaWin: Der verwendete Compiler ist ein Tasking v8.5 compiler.

@DirkB: Bei dem Compiler kann man irgendwie keine Warnlevel erhöhen. Das 
gibt es da wohl nicht. Was geht ist bestimmte Warnungen komplett 
deaktivieren (zum Beispiel sind bei mir deaktiviert: -w68 -w91 -w27 
usw.)

68: function xxx, parameter yyy not used
91: no prototype of function xxx
27: unexpected text after control

Vermutlich fällt der besagte Fehler unter Warnung 91? Werds mal 
probieren. Hab leider davon jede Menge Warnungen. Weiss nicht genau 
warum.
Andere Frage dazu: Sind die Warnungen schlimm bzw. können Sie Probleme 
verursachen? Programm scheint gut zu laufen, nur gelegentlich gibt's 
Abstürze, aber wohl aus anderen Gründen.
Das Problem ist, ich verwende hier Rhapsody und dies generiert mir 
überall den Code. Für Funktionen werden stets Parameter verwendet, die 
zum Teil nicht verwendet werden (Warning 68). Auch bei Warning 27 werden 
zum Beispiel nach #endif Strichpunkt (;) Zeichen eingefügt, welche die 
Warnung 27 verursachen.

Grüße, Andy

von foobar (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Warnungen haben ihren Sinn, sie einfach blind abzuschalten kann nach 
hinten losgehen (hast du ja gerade gesehen).

Die Warnung 68 abzuschalten kann ich verstehen.  Sie soll vor 
Tippfehlern warnen.  Die übliche Methode, sie "abzuschalten" ist ein:
   (void)yyy; /*unused*/
im Body von xxx.  Einige benutzen ein entsprendes Makro: UNUSED(yyy);

Warnung 91 sollte man auf Systemen, die je nach Prototype 
unterschiedlichen Kode generieren, nie abschalten - umschalten auf ERROR 
wäre eher angebracht.

Die Warnung 27 solltest du einfach im Kode korrigieren.  Hinter #endif 
gehört kein Semikolon.  Früher war da mal beliebiger Text erlaubt, 
heutzutage macht man da einen richtigen Kommentar raus (#endif 
/*MSDOS*/)

von Dirk B. (dirkb2)


Bewertung
0 lesenswert
nicht lesenswert
if (i = 0)
ist gültiger Code, macht aber bestimmt nicht das, was man möchte.

Darum gibt der Compiler eine Warnung

Code kann man auch mit hohem Warnlevel ohne Warnungen übersetzen.

von Andy (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,

 vielen Dank euch für die Infos.
Werde es beherzigen und den Code meines Vorgängers entsprechend 
anpassen...

Schöne Grüße, Andy

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.

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