nop nop nop nop nop nop nop nop

Gast #3285732
Lesenswert?

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
 asm volatile("nop"); // Datenblatt S. 12
4
 asm volatile("nop"); // min. X ms
5
 asm volatile("nop"); // fuer 16MHz
6
 asm volatile("nop");
7
 asm volatile("nop");
8
 asm volatile("nop"); // Angstnop
9
 asm volatile("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
Persönliche Seite #3285764
Lesenswert?

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
#3285766
Lesenswert?

@ 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.
Gast #3285778
Lesenswert?

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
#3285786
Lesenswert?

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.
Persönliche Seite #3285945
Lesenswert?

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
Gast #3286800
Lesenswert?

Für die, die sich schon immer gefragt haben wie man in C++ ohne Makros 
eine feste NOP-Sequenz generieren kann (just for fun ;-) ):
1
template <unsigned int N>
2
struct StaticLoop {
3
  template <typename F>
4
  __attribute__((always_inline)) inline static void run (F f) {
5
    f ();
6
    StaticLoop<N-1>::run (f);
7
  }
8
};
9

10
template <>
11
struct StaticLoop<0> {
12
  template <typename F>
13
  __attribute__((always_inline)) inline static void run (F f) {
14
  }
15
};
16

17
int main () {
18
  StaticLoop<13>::run ([] { asm volatile ("nop"); });
19
}
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 :-)
Gast #3287175
Lesenswert?

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 :).

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