Dr. Sommer schrieb:
> "r" ist falsch, weil der Wert ja geändert wird. Ich meine es müsste "+r"
> sein, und bei den Output Operands gelistet werden.
Jau. Ansonsten konnte man bei
asmDelay(10);
asmDelay(10);
falschen Code bekommen.
> Wozu das %= ?
%= liefert eine für die Übersetzungseinheit eindeutige Zahl pro Inline
Asm, so dass Code wie
asmDelay(10);
asmDelay(10);
nicht dazu führt, dass ein Label wie loop 2x auftaucht, was zu einen
Assembler-Fehler führen würde.
Alternativ gehen lokale Labels:
1 | static inline void asmDelay (int32_t val)
|
2 | {
|
3 | asm volatile ("1: subs %0, %0, #1" "\n\t"
|
4 | " nop" "\n\t"
|
5 | " bne 1b"
|
6 | : "+r" (val));
|
7 | }
|
Seltsam ist außerden, dass val signed ist. Oder ist SUBS eine
saturierte Subtraktion, so dass -1 -1 = 0 wird? (Ich kenn kein ARM-Asm).
Und asmDelay will einen Rückgabewert; alo entweder was zurückgeben oder
void asmDelay (..).
> Das delay ist natürlich ungenau, hängt von Flash Latenz und so ab.
> Besser macht man das mit Timern.
Für längere, exakte Zeiten besser mit Timer. Wenn es nur sehr kurze
Zeiten sind, z.B. ne handvoll Ticks zum für eine langsame I/O Line bis
sich Pegel stabilisiert haben, dann ist ein Delay einfacher und durchaus
sinnvoll, da es nur um Mindestzeiten geht und Cache-, Pipeline- und
Interrupt-Effekte nicht stören. Außerdem verschendet man nicht einen
ganzen Timer um 2 Ticks zu schnarchen.