- # Peripherie
- ## Klassifikation von Peripherie Komponenten
- - Intern oder on-chip Peripherie
- - Befinden sich neben Prozessor und Speicher im Mikrocontroller Chip
- - Externe Peripherie
- - Befindet sich außerhalb des Mikrocontroller Chips
- ## Steuer und Status Register
- - Ein eingebetteter Prozessor interagiert mit Peripherie Komponenten mittels Steuer und Status Register.
- - Diese Register sind Teil der Peripherie Hardware. Ihre Adresse, Größe und individuelle Bedeutung sind Charakteristiken der Peripherie.
- - Zum Beispiel sind die Steuer (Control) Register einer Seriellen Schnittstelle sehr unterschiedlich von denen eines Timers.
- ## Anbindung von Peripherie
- ### I/O Bereich
- - erfordert besondere Befehle für den Zugriff
- - Peripherie benötigt keinen Speicherbereich (Vorteil bei begrenztem Adressraum z.B. 8-Bit)
- - Beispiel: 8085
- ### Prozessor Speicher Bereich
- - Memory-Mapped Peripherie
- - Es ist einfacher damit zu arbeiten, da die Steuer und Status Register wie gewöhnliche Variablen im C-Code gehandhabt werden können.
- - Beispiel
- ``` C
- #define GPIO_BASE_ADDR 0xE0028000
- #define IOPIN0 (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0x00))
- ```
- Normalerweise werden Peripherie Register als **unsigned** Typen definiert, da die Interpretation des Inhaltes für gewöhnlich auf Bit-Ebene stattfindet.
- ## Bit Manipulations
- ### set n-th bit
- x |= (1 << (n))
- ### clear n-th bit
- x &= ~(1 << (n))
- ### test bit
- (x & (1 << (y)) ? 1 : 0)
- ### toggle n-th bit
- x ^= (1 << (n))
- ## Bit Felder
- ``` C
- struct {
- uint8_t bit0 :1;
- uint8_t bit1 :1;
- uint8_t bit2 :1;
- uint8_t bit3 :1;
- uint8_t nibble :4;
- } foo;
- ```
- **Theoretisch** können Bits innerhalb eines Bit-Feldes individuell gesetzt, getestet, gelöscht und umgeschaltet werden, ohne die anderen Bits zu beeinflussen.
- **Theoretisch weil** in vielen Fällen solche Operationen nicht Thread-Save sind. Und abhängig von der Compiler Implementierung teilweise sehr ineffizienten Code erzeugen. Des weiteren sind Bitfelder nicht portierbar, die Bits Verteilung ist stark Compiler abhängig und solche Daten können in unterschiedlichen Systemen nicht identisch interpretiert werden. (Bemerkung: ähnlich dem Endianess Problem)
- ### Probleme
- - nicht Thread-Save
- - compileranhängig
- - nicht portierbar
- ## Struktur Überlagerung
- - In eingebetteten Systemen mit Memory-Mapped I/O Peripherie Komponenten kann es sinnvoll sein eine C Struktur über die Peripherie Steuer und Status Register zu legen.
- - Damit kann mit einem Pointer auf die Struktur sehr anschaulich auf die Register der Peripherie zugegriffen werden.
- - Der Code ist sehr gut lesbar.
- - Der Compiler berechnet die Adress-Offsets beim Bilden automatisch.
- ``` C
- typedef struct {
- uint16_t count; /* Offset 0 */
- uint16_t maxCount; /* Offset 2 */
- uint16_t _reserved1; /* Offset 4 */
- uint16_t control; /* Offset 6 */
- } volatile timer_t
- ...
- timer_t* pTimer = (timer_t *)(0xABCD0123);
- ...
- if(pTimer->control & 0x08) {
- // do something
- }
- ```