PFS154 und Assembler im C-Quellcode mit SDCC 4.4.4

OP #7781350
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).

Angehängte Dateien:
#7781387
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...

#7781398
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).

OP #7781402
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

#7781425
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.

OP #7781492
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!

#7781593
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).

OP #7783282
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!

#7783433
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.

OP #7784928
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren