Guten Morgen zusammen,
sollte jemand mehrere meiner Fragen in den letzten Wochen im GCC-Forum
beobachtet haben wird er bemerkt haben, daß ich nach ein paar Jahren
C-Abstinenz wieder angefangen habe und mir endlich mehr good practices
angewöhnen will. Im diesem Rahmen mache ich schlimme Sachen: Alte
Quelltexte refaktorieren.
Was mir momentan etwas störend aufstößt sind unübersichtliche
nop-Schlangen in meinen Displaytreibern, da finden sich oft Konstrukte
wie:
1
[..]
2
PORT_GLCD_COM|=(1<<GLCD_EN);
3
asmvolatile("nop");// Datenblatt S. 12
4
asmvolatile("nop");// min. X ms
5
asmvolatile("nop");// fuer 16MHz
6
asmvolatile("nop");
7
asmvolatile("nop");
8
asmvolatile("nop");// Angstnop
9
asmvolatile("nop");// Angstnop
10
PORT_GLCD_COM&=~(1<<GLCD_EN);
11
[...]
Ich habe ein paar Quelltexte durchforstet, die nop-Schlangen finden sich
überall. Gibt es keine Präprozessormagische Möglichkeit, eine solche,
übersichtlichere Schreibweise zu erreichen:
1
[..]
2
PORT_GLCD_COM|=(1<<GLCD_EN);
3
NOP(8);// Datenblatt S. 12 min. X ms fuer 16MHz + 2 Angstnop
4
PORT_GLCD_COM&=~(1<<GLCD_EN);
5
[...]
Eine for-Schleife ist für so kurze Wartezeiten ja eher ungeeignet, und
die _delay_XX-Funktionen auch. Schleifenähnliche Konstrukte sind mir für
den Präprozessor aber noch nie begegnet.
Gibt es keine bessere Lösung?
Viele Grüße
Nicolas
Nicolas S. schrieb:> Eine for-Schleife ist für so kurze Wartezeiten ja eher ungeeignet, und> die _delay_XX-Funktionen auch.
Und warum bitte soll _delay_us() hier ungeeignet sein?
Stefan Ernst schrieb:> Und warum bitte soll _delay_us() hier ungeeignet sein?
Weil 8 nops bei 16MHz immer noch kürzer als eine µs sind. Und
_delay_ns(...) gibt es meines Wissens nach nicht.
Aber danke für __builtin_avr_delay_cycles, das kannte ich noch nicht.
Nicolas S. schrieb:> Weil 8 nops bei 16MHz immer noch kürzer als eine µs sind. Und> _delay_ns(...) gibt es meines Wissens nach nicht.
Und was ist falsch an _delay_us(0.5)?
So am Rande: Schleifen im Präprozessor sind möglich, aber umständlich,
unflexibel, und sehr schmuddelig. Da lohnt sich meistens, einfach
mehrere unterschiedliche Makros mit den tatsächlich benötigten
Wiederholsequenzen zu definieren.
Hallo Stefan,
danke für die Antwort. Wenn die _delay- Funktionen mit float arbeiten
(was ich implizit immer ausgeschlossen habe) mit sind die nop-Sammlungen
tatsächlich obsolet geworden.
Vielleicht sollte ich mir öfter alte, vertraut erscheinende Bekannte
ansehen...
Viele Grüße
Nicolas
Nicolas S. schrieb:> mit sind die nop-Sammlungen tatsächlich obsolet geworden.
Und auch noch für verschiedene Megaherze brauchbar ;-)
Nicolas S. schrieb:> Wenn die _delay- Funktionen mit float arbeiten
Und wenn nicht, stört es echt ob das nun 1 µs oder 500ns gewartet wird?
Hallo Nicolas S.
> danke für die Antwort. Wenn die _delay- Funktionen mit float arbeiten> (was ich implizit immer ausgeschlossen habe) mit sind die nop-Sammlungen> tatsächlich obsolet geworden.
Warum sind solche nop-Sequenzen denn unübersichtlicher als die Delay
Funktion?
Immerhin gibt dir die nop-Kette mit den Kommentaren einen
Anschaulicheren Überblick, wie sich die Pause zusammensetzt.
Die Delayfunktion ist deutlich kürzer zu lesen, aber auch mit
ausführlichem Kommentar unanschaulicher. Aber Speicherplatz auf dem
Rechner ist ja hoffentlich dafür kein Problem.
Was passiert, wenn ich in die delay Funktion einen Wert eintrage, der
kürzer ist als ein nop? Gibt das eine Fehlermeldung, oder krieg ich
einfach die Kurve nicht und flieg raus? Was ist, wenn ich einen Wert
vorgebe, der mit dem Raster der nops nicht passt? Die nops geben mir
eine auf den Controller bezogene Quantisierung der Zeit vor. Ich kann
nicht darunter gehen und auch keine Bruchstücke der Zeitabschnitte
verwenden.
Oder sehe ich das zu verquer?
> Vielleicht sollte ich mir öfter alte, vertraut erscheinende Bekannte> ansehen...>
Immer. ;O)
Mit freundlichem Gruß: Bernd Wiebus alias dl1eic
http://www.dl0dg.de
@ Bernd Wiebus (berndwiebus) Benutzerseite
>> danke für die Antwort. Wenn die _delay- Funktionen mit float arbeiten>> (was ich implizit immer ausgeschlossen habe) mit sind die nop-Sammlungen>> tatsächlich obsolet geworden.>Warum sind solche nop-Sequenzen denn unübersichtlicher als die Delay>Funktion?
Eben weil es NOP-Sequenzen sind. Riesig groß, nehmen viel Raum und
Aufmerksamkeit ein, mehr als ihnen gebührt. Ausserdem sind sie
taktfrequenzabhängig. Will man mal die CPU-Frequenz ändern, warum auch
immer, muss man wieder rumfummeln.
>Immerhin gibt dir die nop-Kette mit den Kommentaren einen>Anschaulicheren Überblick, wie sich die Pause zusammensetzt.
Sinnlose Lyrik.
>Die Delayfunktion ist deutlich kürzer zu lesen, aber auch mit>ausführlichem Kommentar unanschaulicher.
Nö. Kurz und prägnant auf den Punkt gebracht.
>Was passiert, wenn ich in die delay Funktion einen Wert eintrage, der>kürzer ist als ein nop? Gibt das eine Fehlermeldung, oder krieg ich>einfach die Kurve nicht und flieg raus?
Die Funktion sorgt dafür, dass die angegebene Zeit MINDESTENS
eingehalten wird, manchmal ist sie halt einen Tick, ähhh NOP länger.
Bernd Wiebus schrieb:> Warum sind solche nop-Sequenzen denn unübersichtlicher als die Delay> Funktion?> Immerhin gibt dir die nop-Kette mit den Kommentaren einen> Anschaulicheren Überblick, wie sich die Pause zusammensetzt.
Die nop-Kette gibt einen schönen, intuitiven Überblick darauf, wo Zeit
verbraucht wird. Aber ich erwische mich immer wieder dabei, mich zu
verzählen (wem ist eigentlich aufgefallen, daß im obigen Beispiel nicht
8 sondern nur 7 NOPs waren?).
Und ein weiterer Hintergrund: Gerade bei den Pollin-KS0108-LCDs habe ich
ordentliche Exemplarsteuerungen, was das notwendige delay zwischen
enable und busy-flag angeht (die grünen brauchen irgendwie immer länger.
Und bei den grünen ist die LED-Spannungsversorgung andersherum, stimmt
hier zufällig mit dem Aufdruck überein). Hier einfach einen Zahlenwert
als Konstante hinterlegen zu können hat durchaus Vorteile.
Viele Grüße
Nicolas
Bernd Wiebus schrieb:> Die Delayfunktion ist deutlich kürzer zu lesen, aber auch mit> ausführlichem Kommentar unanschaulicher.
Hä? Selbst ohne jeden Kommentar steht dann doch exakt da, um was es
geht, nämlich den Programmablauf um eine bestimmt Zeit zu verzögern.
Sogar die Zeit selber sieht man sofort.
Bernd Wiebus schrieb:> Was passiert, wenn ich in die delay Funktion einen Wert eintrage, der> kürzer ist als ein nop? Gibt das eine Fehlermeldung, oder krieg ich> einfach die Kurve nicht und flieg raus? Was ist, wenn ich einen Wert> vorgebe, der mit dem Raster der nops nicht passt?
Die Anzahl der zu "verplempernden" Cycles wird immer auf die nächste
ganze Zahl aufgerundet.
Hallo Stefan Ernst.
>> Die Delayfunktion ist deutlich kürzer zu lesen, aber auch mit>> ausführlichem Kommentar unanschaulicher.> Hä? Selbst ohne jeden Kommentar steht dann doch exakt da, um was es> geht, nämlich den Programmablauf um eine bestimmt Zeit zu verzögern.> Sogar die Zeit selber sieht man sofort.
Ok. Vergiss es. Es ist anscheinend ein persönliches Problem meiner
Hirnstruktur.
>> Was passiert, wenn ich in die delay Funktion einen Wert eintrage, der>> kürzer ist als ein nop? Gibt das eine Fehlermeldung, oder krieg ich>> einfach die Kurve nicht und flieg raus? Was ist, wenn ich einen Wert>> vorgebe, der mit dem Raster der nops nicht passt?>> Die Anzahl der zu "verplempernden" Cycles wird immer auf die nächste> ganze Zahl aufgerundet.
Danke! Klare Aussage.
Mit freundlichem Gruß: Bernd Wiebus alias dl1eic
http://www.dl0dg.de
Benötigt leider GCC-spezifische Attribute um keine unnötigen
Funktionsaufrufe zu generieren und klappt auch nur mit eingeschalteten
Optimierungen. Die delay Funktion ist wohl onehin besser da sie den
CPU-Takt mit einberechnet. Vielleicht kann das hier ja jemand für
allgemeine statische Schleifen gebrauchen :-)
Attribute sollten doch ab 4.8.1 auch schöner gehen:
always inline
Das ist C++11!
In (gc)C scheint das aber nicht vorgesehen zu sein. Aber deine Templates
ja auch nicht ;-)
G++ schrieb:> Attribute sollten doch ab 4.8.1 auch schöner gehen:
Ich weiß... aber wie du selbst siehst... ;-)
G++ schrieb:> Aber deine Templates ja auch nicht ;-)
Wieso, die funktionieren doch?!
Es ging um die Frage, ob gcc auch in C ( mit ohne ++) diese Attribute
kann. Und das es im Fall deines Codes ja egal wäre, da der eh C++ ist.
Jetzt klar?
Dr. Sommer schrieb:> Naja, nach C war nicht explizit gefragt,
Och, für mich ist die ursprüngliche Fragestellung seit der Erkenntnis,
daß _delay_XX auch float versteht gegessen. Das und ein bischen
Hühnerfutter, das hoffentlich morgen per Post kommt, reichen mir völlig
aus, um ein gelungenes Wochenende zu versprechen.
Insofern stört mich das nicht, wenn hier über g++ oder das Wetter
diskutiert wird :).