Forum: Mikrocontroller und Digitale Elektronik PFS154 und Assembler im C-Quellcode mit SDCC 4.4.4


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 Ralph S. (jjflash)


Angehängte Dateien:

Lesenswert?

Nachdem ich nun wieder im "Padauk-Fieber" bin (ich habe keine Ahnung, 
warum mich dieser derart kastrierte Mikrocontroller so fasziniert) habe 
ich ein (kleines) "Schönheitsproblem" (wie ich glaube).

Etwas, das bisher problemlos mit SDCC 4.0.4 und SDCC 4.10 funktioniert 
hat, gibt mir nun eine Assemblerwarnung aus:
1
?ASxxxx-Warning in line 88 of delay.asm
2
               Forced IO address space for instruction without .io
3
?ASxxxx-Warning in line 109 of delay.asm
4
               Forced IO address space for instruction without .io

und ich habe keine Ahnung wo das herkommt und wichtiger wie ich das 
abgestellt bekomme.

Die Warnung wird von einer Verzögerungsschleife generiert, die in 
Assembler codiert und nicht von mir ist. Quelle der delay-Funktion ist:

https://github.com/free-pdk/free-pdk-examples/blob/master/include/delay.h

Der Author dieser Funktion zählt die Taktimpulse der MCU (und macht das 
sehr genau). Leider hat er Programmcode in die delay.h eingefügt, was 
mir nicht so wirklich gefällt. Vor allen Dingen kann bei diesem Vorgehen 
diese delay.h nur einmal im gesamten Programm inkludiert werden. Habe 
ich andere *.h / *.c Dateien kann ich dort dann nicht auch #include 
"delay.h" machen, weil ich hier dann doppelte Definitionen habe.

Also hatte ich diese Funktion geteilt in eine delay.c und eine delay.h 
und habe die bisher meinem Programm hinzugelinkt.

Hat bisher klaglos funktioniert.

So wollte ich das auch mit SDCC4.4.4 machen. Wie oben beschrieben 
erzeugt mir das eine Warnmeldung. Allerdings ist das "nur" eine Warnung, 
das Programm verarbeitet die delay-funktion klaglos.

Bindet man die originale delay.h (ohne zu linken), die ich zu 
Unterscheidungszwecke nach delay_inc.h umbenannt habe im Main-Programm 
ein, wird diese Warnmeldung interessanterweise nicht erzeugt!

Im Zip-Anhang habe ich beide Programmversionen (mit und ohne Linken) 
hinzugefügt.

Der Assemblercode der Delay-Funktion stößt sich an folgender Instruktion 
(gleiche Befehle in Zeile 88 und 109:
1
    t1sn f, z ; 1 cycle + 1 cycle for final skip

Diese Instruktion überspringt die nachfolgende Instruktion (ein goto) 
und beendet somit die Warteschleife.

Wie bekomme ich die Warnmeldungen weg oder wie kann ich hier zumindest 
diese Warnmeldung explizit unterdrücken? (und nur diese).

von Klaus R. (klausro)


Lesenswert?

Ralph S. schrieb:
1
> ?ASxxxx-Warning in line 88 of delay.asm
2
>                Forced IO address space for instruction without .io

Nun, da fehlt eine .io extention.

> https://github.com/free-pdk/free-pdk-examples/blob/master/include/delay.h

Wenn ich da Zeile 81 ansehe, steht da:
1
 t1sn.io  f, z

Könnte es möglicherweise sein, das (ganz banal) ein
1
    t1sn.io f, z ; 1 cycle + 1 cycle for final skip

das Problem löst? Nein, ich habe mir jetzt keinen sdcc installiert...

von Mario M. (thelonging)


Lesenswert?

Ralph S. schrieb:
> Vor allen Dingen kann bei diesem Vorgehen diese delay.h nur einmal im
> gesamten Programm inkludiert werden.

Nein, die Datei hat ein "include guard", d. h. der Inhalt wird auch bei 
mehrfachem Aufruf nur einmal eingebunden.

von Klaus R. (klausro)


Lesenswert?

Klaus R. schrieb:
> Könnte es möglicherweise sein

Das wird es sein. Der Patch vom 24. May auf delay.h fügt u.a. das ".io" 
an die Instruktion an:
https://github.com/free-pdk/free-pdk-examples/commit/768a1790e786084a56ddb37d0f670e33618db102

Ralph S. schrieb:
> Bindet man die originale delay.h (ohne zu linken), die ich zu
> Unterscheidungszwecke nach delay_inc.h umbenannt habe im Main-Programm
> ein, wird diese Warnmeldung interessanterweise nicht erzeugt!

Ist auch logisch, denn dort steht ja auch "t1sn.io  f, z" (mit .io).

Ralph S. schrieb:
> Vor allen Dingen kann bei diesem Vorgehen
> diese delay.h nur einmal im gesamten Programm inkludiert werden.

Wobei der "include guard", den Mario erwähnt hat, schon in der ersten 
Version in der Datei war (zumindest der auf github).

von Ralph S. (jjflash)


Lesenswert?

Klaus R. schrieb:
> Wenn ich da Zeile 81 ansehe, steht da: t1sn.io  f, z
>
> Könnte es möglicherweise sein, das (ganz banal) ein
>     t1sn.io f, z ; 1 cycle + 1 cycle for final skip

So banal wie das klingt  ... :-)

DAS WAR ES !

Ich hatte diese Funktion vor längerer Zeit aus diesem Github kopiert und 
nicht mitbekommen, dass der Besitzer des Githubs, genau dieses geändert 
hatte.

Vielen Dank

von Ralph S. (jjflash)


Lesenswert?

Klaus R. schrieb:
> Wobei der "include guard", den Mario erwähnt hat, schon in der ersten
> Version in der Datei war (zumindest der auf github).

Na ja, ich brauch den include guard jetzt nicht, weil das mit *.h / *.c 
und linken jetzt auch ohne Warnung funktioniert.

Und nochmal: vielen Dank an euch beide !

von Harald K. (kirnbichler)


Lesenswert?

Mario M. schrieb:
> Nein, die Datei hat ein "include guard", d. h. der Inhalt wird auch bei
> mehrfachem Aufruf nur einmal eingebunden.

Ein Include Guard funktioniert nur für eine "translation unit", d.h., er 
schützt nur vor mehrfachem Einbinden in ein und dasselbe Sourcefile. Bei 
Projekten, die aus mehreren Sourcefiles bestehen, funktioniert das 
nicht, denn jedes Sourcefile wird separat übersetzt.

Und damit wird, wenn der via #include eingebundene Kram globale Symbole 
definiert (sei es durch Variablen oder aber eben Funktionen), der Linker 
zu Recht über Mehrfachdefinitionen klagen.

von Ralph S. (jjflash)


Lesenswert?

Harald K. schrieb:
> nd damit wird, wenn der via #include eingebundene Kram globale Symbole
> definiert (sei es durch Variablen oder aber eben Funktionen), der Linker
> zu Recht über Mehrfachdefinitionen klagen.

... und das ist der Grund, warum die originale delay.h in delay.h (ohne 
globale Symbole) und in delay.c (den Codedefinitionen) aufgeteilt wurde. 
Dein Post hat das super beschrieben!

von Harald K. (kirnbichler)


Lesenswert?

Ralph S. schrieb:
> Dein Post hat das super beschrieben!

Danke für die Blumen. Mit altem C mache ich halt auch schon 'ne Weile 
rum, auch wenn der Erstkontakt erst mal sehr abschreckend war (ein 
K&R-Compiler und schlechte Dokumentation). Der Zweitkontakt erfolgte 
dann mit Borlands Turbo C 2.0 (damals von Heimsoeth mit einem 
exzellenten deutschsprachigen Handbuch verkauft), das kam noch vor dem 
offiziellen C89-Standard auf den Markt (war aber anhand von "drafts" 
daran angepasst).

von Ralph S. (jjflash)


Lesenswert?

Mein Erstkontakt war auf einem Schneider CPC6128 (Compiler weiß ich 
nicht mehr) und dann auch Turbo C von Borland. Es hätte mich gewundert, 
wenn Programmcode im Headerfile von mehreren Sourcen keine 
Multidefinition hervorrufen würde. :-) aus diesem Grund eben linken.

von Harald K. (kirnbichler)


Lesenswert?

Ralph S. schrieb:
> Es hätte mich gewundert,
> wenn Programmcode im Headerfile von mehreren Sourcen keine
> Multidefinition hervorrufen würde.

Geht - wenn der als static definiert wird. Dann sieht der Linker 
nichts davon.

von Ralph S. (jjflash)


Lesenswert?

Harald K. schrieb:
> Geht - wenn der als static definiert wird. Dann sieht der Linker
> nichts davon.

okay, stimmt ! Allerdings: static verwende ich - in aller Regel - nur 
innerhalb einer Funktion, wenn beim Wiedereintritt der Wert einer 
Variablen den Inhalt haben soll, den er bei einer vorherigen Verwendung 
besessen hat.

Ansonsten überlasse ich schon dem Compiler/Linker die beste Aufteilung 
im Speicher!

von Harald K. (kirnbichler)


Lesenswert?

Ralph S. schrieb:
> Allerdings: static verwende ich - in aller Regel - nur
> innerhalb einer Funktion

Das ist dann was komplett anderes. Das Schlüsselwort static hat zwei 
komplett unterschiedliche Bedeutungen - in einer Funktion kann man es 
für eine Variablendefinition verwenden, so, wie Du es tust, aber 
außerhalb einer Funktion bewirkt es etwas anderes, nämlich die 
"Unsichtbarkeit" des jeweiligen Symbols für den Linker. Das Symbol 
kann hier eine Variable, aber auch ein Funktion sein.

Und in C++ hat static noch eine weitere Bedeutung, eine als static 
deklarierte Memberfunktion einer Klasse wird ohne impliziten this 
-Pointer aufgerufen, d.h. kann auch ohne Instanziierung eines Objektes 
verwendet werden.

: Bearbeitet durch User
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Harald K. schrieb:
> Geht - wenn der als static definiert wird.

Kann man machen, ist aber auf einem PFS154 nicht sehr sinnvoll. Damit 
kommt der Code nämlich N-fach in den Speicher, wenn Du delay.h in N 
Übersetzungseinheiten includierst. Der kleine PFS154 wird dann 
irgendwann platzen.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Ralph S. schrieb:
> Leider hat er Programmcode in die delay.h eingefügt, was mir nicht so
> wirklich gefällt.

Schreib dem Autor doch eine Nachricht mit der Begründung, dass der 
Programmcode in delay.h die Usablilty doch sehr einschränkt.

von Harald K. (kirnbichler)


Lesenswert?

Frank M. schrieb:
> Kann man machen, ist aber auf einem PFS154 nicht sehr sinnvoll.

Allerdings, das wollte ich auch nicht behaupten. Es ist im Grunde 
genommen nirgends sinnvoll.

Ich hab' das halt nur erwähnt, weil es möglich ist.

von Ralph S. (jjflash)


Lesenswert?

Frank M. schrieb:
> Schreib dem Autor doch eine Nachricht mit der Begründung, dass der
> Programmcode in delay.h die Usablilty doch sehr einschränkt.

:-) ich für mich habe das ja geändert in *.c / *.h Datei geändert und 
linke das bei Bedarf hinzu. Hm, auf dem Github des Authors sind noch 
andere Fehler enthalten (auch was das Initialisieren der Hardware 
angeht). Außerdem führt er in jeder *.h Datei Code mit sich herum und 
linkt nie etwas hinzu.

Von daher glaube ich macht es wenig Sinn ihn darauf aufmerksam zu 
machen. Abgesehen davon sind seine Taktzählungen und das Aufteilen in 
8-, 16- und 32-Bit Zählschleifen relativ gut gelungen. :-) so gut, dass 
ich das nicht selbst machen wollte.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.