Grundlagen der Programmiersprache C

#define GPIO_BASE 0x40020000u
volatile uint32_t *const odr =
    (volatile uint32_t *)(GPIO_BASE + 0x14);
*odr |= 1u << 5;

Bei einem Mikrocontroller wird das Ausgaberegister wie oben deklariert und verwendet. Welche Aussage über diese Deklaration ist richtig?

  1. ADer Wert von *odr kann nicht geändert werden, während odr selbst durch Interrupts geändert werden kann und daher bei jeder Verwendung neu gelesen wird
  2. BDa volatile angegeben ist, wird das Lesen, Ändern und Schreiben in *odr |= 1u << 5 zu einer zusammenhängenden Operation, die nicht durch Interrupts unterbrochen wird
  3. CDie Adresse, auf die odr zeigt, kann nicht geändert werden, und Lese- und Schreibzugriffe über odr werden nicht weggelassen, sondern so oft tatsächlich ausgeführt, wie sie geschrieben sind
Antwort und Erläuterung anzeigen

Antwort: C. Die Adresse, auf die odr zeigt, kann nicht geändert werden, und Lese- und Schreibzugriffe über odr werden nicht weggelassen, sondern so oft tatsächlich ausgeführt, wie sie geschrieben sind

const steht rechts vom *, daher kann der Zeiger odr selbst nicht geändert werden und zeigt immer auf die Adresse desselben Registers. Das uint32_t, auf das er zeigt, ist mit volatile versehen, daher lässt der Compiler Lese- und Schreibzugriffe auf *odr weder weg noch fasst er sie zusammen, sondern greift so oft tatsächlich zu, wie es geschrieben ist. volatile macht Operationen jedoch nicht atomar, sodass zwischen Lesen und Schreiben in *odr |= … ein Interrupt auftreten kann. Bearbeitet ein Interrupt-Handler dasselbe Register, sperrt man Interrupts für diese Zeitspanne oder verwendet ein Register, das ausschließlich zum Setzen von Bits dient.

Dieses Thema üben Zur Themenseite

Weitere Fragen zu Grundlagen der Programmiersprache C

  1. Welche Aussage beschreibt das undefinierte Verhalten im Sinne des C-Standards richtig?
  2. int und unsigned int haben 32 Bit. Was davon ist nach dem C-Standard undefiniertes Verhalten?
  3. Wird die obige Funktion mit gcc und aktivierter Optimierung kompiliert, kann die Prüfung if (p == NULL) entfernt werden. Was ist der Grund dafür?
  4. Was legt der C-Standard über die Größe des Typs int fest?
  5. In Embedded-Programmen wird eine Variable für den Wert eines 32-Bit-Peripherieregisters oft nicht als unsigned int, sondern als uint32_t aus stdint.h deklariert. Was ist der Hauptgrund dafür?