Grundlagen der Systemnahen Programmierung in C (GSPiC)

Ähnliche Dokumente
Systemnahe Programmierung in C (SPiC)

c dl SPiC (Teil C, SS 11) 13 Zeiger und Felder 13.1 Zeiger Einführung 13 1 Zeigervariable := Behälter für Verweise ( Adresse) Beispiel int x = 5;

Grundlagen der Systemnahen Programmierung in C (GSPiC)

c dl SPiC (Teil C, SS 11) 14 µc-systemarchitektur 14.1 Überblick x0000 0x0046 main:... wait:... Peripherie 0x1FFFF

Was ist ein µ-controller?

Überblick: Teil C Systemnahe Softwareentwicklung

Grundlagen der Systemnahen Programmierung in C (GSPiC)

Überblick: Teil C Systemnahe Softwareentwicklung

Grundlagen der Systemnahen Programmierung in C (GSPiC)

Grundlagen der Systemnahen Programmierung in C (GSPiC)

Grundlagen der Systemnahen Programmierung in C (GSPiC)

Grundlagen der Systemnahen Programmierung in C (GSPiC)

Grundlagen der Systemnahen Programmierung in C (GSPiC)

Grundlagen der Systemnahen Programmierung in C (GSPiC)

Systemnahe Programmierung in C (SPiC)

Mechanismus Aufrufer Funktion Funktion Aufrufer Parameter ja mit Hilfe von Zeigern Funktionswert nein ja globale Variablen ja ja

2 Kurzeinführung in die Programmiersprache C 2.7 Programmstruktur & Module. 2 Kurzeinführung in die Programmiersprache C 2.7 Programmstruktur & Module

Überblick: Teil B Einführung in C

11-Praeprozessor: c dl SPiC (Teil B, SS 13) 11 Präprozessor 11.1 Einführung Leeres Makro (Flag)

3. Gültigkeit von Definitionen

Zentrale Fragestellung. Grundsätzliche Überlegungen über die Struktur eines Programms vor Beginn der Programmierung. Verschiedene Design-Methoden

Grundlagen der Programmierung Prof. H. Mössenböck. 7. Arrays

U5-2 Register beim AVR-µC

F Zeiger, Felder und Strukturen in C

3 Module in C. 4 Gültigkeit von Namen. 5 Globale Variablen (2) Gültig im gesamten Programm

GdI2 - Systemnahe Programmierung in C Übungen Jürgen Kleinöder Universität Erlangen-Nürnberg Informatik 4, 2006 U4.fm

Objektorientierte Programmierung

Pr r r P. ür ö r r. rst ür r t. r r 1 r rs tät r ür r. rs st r. P t

Inhalt. Übungen zu Systemnahe Programmierung in C (SPiC) Inhalt. Globale Variablen

Übungen zu Systemnahe Programmierung in C (SPiC)

E Mikrocontroller-Programmierung

Inhalt. Übungen zu Systemnahe Programmierung in C (SPiC) Schnittstellenbeschreibung. Inhalt

Wiederholung: Zugriff auf AVR-Prozessor-Register

Ausdrücke haben einen Wert sin(math.pi) wird zu 1 sin(kreisradius) wird zur Laufzeit ausgewertet. Informatik I Kapitel 6

Wiederholung: Zugriff auf AVR-Prozessor-Register. Aufgabe 3: 7seg-Modul der SPiCboard-Bibliothek

U3-1 Register beim AVR-μC. U3 3. Übung. U3-2 I/O-Ports des AVR-μC. 1 Überblick. 2 Makros für Register-Zugriffe. 1 Überblick

Übungen zu Systemnahe Programmierung in C (SPiC)

Problem: Gliederung betrifft nur die Aktivitäten, nicht die Struktur der Daten

Wiederholung: Zugriff auf AVR-Prozessor-Register. Aufgabe 3: 7seg-Modul der SPiCboard-Bibliothek

E Mikrocontroller-Programmierung. E.2 Beispiel: AVR-Mikrocontroller (ATmega-Serie) 1 Mikrocontroller-Umgebung. E.1 Überblick.

U3 3. Übung U3 3. Übung. Systemnahe Programmierung in C Übungen Moritz Strübe Universität Erlangen-Nürnberg Informatik 4, 2009 U3.fm

Besprechung Aufgabe 1. Pointer. Register und Ports. SPiC - Ü U3.1

... Polling. Interrupt: c dl GSPiC (Teil C, SS 11) 15 Nebenläufigkeit 15.1 Interrupts: Einführung 15 1

Sebastian Maier (Lehrstuhl Informatik 4) Übung 4. Sommersemester 2017

Systemnahe Programmierung in C (SPiC)

Makros sind Textersetzungen, welche vom Präprozessor aufgelöst werden. Dies Passiert bevor der Compiler die Datein verarbeitet.

Systemnahe Programmierung in C (SPiC)

5.2 BASIC MSC (BMSC) BASIC MSC. Kommunikation zwischen Instanzen. Message Sequence Charts

Programmieren in C/C++ und MATLAB. Programmieren in C/C++ und MATLAB. Sebastian Bauer Sven Willert Sabine Schmidt

Systemnahe Programmierung in C (SPiC)

Übungen zur Systemprogrammierung I Wintersemester 2001/2002

Inhalt. Aufgabe 4: LED-Modul Hinweise Testen des Moduls Sommersemester 2015

Ansteuerung eines LCD-Screens

Einleitung Die Pins alphabetisch Kapitel 1 Programmierung des ATmega8 und des ATmega

Inhalt. Übungen zu Systemnahe Programmierung in C (SPiC) Implementierung von Interruptbehandlungen. Interrupts

U2-1 Register beim AVR- C. U2-2 I/O-Ports des AVR- C. 1 Überblick. 2 Makros für Register-Zugriffe. 1 Überblick

U2 Fortgeschrittene AVR-Programmierung. U2-1 Externe Interrupts des AVR-μC. 1 Flanken-/Pegel-Steuerung. 1 Flanken-/Pegel-Steuerung (2) 2 Maskieren

F Zeiger, Felder und Strukturen in C

Real-time Simulation Center for Automation

U5 Fortgeschrittene AVR-Programmierung

Atmega Interrupts. Rachid Abdallah Gruppe 3 Betreuer : Benjamin Bös

Systemnahe Programmierung in C (SPiC)

Parallel-IO. Ports am ATmega128

Übungen zu Grundlagen der systemnahen Programmierung in C (GSPiC) im Wintersemester 2017/18

x x x Eine solche Verzweigung ist als Verzweigung der vom Signal getragenen Information

Selbststudium Informationssysteme - H1102 Christian Bontekoe & Felix Rohrer

U5 Fortgeschrittene AVR-Programmierung U5 Fortgeschrittene AVR-Programmierung. Synchronisation mit Unterbrechungsbehandlungen

Objektorientierte Programmierung. Objektorientierte Programmierung. Objektorientierte Programmierung. Objektorientierte Programmierung

Einführung in die Welt der Microcontroller


Übungen zu Systemnahe Programmierung in C (SPiC) Inhalt. Moritz Strübe, Rainer Müller (Lehrstuhl Informatik 4) Sommersemester 2014

Einführung Sprachfeatures Hinweise, Tipps und Styleguide Informationen. Einführung in C. Patrick Schulz

Übungen zu Systemnahe Programmierung in C (SPiC)

G2 Grundlagen der Vektorrechnung

Übungen zu Systemnahe Programmierung in C (SPiC)

Übungen zu Systemnahe Programmierung in C (SPiC) Wintersemester 2018/19

Die AVR Mikrocontrollerfamilie

Programmiertechnik. Teil 4. C++ Funktionen: Prototypen Overloading Parameter. C++ Funktionen: Eigenschaften

2.1 Atmega-Peripherie/Interrupts

f) Was versteht man beim Zugriff auf I/O-Register unter dem Begriff "Memory-mapped"?

Übungen zu Systemnahe Programmierung in C (SPiC) Wintersemester 2017/18

1KOhm + - y = x LED leuchtet wenn Schalter x gedrückt ist

Repetitorium Programmieren I + II

Python 1. Vorlesung Computerlinguistische Techniken Alexander Koller. 27. Oktober 2014

4.0 Der Atmel AT89LPx052 Mikrocontroller

J Mikrocontroller-Programmierung

6. Quadratische Gleichungen

Unter einem Interrupt kann man sich einen durch Hardware ausgelösten Unterprogrammaufruf vorstellen.

2. Das Rechnen mit ganzen Zahlen (Rechnen in )

Mikroprozessortechnik Grundlagen 1

d) Was passiert, wenn das folgende Programmstück übersetzt und ausgeführt

2

Aufbau und Funktionsweise eines Computers

05. Assembler-Programmierung. Datenstrukturen des ATMega32. Literatur

Die Technik hinter IoT: Arduino, Raspberry Pi & Co.

Bisher haben wir keine Annahmen bzgl. der Sortierung der gegebenen Werte gemacht, d.h. sie durften in beliebiger Reihenfolge im Array a stehen

Zeiger vom Typ (void *) sind am besten für Zeigerarithmetik geeignet, da sie kompatibel zu jedem Zeigertyp sind.

Transkript:

Grundlgen der Systemnhen Progrmmierung in C (GSPiC) Überblick: Teil C Systemnhe Softwreentwicklung Teil C Systemnhe Softwreentwicklung 12 Progrmmstruktur und Module 13 Zeiger und Felder V_GSPIC_hndout Dniel Lohmnn Lehrstuhl für Informtik 4 Verteilte Systeme und Betriebssysteme Friedrich-Alexnder-Universität Erlngen-Nürnberg Wintersemester 2012 http://www4.cs.fu.de/lehre/ws12/v_gspic V_GSPIC_hndout 14 µc-systemrchitektur 15 Nebenläufigkeit 16 Speicherorgnistion Softwreentwurf Beispiel-Projekt: Eine Wettersttion Softwreentwurf: Grundsätzliche Überlegungen über die Struktur eines Progrmms vor Beginn der Progrmmierung Ziel: Zerlegung des Problems in beherrschbre Einheiten Es gibt eine Vielzhl von Softwreentwurfs-Methoden Objektorientierter Entwurf Stnd der Kunst Dekomposition in Klssen und Objekte An Progrmmiersprchen wie C++ oder Jv usgelegt [ GDI, IV] Top-Down-Entwurf / Funktionle Dekomposition Bis Mitte der 80er Jhre fst usschließlich verwendet Dekomposition in Funktionen und Funktionsufrufe An Progrmmiersprchen wie Fortrn, Cobol, Pscl oder C orientiert Systemnhe Softwre wird oft (noch) mit Funktionler Dekomposition entworfen und entwickelt. Typisches eingebettetes System Mehrere Sensoren 0+&1 Wind -)#''8)# Luftdruck Tempertur 2#$3 Mehrere Aktoren ; # < (hier: Ausgbegeräte) LCD-Anzeige 95: PC über RS232 PC über USB Sensoren und Aktoren n den µc ngebunden über verschiedene Bussysteme I 2 C RS232 Wie sieht die funktionle Dekomposition der Softwre us? ;<%&()%..#),=>?4@ 45676 "+'3.*A c dl GSPiC (Teil C, WS 12) 12 Progrmmstruktur und Module 12.1 Einführung 12 1 c dl GSPiC (Teil C, WS 12) 12 Progrmmstruktur und Module 12.2 Funktionle Dekomposition 12 2

Funktionle Dekomposition: Beispiel Funktionle Dekomposition: Probleme Funktionle Dekomposition der Wettersttion (Auszug): 1. Sensordten lesen 0+&1 1.1 Tempertursensor lesen -)#''8)# 1.1.1 I 2 C-Dtenübertrgung intiieren 2#$3 1.1.2 Dten vom I 2 C-Bus lesen ; # < 1.2 Drucksensor lesen 95: 1.3 Windsensor lesen 2. Dten ufbereiten (z. B. glätten) 3. Dten usgeben 3.1 Dten über RS232 versenden 3.1.1 Budrte und Prität festlegen (einmlig) 3.1.2 Dten schreiben 3.2 LCD-Disply ktulisieren 4. Wrten und b Schritt 1 wiederholen ;<%&()%..#),=>?4@ 45676 "+'3.*A Erzielte Gliederung betrchtet nur die Struktur der Aktivitäten, nicht jedoch die die Struktur der Dten Gefhr: Funktionen rbeiten wild uf einer Unmenge schlecht strukturierter Dten mngelhfte Trennung der Belnge sendbuf[] RS232Init() bud RS232Send() init curdev I2CRec() I2CStrt() lsttemp lstwind GetTemp() Dten min() SendToPC() Aktivitäten c dl GSPiC (Teil C, WS 12) 12 Progrmmstruktur und Module 12.2 Funktionle Dekomposition 12 3 c dl GSPiC (Teil C, WS 12) 12 Progrmmstruktur und Module 12.2 Funktionle Dekomposition 12 4 Funktionle Dekomposition: Probleme Zugriff uf Dten (Vriblen) Erzielte Gliederung betrchtet nur die Struktur der Aktivitäten, nicht jedoch die die Struktur der Dten Gefhr: Funktionen rbeiten wild uf einer Unmenge schlecht strukturierter Dten mngelhfte Trennung der Belnge Vriblen hben 10 1 Sichtbrkeit (Scope) Wer knn uf die Vrible zugreifen? Lebensduer Wie lnge steht der Speicher zur Verfügung? Wird festgelegt durch Position (Pos) und Speicherklsse (SK) Pos SK Sichtbrkeit Lebensduer Prinzip der Trennung der Belnge Dinge, die nichts miteinnder zu tun hben, sind uch getrennt unterzubringen! Trennung der Belnge (Seprtion of Concerns) ist ein Fundmentlprinzip der Informtik (wie uch jeder nderen Ingenieursdisziplin). Lokl keine, uto Definition Blockende Definition Blockende sttic Definition Blockende Progrmmstrt Progrmmende Globl keine unbeschränkt Progrmmstrt Progrmmende sttic modulweit Progrmmstrt Progrmmende int = 0; sttic int b = 47; void f() { uto int = b; sttic int c = 11; // : globl // b: locl to module // : locl to function (uto optionl) // destroyed t end of block // c: locl to function, not destroyed c dl GSPiC (Teil C, WS 12) 12 Progrmmstruktur und Module 12.2 Funktionle Dekomposition 12 4 c dl GSPiC (Teil C, WS 12) 12 Progrmmstruktur und Module 12.3 Globle Vriblen 12 5

Zugriff uf Dten (Vriblen) (Forts.) Sichtbrkeit und Lebensduer sollten restriktiv usgelegt werden Sichtbrkeit so beschränkt wie möglich! Überrschende Zugriffe von ußen usschließen (Fehlersuche) Implementierungsdetils verbergen (Blck-Box-Prinzip, informtion hiding) Lösung: Modulrisierung Seprtion jeweils zusmmengehöriger Dten und Funktionen in übergeordnete Einheiten Module Lebensduer so kurz wie möglich Speicherpltz spren Insbesondere wichtig uf µ-controller-plttformen 1 3 sendbuf[] bud init curdev lsttemp lstwind min() Konsequenz: Globle Vriblen vermeiden! Globle Vriblen sind überll sichtbr Regel: Globle Vriblen belegen Speicher über die gesmte Progrmmlufzeit Vriblen erhlten stets die geringstmögliche Sichtbrkeit und Lebensduer RS232Init() RS232Send() RS232.c I2CRec() I2CStrt() I2C.c SendToPC() GetTemp() wether.c c dl GSPiC (Teil C, WS 12) 12 Progrmmstruktur und Module 12.3 Globle Vriblen 12 6 c dl GSPiC (Teil C, WS 12) 12 Progrmmstruktur und Module 12.4 Modulrisierung 12 7 Ws ist ein Modul? Module in C [ Jv] Modul := (<Menge von Funktionen>, <Menge von Dten>, <Schnittstelle>) ( clss in Jv) Module sind größere Progrmmbusteine 9 1 Problemorientierte Zusmmenfssung von Funktionen und Dten Trennung der Belnge Ermöglichen die einfche Wiederverwendung von Komponenten Ermöglichen den einfchen Austusch von Komponenten Verbergen Implementierungsdetils (Blck-Box-Prinzip) Zugriff erfolgt usschließlich über die Modulschnittstelle Modul Abstrktion 4 1 Die Schnittstelle eines Moduls bstrhiert Von der ttsächlichen Implementierung der Funktionen Von der internen Drstellung und Verwendung von Dten In C ist ds Modulkonzept nicht Bestndteil der Sprche, 3 13 sondern rein idiomtisch (über Konventionen) relisiert Modulschnittstelle.h-Dtei (enthält Deklrtionen 9 7 ) Modulimplementierung.c-Dtei (enthält Definitionen 9 3 ) Modulverwendung #include <Modul.h> void RS232Init( uint16_t br ); RS232.h: Schnittstelle / Vertrg (öffentl.) void RS232Send( chr ch ); Deklrtion der bereitgestellten Funktionen (und ggf. Dten) #include <RS232.h> RS232.c: Implementierung (nicht öffentl.) sttic uint16_t bud = 2400; Definition der bereitgestellten sttic chr sendbuf[16]; Funktionen (und ggf. Dten) void RS232Init( uint16_t br) { Ggf. modulinterne Hilfsfunktionen und Dten (sttic) bud = br; void RS232Send( chr ch ) { sendbuf[] = ch; Inklusion der eigenen Schnittstelle stellt sicher, dss der Vertrg eingehlten wird c dl GSPiC (Teil C, WS 12) 12 Progrmmstruktur und Module 12.4 Modulrisierung 12 8 c dl GSPiC (Teil C, WS 12) 12 Progrmmstruktur und Module 12.5 Module in C 12 9

Module in C Export [ Jv] Module in C Import [ Jv] Ein C-Modul exportiert eine Menge von definierten Symbolen Alle Funktionen und globlen Vriblen ( public in Jv) Export knn mit sttic unterbunden werden ( privte in Jv) ( Einschränkung der Sichtbrkeit 12 5 ) Export erfolgt beim Übersetzungsvorgng (.c-dtei.o-dtei) Ein C-Modul importiert eine Menge nicht-definierter Symbole Funktionen und globle Vriblen, die verwendet werden, im Modul selber jedoch nicht definiert sind Werden beim Übersetzen ls unufgelöst mrkiert Quelldtei (br.c) Objektdtei (br.o) Quelldtei (foo.c) uint16_t ; // public sttic uint16_t b; // privte void f(void) { sttic void g(int) { foo.c Compiler foo.o // public // privte Objektdtei (foo.o), f Symbole und f werden exportiert. Symbole b und g sind sttic definiert und werden deshlb nicht exportiert. extern uint16_t ; // declre void f(void); = 0x4711; f(); // declre // public // use // use Symbol min wird exportiert. Symbole und f sind unufgelöst. c dl GSPiC (Teil C, WS 12) 12 Progrmmstruktur und Module 12.5 Module in C 12 10 c dl GSPiC (Teil C, WS 12) 12 Progrmmstruktur und Module 12.5 Module in C 12 11 Module in C Import (Forts.) [ Jv] Module in C Heder [ Jv] Die eigentliche Auflösung erfolgt durch den Linker [ GDI, VI-158] foo.c br.c Compiler foo.o br.o, f min, f Linker min,, f br Elemente us fremden Modulen müssen deklriert werden Funktionen durch normle Deklrtion 9 7 void f(void); Globle Vriblen durch extern extern uint16_t ; Ds extern unterscheidet eine Vriblendeklrtion von einer Vriblendefinition. Linken ist nicht typsicher! Typinformtionen sind in Objektdteien nicht mehr vorhnden Auflösung durch den Linker erfolgt usschließlich über die Symbolnmen (Bezeichner) Typsicherheit muss beim Übersetzen sichergestellt werden Einheitliche Deklrtionen durch gemeinsme Heder-Dtei Die Deklrtionen erfolgen sinnvollerweise in einer Heder-Dtei, die von der Modulentwicklerin bereitgestellt wird Schnittstelle des Moduls ( interfce in Jv) Exportierte Funktionen des Moduls Exportierte globle Vriblen des Moduls Modulspezifische Konstnten, Typen, Mkros Verwendung durch Inklusion ( import in Jv) Wird uch vom Modul inkludiert, um Übereinstimmung von Deklrtionen und Definitionen sicher zu stellen ( implements in Jv) c dl GSPiC (Teil C, WS 12) 12 Progrmmstruktur und Module 12.5 Module in C 12 12 c dl GSPiC (Teil C, WS 12) 12 Progrmmstruktur und Module 12.5 Module in C 12 13

Module in C Heder (Forts.) [ Jv] Zurück zum Beispiel: Wettersttion Modulschnittstelle: foo.h // foo.h #ifndef _FOO_H #define _FOO_H // declrtions extern uint16_t ; void f(void); #endif // _FOO_H Modulimplementierung foo.c // foo.c #include <foo.h> // definitions uint16_t ; void f(void){ Modulverwendung br.c (vergleiche 12 11 ) RS232.h I2C.h RS232.c I2C.c wether.c io.h.h r r Quellmodule Objektmodule ELF-Binry gcc (Compiler) RS232.o I2C.o wether.o ld (Linker) io.o.o.o.o.o.o vr-libc.lib wether // br.c extern uint16_t ; void f(void); #include <foo.h> = 0x4711; f(); Jedes Modul besteht us Heder- und Implementierungsdtei(en).h-Dtei definiert die Schnittstelle.c-Dtei implementiert die Schnittstelle, inkludiert.h-dtei, um sicherzustellen, dss Deklrtion und Definition übereinstimmen Modulverwendung durch Inkludieren der modulspezifischen.h-dtei Ds Gnze funktioniert entsprechend bei Bibliotheken c dl GSPiC (Teil C, WS 12) 12 Progrmmstruktur und Module 12.5 Module in C 12 14 c dl GSPiC (Teil C, WS 12) 12 Progrmmstruktur und Module 12.5 Module in C 12 15 Zusmmenfssung Überblick: Teil C Systemnhe Softwreentwicklung Prinzip der Trennung der Belnge Modulrisierung Wiederverwendung und Austusch wohldefinierter Komponenten Verbergen von Implementierungsdetils In C ist ds Modulkonzept nicht Bestndteil der Sprche, sondern idiomtisch durch Konventionen relisiert Modulschnittstelle.h-Dtei (enthält Deklrtionen) Modulimplementierung.c-Dtei (enthält Definitionen) Modulverwendung #include <Modul.h> privte Symbole ls sttic definieren Die eigentliche Zusmmenfügung erfolgt durch den Linker Auflösung erfolgt usschließlich über Symbolnmen Linken ist nicht typsicher! Typsicherheit muss beim Übersetzen sichergestellt werden durch gemeinsme Heder-Dtei V_GSPIC_hndout 12 Progrmmstruktur und Module 13 Zeiger und Felder 14 µc-systemrchitektur 15 Nebenläufigkeit 16 Speicherorgnistion c dl GSPiC (Teil C, WS 12) 12 Progrmmstruktur und Module 12.6 Zusmmenfssung 12 16

Einordnung: Zeiger (Pointer) Zeiger (Pointer) Literl: Drstellung eines Wertes Vrible: chr ; Behälter für einen Wert 0110 0001 Eine Zeigervrible (Pointer) enthält ls Wert die Adresse einer nderen Vriblen Ein Zeiger verweist uf eine Vrible (im Speicher) Über die Adresse knn mn indirekt uf die Zielvrible (ihren Speicher) zugreifen Drus resultiert die große Bedeutung von Zeigern in C Zeiger-Vrible: chr *p = &; Behälter für eine Referenz uf eine Vrible ein p Funktionen können Vriblen des Aufrufers verändern 9 5 (cll-by-reference) Speicher lässt sich direkt nsprechen Effizienz durch Effizientere Progrmme Mschinennähe 3 14 Aber uch viele Probleme! Progrmmstruktur wird unübersichtlicher (welche Funktion knn uf welche Vriblen zugreifen?) Zeiger sind die häufigste Fehlerquelle in C-Progrmmen! c dl GSPiC (Teil C, WS 12) 13 Zeiger und Felder 13.1 Zeiger Einführung 13 1 c dl GSPiC (Teil C, WS 12) 13 Zeiger und Felder 13.1 Zeiger Einführung 13 2 Definition von Zeigervriblen Adress- und Verweisopertoren Zeigervrible := Behälter für Verweise ( Adresse) Syntx (Definition): Typ * Bezeichner ; Beispiel int x = 5; x 5 int *ip; ip ➊ int y; ip = &x; ➊ y = *ip; ➋ y 5 ➋ Adressopertor: & x Der unäre &-Opertor liefert die Referenz ( Adresse im Speicher) der Vriblen x. Verweisopertor: * y Der unäre * -Opertor liefert die Zielvrible ( Speicherzelle / Behälter), uf die der Zeiger y verweist (Dereferenzierung). Es gilt: (* (& x)) x Der Verweisopertor ist die Umkehropertion des Adressopertors. Achtung: Verwirrungsgefhr (*** Ich seh überll Sterne ***) Ds * -Symbol ht in C verschiedene Bedeutungen, je nch Kontext 1. Multipliktion (binär): x * y in Ausdrücken 2. Typmodifizierer: uint8_t *p1, *p2 typedef chr* CPTR in Definitionen und Deklrtionen 3. Verweis (unär): x = *p1 in Ausdrücken Insbesondere 2. und 3. führen zu Verwirrung * wird fälschlicherweise für ein Bestndteil des Bezeichners gehlten. c dl GSPiC (Teil C, WS 12) 13 Zeiger und Felder 13.2 Zeiger Definition 13 3 c dl GSPiC (Teil C, WS 12) 13 Zeiger und Felder 13.2 Zeiger Definition 13 4

Zeiger ls Funktionsrgumente Zeiger ls Funktionsrgumente (Forts.) Prmeter werden in C immer by-vlue übergeben 9 5 Prmeterwerte werden in lokle Vriblen der ufgerufenen Funktion kopiert Aufgerufene Funktion knn ttsächliche Prmeter des Aufrufers nicht ändern Ds gilt uch für Zeiger (Verweise) Aufgerufene Funktion erhält eine Kopie des Adressverweises [ GDI, II-89] Mit Hilfe des *-Opertors knn drüber jedoch uf die Zielvrible zugegriffen werden und diese verändert werden Cll-by-reference Beispiel (Gesmtüberblick) void swp (int *, int *); int min() { int =47, b=11; swp(&, &b); ➊ void swp (int *px, int *py) { int tmp; tmp = *px; ➋ *px = *py; ➌ *py = tmp; ➍ b px py tmp ➊ ➌ ➍ ➋ c dl GSPiC (Teil C, WS 12) 13 Zeiger und Felder 13.3 Zeiger und Funktionen 13 5 c dl GSPiC (Teil C, WS 12) 13 Zeiger und Felder 13.3 Zeiger und Funktionen 13 6 Zeiger ls Funktionsrgumente (Forts.) Beispiel (Einzelschritte) Zeiger ls Funktionsrgumente (Forts.) Beispiel (Einzelschritte) void swp (int *, int *); int min() { int =47, b=11; swp(&, &b); ➊ 47 b 11 ➊ void swp (int *, int *); int min() { int =47, b=11; swp(&, &b); 47 b 11 void swp (int *px, int *py) { int tmp; px py void swp (int *px, int *py) { int tmp; px py tmp tmp c dl GSPiC (Teil C, WS 12) 13 Zeiger und Felder 13.3 Zeiger und Funktionen 13 6 c dl GSPiC (Teil C, WS 12) 13 Zeiger und Felder 13.3 Zeiger und Funktionen 13 6

Zeiger ls Funktionsrgumente (Forts.) Beispiel (Einzelschritte) Zeiger ls Funktionsrgumente (Forts.) Beispiel (Einzelschritte) void swp (int *, int *); int min() { int =47, b=11; swp(&, &b); 47 b 11 void swp (int *, int *); int min() { int =47, b=11; swp(&, &b); 47 b 11 void swp (int *px, int *py) { int tmp; tmp = *px; ➋ *px px py tmp void swp (int *px, int *py) { int tmp; tmp = *px; ➋ *px = *py; ➌ *px px *py py tmp 47 c dl GSPiC (Teil C, WS 12) 13 Zeiger und Felder 13.3 Zeiger und Funktionen 13 6 c dl GSPiC (Teil C, WS 12) 13 Zeiger und Felder 13.3 Zeiger und Funktionen 13 6 Zeiger ls Funktionsrgumente (Forts.) Beispiel (Einzelschritte) Zeiger ls Funktionsrgumente (Forts.) Beispiel (Einzelschritte) void swp (int *, int *); int min() { int =47, b=11; swp(&, &b); 11 b 11 void swp (int *, int *); int min() { int =47, b=11; swp(&, &b); 11 b 47 void swp (int *px, int *py) { int tmp; tmp = *px; ➋ *px = *py; ➌ px py ➌ tmp 47 void swp (int *px, int *py) { int tmp; tmp = *px; ➋ *px = *py; ➌ *py = tmp; ➍ px py ➍ tmp 47 c dl GSPiC (Teil C, WS 12) 13 Zeiger und Felder 13.3 Zeiger und Funktionen 13 6 c dl GSPiC (Teil C, WS 12) 13 Zeiger und Felder 13.3 Zeiger und Funktionen 13 6

Einordnung: Felder (Arrys) [ Jv] Feldinitilisierung Feldvrible := Behälter für eine Reihe von Werten desselben Typs Syntx (Definition): Typ Bezeichner [ IntAusdruck ] ; Typ Typ der Werte [=Jv] Wie ndere Vriblen uch, knn ein Feld bei Definition eine initile Wertzuweisung erhlten uint8_t LEDs[4] = { RED0, YELLOW0, GREEN0, BLUE0 ; int prim[5] = { 1, 2, 3, 5, 7 ; Bezeichner Nme der Feldvriblen [=Jv] IntAusdruck Beispiele: sttic uint8_t LEDs[ 8*2 ]; void f( int n ) { uto chr [ NUM_LEDS * 2]; uto chr b[ n ]; Konstnter Gnzzhl-Ausdruck, definiert die Feldgröße ( Anzhl der Elemente). Ab C99 drf IntAusdruck bei uto-feldern uch vribel (d. h. beliebig, ber fest) sein. // constnt, fixed rry size [ Jv] // constnt, fixed rry size // C99: vrible, fixed rry size Werden zu wenig Initilisierungselemente ngegeben, so werden die restlichen Elemente mit 0 initilisiert uint8_t LEDs[4] = { RED0 ; // => { RED0, 0, 0, 0 int prim[5] = { 1, 2, 3 ; // => { 1, 2, 3, 0, 0 Wird die explizite Dimensionierung usgelssen, so bestimmt die Anzhl der Initilisierungselemente die Feldgröße uint8_t LEDs[] = { RED0, YELLOW0, GREEN0, BLUE0 ; int prim[] = { 1, 2, 3, 5, 7 ; c dl GSPiC (Teil C, WS 12) 13 Zeiger und Felder 13.4 Felder Einführung 13 7 c dl GSPiC (Teil C, WS 12) 13 Zeiger und Felder 13.4 Felder Einführung 13 8 Feldzugriff Felder sind Zeiger Syntx: Feld [ IntAusdruck ] Wobei 0 IntAusdruck < n für n = Feldgröße Achtung: Feldindex wird nicht überprüft häufige Fehlerquelle in C-Progrmmen Beispiel uint8_t LEDs[] = { RED0, YELLOW0, GREEN0, BLUE0 ; LEDs[ 3 ] = BLUE1; for( unit8_t i = 0; i < 4; ++i ) { sb_led_on( LEDs[ i ] ); LEDs[ 4 ] = GREEN1; // UNDEFINED!!! [=Jv] [ Jv] Ein Feldbezeichner ist syntktisch äquivlent zu einem konstnten Zeiger uf ds erste Element des Feldes: rry &rry[0] Ein Alis kein Behälter Wert knn nicht verändert werden Über einen so ermittelten Zeiger ist ein indirekter Feldzugriff möglich Beispiel (Gesmtüberblick) int rry[5]; int *ip = rry; ➊ int *ep; ep = &rry[0]; ➋ ep = &rry[2]; ➌ *ep = 1; ➍ rry ip ep ➊ ➋ ➊ ➋ ➌ 1 ➍ ➌ c dl GSPiC (Teil C, WS 12) 13 Zeiger und Felder 13.4 Felder Einführung 13 9 c dl GSPiC (Teil C, WS 12) 13 Zeiger und Felder 13.5 Syntktische Äquivlenz 13 10

Felder sind Zeiger Ein Feldbezeichner ist syntktisch äquivlent zu einem konstnten Zeiger uf ds erste Element des Feldes: rry &rry[0] Ein Alis kein Behälter Wert knn nicht verändert werden Über einen so ermittelten Zeiger ist ein indirekter Feldzugriff möglich Felder sind Zeiger Ein Feldbezeichner ist syntktisch äquivlent zu einem konstnten Zeiger uf ds erste Element des Feldes: rry &rry[0] Ein Alis kein Behälter Wert knn nicht verändert werden Über einen so ermittelten Zeiger ist ein indirekter Feldzugriff möglich Beispiel (Einzelschritte) Beispiel (Einzelschritte) int rry[5]; rry int rry[5]; rry int *ip = rry; ➊ int *ep; ep = &rry[0]; ➋ int *ip = rry; ➊ int *ep; ep = &rry[0]; ➋ ep = &rry[2]; ➌ ip ep ➌ ep = &rry[2]; ➌ *ep = 1; ➍ ip ep *ep ➌ c dl GSPiC (Teil C, WS 12) 13 Zeiger und Felder 13.5 Syntktische Äquivlenz 13 10 c dl GSPiC (Teil C, WS 12) 13 Zeiger und Felder 13.5 Syntktische Äquivlenz 13 10 Zeiger sind Felder Rechnen mit Zeigern Ein Feldbezeichner ist syntktisch äquivlent zu einem konstnten Zeiger uf ds erste Element des Feldes: rry &rry[0] Diese Beziehung gilt in beide Richtungen: *rry rry[0] Ein Zeiger knn wie ein Feld verwendet werden Insbesondere knn der [ ] - Opertor ngewndt werden 13 9 Im Unterschied zu einem Feldbezeichner ist eine Zeigervrible ein Behälter Ihr Wert ist veränderbr Neben einfchen Zuweisungen ist dbei uch Arithmetik möglich int rry[3]; int *ip = rry; ➊ rry Beispiel (vgl. 13 9 ) uint8_t LEDs[] = { RED0, YELLOW0, GREEN0, BLUE0 ; LEDs[ 3 ] = BLUE1; uint8_t *p = LEDs; for( unit8_t i = 0; i < 4; ++i ) { sb_led_on( p[ i ] ); ip++; ➋ ip++; ➌ int rry[5]; ip = rry; ➊ ip ➊ ip ➊ ➊ ➋ ➌ (ip+3) &ip[3] Bei der Zeigerrithmetik wird immer die Größe des Objekttyps mit berücksichtigt. c dl GSPiC (Teil C, WS 12) 13 Zeiger und Felder 13.5 Syntktische Äquivlenz 13 11 c dl GSPiC (Teil C, WS 12) 13 Zeiger und Felder 13.6 Zeigerrithmetik 13 12

Zeigerrithmetik Opertionen Felder sind Zeiger sind Felder Zusmmenfssung Arithmetische Opertionen ++ Prä-/Postinkrement Verschieben uf ds nächste Objekt In Kombintion mit Zeigerrithmetik lässt sich in C jede Feldopertion uf eine äquivlente Zeigeropertion bbilden. Prä-/Postdekrement Verschieben uf ds vorngegngene Objekt Für int i, rry[n], *ip = rry; mit 0 i < N gilt: +, Addition / Subtrktion eines int-wertes Ergebniszeiger ist verschoben um n Objekte Subtrktion zweier Zeiger Anzhl der Objekte n zwischen beiden Zeigern (Distnz) rry &rry[0] ip &ip[0] *rry rry[0] * ip ip[0] *(rry + i) rry[i] * (ip + i) ip[i] rry++ ip++ Vergleichsopertionen: <, <=, ==, >=, >,! = 7 3 Zeiger lssen sich wie Gnzzhlen vergleichen und ordnen Fehler: rry ist konstnt! Umgekehrt können Zeigeropertionen uch durch Feldopertionen drgestellt werden. Der Feldbezeichner knn ber nicht verändert werden. c dl GSPiC (Teil C, WS 12) 13 Zeiger und Felder 13.6 Zeigerrithmetik 13 13 c dl GSPiC (Teil C, WS 12) 13 Zeiger und Felder 13.6 Zeigerrithmetik 13 14 Felder ls Funktionsprmeter Felder ls Funktionsprmeter (Forts.) Felder werden in C immer ls Zeiger übergeben Cll-by-reference sttic uint8_t LEDs[] = {RED0, YELLOW1; void enlight( uint8_t *rry, unsigned n ) { for( unsigned i = 0; i < n; ++i ) sb_led_on( rry[i] ); [=Jv] Felder werden in C immer ls Zeiger übergeben Cll-by-reference Wird der Prmeter ls const deklriert, so knn die Funktion die Feldelemente nicht verändern Guter Stil! void enlight( const uint8_t *rry, unsigned n ) { [=Jv] [ Jv] enlight( LEDs, 2 ); uint8_t moreleds[] = {YELLOW0, BLUE0, BLUE1; enlight( moreleds, 3); R 0 Y 0 G 0 B 0 R 1 Y 1 G 1 B 1 Informtionen über die Feldgröße gehen dbei verloren! Die Feldgröße muss explizit ls Prmeter mit übergeben werden In mnchen Fällen knn sie uch in der Funktion berechnet werden (z. B. bei Strings durch Suche nch dem bschließenden NUL-Zeichen) Um nzuzeigen, dss ein Feld (und kein Zeiger uf Vrible ) erwrtet wird, ist uch folgende äquivlente Syntx möglich: void enlight( const uint8_t rry[], unsigned n ) { Achtung: Ds gilt so nur bei Deklrtion eines Funktionprmeters Bei Vriblendefinitionen ht rry[] eine völlig ndere Bedeutung (Feldgröße us Initilisierungsliste ermitteln, 13 8 ) c dl GSPiC (Teil C, WS 12) 13 Zeiger und Felder 13.7 Felder ls Funktionsprmeter 13 15 c dl GSPiC (Teil C, WS 12) 13 Zeiger und Felder 13.7 Felder ls Funktionsprmeter 13 16

Felder ls Funktionsprmeter (Forts.) Zeiger uf Zeiger Die Funktion int strlen(const chr *) us der Stndrdbibliothek liefert die Anzhl der Zeichen im übergebenen String const chr *string = "hllo"; // string is rry of chr sb_7seg_shownumber( strlen(string) ); Dbei gilt: Implementierungsvrinten Vrinte 1: Feld-Syntx "hllo" h l l o \0 6 13 Vrinte 2: Zeiger-Syntx Ein Zeiger knn uch uf eine Zeigervrible verweisen int x = 5; int *ip = &x; int **ipp = &ip; /* ** ipp = 5 */ x 5 ip ipp Wird vor llem bei der Prmeterübergbe n Funktionen benötigt Zeigerprmeter cll-by-reference übergeben (z. B. swp()-funktion für Zeiger) Ein Feld von Zeigern übergeben int strlen( const chr s[] ) { int n=0; while( s[n]!= 0 ) n++; urn n; int strlen( const chr *s ) { const chr *end = s; while( *end ) end++; urn end - s; c dl GSPiC (Teil C, WS 12) 13 Zeiger und Felder 13.7 Felder ls Funktionsprmeter 13 17 c dl GSPiC (Teil C, WS 12) 13 Zeiger und Felder 13.8 Erweiterte Zeigertypen 13 18 Zeiger uf Funktionen Zeiger uf Funktionen (Forts.) Ein Zeiger knn uch uf eine Funktion verweisen Dmit lssen sich Funktionen n Funktionen übergeben Funktionen höherer Ordnung Beispiel // invokes job() every second void doperiodiclly( void (*job)(void) ) { while( 1 ) { job(); // invoke job for( voltile uint16_t i = 0; i < 0xffff; ++i ) ; // wit second void blink( void ) { sb_led_toggle( RED0 ); doperiodiclly( blink ); // pss blink() s prmeter Syntx (Definition): Typ ( * Bezeichner )( FormlePrm opt ); (sehr ähnlich zur Syntx von Funktionsdeklrtionen) 9 3 Typ Bezeichner Rückgbetyp der Funktionen, uf die dieser Zeiger verweisen knn Nme des Funktionszeigers FormlePrm opt Formle Prmeter der Funktionen, uf die dieser Zeiger verweisen knn: Typ 1,..., Typ n Ein Funktionszeiger wird genu wie eine Funktion verwendet Aufruf mit Bezeichner ( TtPrm ) 9 4 Adress- (&) und Verweisopertor (*) werden nicht benötigt 13 4 Ein Funktionsbezeichner ist ein konstnter Funktionszeiger void blink( uint8_t which ) { sb_led_toggle( which ); void (*myfun)(uint8_t); // myfun is pointer to function myfun = blink; // blink is constnt pointer to function myfun( RED0 ); // invoke blink() vi function pointer blink( RED0 ); // invoke blink() c dl GSPiC (Teil C, WS 12) 13 Zeiger und Felder 13.8 Erweiterte Zeigertypen 13 19 c dl GSPiC (Teil C, WS 12) 13 Zeiger und Felder 13.8 Erweiterte Zeigertypen 13 20

Zeiger uf Funktionen (Forts.) Zusmmenfssung Funktionszeiger werden oft für Rückruffunktionen (Cllbcks) zur Zustellung synchroner Ereignisse verwendet ( Listener in Jv) // Exmple: synchronous button events with libspicbord #include <vr/interrupt.h> // for sei() #include <7seg.h> // for sb_7seg_shownumber() #include <button.h> // for button stuff // cllbck hndler for button events (invoked on interrupt level) void onbutton( BUTTON b, BUTTONEVENT e ) { sttic int8_t count = 1; sb_7seg_shownumber( count++ ); // show no of button presses if( count > 99 ) count = 1; // reset t 100 sb_button_registerlistener( // register cllbck BUTTON0, BTNPRESSED, // for this button nd events onbutton // invoke this function ); sei(); // enble interrupts (necessry!) while( 1 ) ; // wit forever Ein Zeiger verweist uf eine Vrible im Speicher Möglichkeit des indirekten Zugriffs uf den Wert Grundlge für die Implementierung von cll-by-reference in C Grundlge für die Implementierung von Feldern Wichtiges Element der Mschinennähe von C Häufigste Fehlerursche in C-Progrmmen Die syntktischen Möglichkeiten sind vielfältig (und verwirrend) Typmodifizierer *, Adressopertor &, Verweisopertor * Zeigerrithmetik mit +, -, ++ und -- syntktische Äquivlenz zu Feldern ([] Opertor) Zeiger können uch uf Funktionen verweisen Übergeben von Funktionen n Funktionen Prinzip der Rückruffunktion c dl GSPiC (Teil C, WS 12) 13 Zeiger und Felder 13.8 Erweiterte Zeigertypen 13 21 c dl GSPiC (Teil C, WS 12) 13 Zeiger und Felder 13.9 Zusmmenfssung 13 22 Überblick: Teil C Systemnhe Softwreentwicklung Ws ist ein µ-controller? 12 Progrmmstruktur und Module µ-controller := Prozessor + Speicher + Peripherie Fktisch ein Ein-Chip-Computersystem SoC (System-on--Chip) Häufig verwendbr ohne zusätzliche externe Busteine, wie z. B. Tktgenertoren und Speicher kostengünstiges Systemdesign 13 Zeiger und Felder 14 µc-systemrchitektur 15 Nebenläufigkeit Wesentliches Merkml ist die (reichlich) enthltene Peripherie Timer/Counter (Zeiten/Ereignisse messen und zählen) Ports (digitle Ein-/Ausgbe), A/D-Wndler (nloge Eingbe) PWM-Genertoren (pseudo-nloge Ausgbe) Bus-Systeme: SPI, RS-232, CAN, Ethernet, MLI, I 2 C,...... V_GSPIC_hndout 16 Speicherorgnistion Die Abgrenzungen sind fließend: Prozessor µc SoC AMD64-CPUs hben ebenflls eingebute Timer, Speicher (Cches),... Einige µc erreichen die Geschwindigkeit großer Prozessoren c dl GSPiC (Teil C, WS 12) 14 µc-systemrchitektur 14.1 Überblick 14 1

PROGRAMMING LOGIC Beispiel ATmeg32: Blockschltbild Beispiel ATmeg-Fmilie: CPU-Architektur VCC PA0 - PA7 PC0 - PC7 CPU-Kern Speicher GND AVCC AREF PORTA DRIVERS/BUFFERS PORTA DIGITAL INTERFACE MUX & ADC PROGRAM COUNTER PROGRAM FLASH INSTRUCTION REGISTER INSTRUCTION DECODER CONTROL LINES AVR CPU ADC INTERFACE STACK POINTER SRAM GENERAL PURPOSE REGISTERS X Y Z ALU STATUS REGISTER SPI PORTC DRIVERS/BUFFERS PORTC DIGITAL INTERFACE TWI TIMERS/ OSCILLATOR COUNTERS INTERNAL OSCILLATOR WATCHDOG OSCILLATOR TIMER MCU CTRL. & TIMING INTERNAL INTERRUPT CALIBRATED UNIT OSCILLATOR EEPROM USART XTAL1 XTAL2 Peripherie 0x0046 0x1FFFF min: wit: IRQ-Vektoren Anwendungs- Code Boot-Code Progrmmdressrum (Flsh) 1 128 KiB, 2-Byte-Elemente 16 Recheneinheit 16 Dtenbus Adressbus 8 16 32 Register 64 IO-Register bis zu 160 Ext. IO-Register bis zu 4KiB internes SRAM bis zu knpp 60 KiB externes SRAM 0x0020 0x0060 0x0100 0x1100 0xFFFF Dtendressrum (SRAM) 0 64 KiB, 1-Byte-Elemente Hrvrd-Architektur (getrennter Speicher für Code und Dten) + COMP. - INTERFACE PORTB DIGITAL INTERFACE PORTB DRIVERS/BUFFERS PORTD DIGITAL INTERFACE PORTD DRIVERS/BUFFERS Peripherie-Register sind in den Speicher eingeblendet nsprechbr wie globle Vriblen Zum Vergleich: PC bsiert uf von-neumnn-architektur [ GDI, VI-6] mit gemeinsmem Speicher; I/O-Register verwenden einen speziellen I/O-Adressrum. PB0 - PB7 Wie rbeitet ein Prozessor? PD0 - PD7 c dl GSPiC (Teil C, WS 12) 14 µc-systemrchitektur 14.2 Architektur 14 3 Wie rbeitet ein Prozessor? Zero bit Progrmmspeicher Zero bit Progrmmspeicher PC = Vcc Z SR SR` µc PC PC` R1 R1` Bus min: ldi R1, 48 beq L1 cll f sub R1, 58 L1: f: dd R1, 11 0x0002 0x0004 0x0006 0x0008 0x000A 0x0100 0x0102 Vcc Z SR SR` µc PC PC` R1 R1` Bus min: ldi R1, 48 beq L1 cll f sub R1, 58 L1: f: dd R1, 11 0x0002 0x0004 0x0006 0x0008 0x000A 0x0100 0x0102 w = *PC++ decode(w) Hier m Beispiel eines sehr einfchen Pseudoprozessors Nur zwei Vielzweckregister (R1 und R2) Progrmmzähler (PC) und Sttusregister (SR) (+ Schttenkopien ) Kein Dtenspeicher, kein Stpel Progrmm rbeitet nur uf Registern execute(w) c dl GSPiC (Teil C, WS 12) 14 µc-systemrchitektur 14.2 Architektur 14 4 c dl GSPiC (Teil C, WS 12) 14 µc-systemrchitektur 14.2 Architektur 14 4

Wie rbeitet ein Prozessor? Wie rbeitet ein Prozessor? Zero bit Progrmmspeicher PC = Zero bit Progrmmspeicher PC = Vcc Z SR SR` µc PC PC` R1 R1` Bus min: ldi R1, 48 beq L1 cll f sub R1, 58 L1: f: dd R1, 11 0x0002 0x0004 0x0006 0x0008 0x000A 0x0100 0x0102 w = *PC++ Vcc Z SR SR` µc PC PC` 48 R1 R1` Bus min: ldi R1, 48 beq L1 cll f sub R1, 58 L1: f: dd R1, 11 0x0002 0x0004 0x0006 0x0008 0x000A 0x0100 0x0102 w = *PC++ decode(w) decode(w) execute(w) execute(w) c dl GSPiC (Teil C, WS 12) 14 µc-systemrchitektur 14.2 Architektur 14 4 c dl GSPiC (Teil C, WS 12) 14 µc-systemrchitektur 14.2 Architektur 14 4 Wie rbeitet ein Prozessor? Wie rbeitet ein Prozessor? Zero bit Progrmmspeicher PC = Zero bit Progrmmspeicher PC = Z 0 SR PC Vcc SR` µc PC` 47 R1 R1` Bus min: ldi R1, 48 beq L1 cll f sub R1, 58 L1: f: dd R1, 11 0x0002 0x0004 0x0006 0x0008 0x000A 0x0100 0x0102 w = *PC++ Z 0 SR PC Vcc SR` µc PC` 47 R1 R1` Bus min: ldi R1, 48 beq L1 cll f sub R1, 58 L1: f: dd R1, 11 0x0002 0x0004 0x0006 0x0008 0x000A 0x0100 0x0102 w = *PC++ decode(w) decode(w) w: dec <R> R = 1 if( R == 0) Z = 1 else Z = 0 w: beq <lb> if (Z) PC = lb w: cll <func> PC = func execute(w) w: dec <R> R = 1 if( R == 0) Z = 1 else Z = 0 w: beq <lb> if (Z) PC = lb w: cll <func> PC = func execute(w) c dl GSPiC (Teil C, WS 12) 14 µc-systemrchitektur 14.2 Architektur 14 4 c dl GSPiC (Teil C, WS 12) 14 µc-systemrchitektur 14.2 Architektur 14 4

Wie rbeitet ein Prozessor? Peripheriegeräte Zero bit Z 0 SR PC Vcc SR` µc PC` 58 R1 R1` Bus Progrmmspeicher min: ldi R1, 48 beq L1 cll f sub R1, 58 L1: f: dd R1, 11 0x0002 0x0004 0x0006 0x0008 0x000A 0x0100 0x0102 PC = w = *PC++ decode(w) Peripheriegerät: Hrdwrekomponente, die sich ußerhlb der Zentrleinheit eines Computers befindet Trditionell (PC): Tsttur, Bildschirm,... ( physisch ußerhlb ) Allgemeiner: Hrdwrefunktionen, die nicht direkt im Befehlsstz des Prozessors bgebildet sind ( logisch ußerhlb ) Peripheriebusteine werden über I/O-Register ngesprochen Kontrollregister: Befehle n / Zustnd der Peripherie wird durch Bitmuster kodiert (z. B. DDRD beim ATmeg) w: dec <R> R = 1 if( R == 0) Z = 1 else Z = 0 w: beq <lb> if (Z) PC = lb w: cll <func> PC = func execute(w) w: PC = PC` Dtenregister: Dienen dem eigentlichen Dtenustusch (z. B. PORTD, PIND beim ATmeg) Register sind häufig für entweder nur Lesezugriffe (red-only) oder nur Schreibzugriffe (write-only) zugelssen c dl GSPiC (Teil C, WS 12) 14 µc-systemrchitektur 14.2 Architektur 14 4 c dl GSPiC (Teil C, WS 12) 14 µc-systemrchitektur 14.3 Peripherie 14 5 Peripheriegeräte: Beispiele Peripheriegeräte Register Auswhl von typischen Peripheriegeräten in einem µ-controller Timer/Counter Wtchdog-Timer (A)synchrone serielle Schnittstelle A/D-Wndler PWM-Genertoren Ports Zählregister, die mit konfigurierbrer Frequenz (Timer) oder durch externe Signle (Counter) erhöht werden und bei konfigurierbrem Zählwert einen Interrupt uslösen. Timer, der regelmäßig neu beschrieben werden muss oder sonst einen uslöst ( Totmnnknopf ). Busteine zur seriellen (bitweisen) Übertrgung von Dten mit synchronem (z. B. RS-232) oder synchronem (z. B. I 2 C) Protokoll. Busteine zur momentweisen oder kontinuierlichen Diskisierung von Spnnungswerten (z. B. 0 5V 10-Bit- Zhl). Busteine zur Generierung von pulsweiten-modulierten Signlen (pseudo-nloge Ausgbe). Gruppen von üblicherweise 8 Anschlüssen, die uf GND oder Vcc gesetzt werden können oder deren Zustnd bgefrgt werden knn. 14 12 Es gibt verschiedene Architekturen für den Zugriff uf I/O-Register Memory-mpped: Register sind in den Adressrum eingeblendet; (Die meisten µc) der Zugriff erfolgt über die Speicherbefehle des Prozessors (lod, store) Port-bsiert: (x86-bsierte PCs) Register sind in einem eigenen I/O-Adressrum orgnisiert; der Zugriff erfolgt über spezielle inund out-befehle Die Registerdressen stehen in der Hrdwre-Dokumenttion!""#$%% &'($ )*+,- )*+,. )*+,/ )*+,0 )*+,1 )*+,2 )*+,3 )*+,4 5'6$!"#$%!&#' ()*+, -. ( / 0 1 2 3!"*$%!&*' (4. 5 5 5 5 (466 (467 (48 (43 66!"9$%!&9' (4: (4; (4< (4& (4= (4" (4> (46 (47 66!"2$%!&2'?2)7 -@ABCD2EFGHBC7$?FHIFH$2EAIJCB$)BK@LHBC 3<!6>$%!">' 4?)-9 4?)-9; 4?)-9< 4?)-9& 4?)-9= 4?)-9" 4?)-9> 4?)-96 4?)-97 <;!66$%!"6' 99)9 999; 999< 999& 999= 999" 999> 9996 9997 <;!67$%!"7' 4,09 4,09; 4,09< 4,09& 4,09= 4,09" 4,09> 4,096 4,097 <3 [1, S. 334] c dl GSPiC (Teil C, WS 12) 14 µc-systemrchitektur 14.3 Peripherie 14 6 c dl GSPiC (Teil C, WS 12) 14 µc-systemrchitektur 14.3 Peripherie 14 7

Peripheriegeräte Register (Forts.) Memory-mpped Register ermöglichen einen komfortblen Zugriff Register Speicher Vrible Alle C-Opertoren stehen direkt zur Verfügung (z. B. PORTD++) Syntktisch wird der Zugriff oft durch Mkros erleichtert: Registerzugriff und Nebenläufigkeit Peripheriegeräte rbeiten nebenläufig zur Softwre Wert in einem Hrdwreregister knn sich jederzeit ändern Dies widerspricht einer Annhme des Compilers Vriblenzugriffe erfolgen nur durch die ktuell usgeführte Funktion Vriblen können in Registern zwischengespeichert werden #define PORTD ( * (voltile uint8_t*)( 0x12 {{ Beispiel Adresse: int {{ Adresse: voltile uint8_t* (Cst 7 17 ) {{ Wert: voltile uint8_t (Dereferenzierung 13 4 ) #define PORTD (*(voltile uint8_t*)(0x12)) PORTD = (1<<7); // set D.7 uint8_t *preg = &PORTD; // get pointer to PORTD *preg &= ~(1<<7); // use pointer to cler D.7 ) ) PORTD ist dmit (syntktisch) äquivlent zu einer voltile uint8_t-vriblen, die n Adresse 0x12 liegt // C code #define PIND (*(uint8_t*)(0x10)) void foo(void) { if(!(pind & 0x2) ) { // button0 pressed if(!(pind & 0x4) ) { // button 1 pressed // Resulting ssembly code foo: lds r24, 0x0010 // PIND->r24 sbrc r24, 1 // test bit 1 rjmp L1 // button0 pressed L1: sbrc r24, 2 // test bit 2 rjmp L2 PIND wird nicht erneut us dem Speicher gelden. Der L2: Compiler nimmt n, dss der Wert in r24 ktuell ist. c dl GSPiC (Teil C, WS 12) 14 µc-systemrchitektur 14.3 Peripherie 14 8 Der voltile-typmodifizierer Lösung: Vrible voltile ( flüchtig, unbeständig ) deklrieren Compiler hält Vrible nur so kurz wie möglich im Register Wert wird unmittelbr vor Verwendung gelesen Wert wird unmittelbr nch Veränderung zurückgeschrieben c dl GSPiC (Teil C, WS 12) 14 µc-systemrchitektur 14.4 Exkurs: voltile 14 9 Der voltile-typmodifizierer (Forts.) Die voltile-semntik verhindert viele Code-Optimierungen (insbesondere ds Entfernen von scheinbr unnützem Code) Knn usgenutzt werden, um ktives Wrten zu implementieren: // C code #define PIND \ (*(voltile uint8_t*)(0x10)) void foo(void) { if(!(pind & 0x2) ) { // button0 pressed if(!(pind & 0x4) ) { // button 1 pressed // Resulting ssembly code foo: lds r24, 0x0010 // PIND->r24 sbrc r24, 1 // test bit 1 rjmp L1 // button0 pressed L1: lds r24, 0x0010 // PIND->r24 sbrc r24, 2 // test bit 2 rjmp L2 L2: PIND ist voltile und wird deshlb vor dem Test erneut us dem Speicher gelden. // C code void wit( void ){ for( uint16_t i = 0; i<0xffff;) i++; voltile! // Resulting ssembly code wit: // compiler hs optimized // "nonsensicl" loop wy Achtung: voltile $$$ Die Verwendung von voltile verurscht erhebliche Kosten Regel: Werte können nicht mehr in Registern gehlten werden Viele Code-Optimierungen können nicht durchgeführt werden voltile wird nur in begründeten Fällen verwendet c dl GSPiC (Teil C, WS 12) 14 µc-systemrchitektur 14.4 Exkurs: voltile 14 10 c dl GSPiC (Teil C, WS 12) 14 µc-systemrchitektur 14.4 Exkurs: voltile 14 11

Peripheriegeräte: Ports Beispiel ATmeg32: Port/Pin-Belegung Port := Gruppe von (üblicherweise 8) digitlen Ein-/Ausgängen PDIP Digitler Ausgng: Digitler Eingng: Externer Interrupt: (bei Pegelwechsel) Bitwert Spnnungspegel n µc-pin Spnnungspegel n µc-pin Bitwert Spnnungspegel n µc-pin Bitwert Prozessor führt Interruptprogrmm us Die Funktion ist üblicherweise pro Pin konfigurierbr Eingng Ausgng Externer Interrupt Alterntive Funktion (nur bei bestimmten Eingängen) (Pin wird von nderem Gerät verwendet)!"#$%&'())*+'!&,())*+,!-.&/%0-.'())*+/!1#'%0-.,())*+2!33())*+4!513-())*+6!5-31())*+7!3#$())*+8 9:3:& ;## <.= "&0>/ "&0>,!9"=())*='!&"=())*=,!-.&'())*=/!-.&,())*=2!1#,+())*=4!1#,0())*=6!-#*,())*=7 *0'))!0=#'( *0,))!0=#,( *0/))!0=#/( *02))!0=#2( *04))!0=#4( *06))!0=#6( *07))!0=#7( *08))!0=#8( 09:? <.= 0;## *#8))!&13#/( *#7))!&13#,( *#6))!&=-( *#4))!&=1( *#2))!&53( *#/))!&#$( *#,))!3=0( *#'))!3#>( *=8))!1#/( Aus Kostengründen ist nhezu jeder Pin doppelt belegt, die Konfigurtion der gewünschten Funktion erfolgt durch die Softwre. Beim SPiCbord werden z. B. Pins 39 40 ls ADCs konfiguriert, um Poti und Photosensor nzuschließen. PORTA steht dher nicht zur Verfügung. c dl GSPiC (Teil C, WS 12) 14 µc-systemrchitektur 14.5 Ports 14 12 Beispiel ATmeg32: Port-Register Pro Port x sind drei Register definiert (Beispiel für x = D) DDRx Dt Direction Register: Legt für jeden Pin i fest, ob er ls Eingng (Bit i=0) oder ls Ausgng (Bit i=1) verwendet wird. 7 6 5 4 3 2 1 0 DDD7 DDD6 DDD5 DDD4 DDD3 DDD2 DDD1 DDD0 R/W R/W R/W R/W R/W R/W R/W R/W c dl GSPiC (Teil C, WS 12) 14 µc-systemrchitektur 14.5 Ports 14 13 Strukturen: Motivtion Jeder Port wird durch drei globle Vriblen verwltet Es wäre besser diese zusmmen zu fssen problembezogene Abstrktionen 4 1 Trennung der Belnge 12 4 Dies geht in C mit Verbundtypen (Strukturen) PORTx Dt Register: Ist Pin i ls Ausgng konfiguriert, so legt Bit i den Pegel fest (0=GND sink, 1=Vcc source). Ist Pin i ls Eingng konfiguriert, so ktiviert Bit i den internen Pull-Up-Widerstnd (1=ktiv). 7 6 5 4 3 2 1 0 PORTD7 PORTD6 PORTD5 PORTD4 PORTD3 PORTD2 PORTD1 PORTD0 R/W R/W R/W R/W R/W R/W R/W R/W PINx Input Register: Bit i repräsentiert den Pegel n Pin i (1=high, 0=low), unbhängig von der Konfigurtion ls Ein-/Ausgng. 7 6 5 4 3 2 1 0 PIND7 PIND6 PIND5 PIND4 PIND3 PIND2 PIND1 PIND0 R R R R R R R R Verwendungsbeispiele: 3 5 und 3 8 [1, S. 66] // Structure declrtion struct Student { chr lstnme[64]; chr firstnme[64]; long mtnum; int pssed; ; // Vrible definition struct Student stud; Ein Strukturtyp fsst eine Menge von Dten zu einem gemeinsmen Typ zusmmen. Die Dtenelemente werden hintereinnder im Speicher bgelegt. stud.lstnme.firstnme.mtnum.pssed???? 0 64 128 132 c dl GSPiC (Teil C, WS 12) 14 µc-systemrchitektur 14.5 Ports 14 14 c dl GSPiC (Teil C, WS 12) 14 µc-systemrchitektur 14.6 Exkurs: Verbundtypen (struct, union) 14 15

Strukturen: Vriblendefinition und -initilisierung Anlog zu einem Arry knn eine Strukturvrible 13 8 bei Definition elementweise initilisiert werden struct Student { chr lstnme[64]; chr firstnme[64]; long mtnum; int pssed; ; struct Student stud = { "Meier", "Hns", 4711, 0 ; Die Initilisierer werden nur über ihre Reihenfolge, nicht über ihren Bezeichner zugewiesen. Potentielle Fehlerquelle bei Änderungen! Anlog zur Definition von enum-typen knn mn mit 6 8 typedef die Verwendung vereinfchen Strukturen: Elementzugriff porta.pin.ddr.port PINA 0 DDRA 0 PORTA Auf Strukturelemente wird mit dem.-opertor zugegriffen [ Jv] port_t porta = { &PINA, &DDRA, &PORTA ; *porta.port = 0; // cler ll pins *porta.ddr = 0xff; // set ll to input Bechte:. ht eine höhere Priorität ls * typedef struct { voltile uint8_t *pin; voltile uint8_t *ddr; voltile uint8_t *port; port_t; port_t porta = { &PINA, &DDRA, &PORTA ; port_t portd = { &PIND, &DDRD, &PORTD ; c dl GSPiC (Teil C, WS 12) 14 µc-systemrchitektur 14.6 Exkurs: Verbundtypen (struct, union) 14 16 c dl GSPiC (Teil C, WS 12) 14 µc-systemrchitektur 14.6 Exkurs: Verbundtypen (struct, union) 14 17 Strukturen: Elementzugriff Strukturen ls Funktionsprmeter pport porta.pin.ddr.port PINA 0 DDRA 0 PORTA Im Gegenstz zu Arrys werden Strukturen by-vlue übergeben void initport( port_t p ){ *p.port = 0; // cler ll pins *p.ddr = 0xff; // set ll to output Bei einem Zeiger uf eine Struktur würde Klmmerung benötigt port_t * pport = &porta; // p --> porta *(*pport).port = 0; // cler ll pins *(*pport).ddr = 0xff; // set ll to output Mit dem ->-Opertor lässt sich dies vereinfchen s->m (*s).m port_t * pport = &porta; // p --> porta *pport->port = 0; // cler ll pins *pport->ddr = 0xff; // set ll to output -> ht ebenflls eine höhere Priorität ls * p.port = &PORTD; // no effect, p is locl vrible void min(){ initport( porta ); Bei größeren Strukturen wird ds sehr ineffizient Z. B. Student ( 14 15 ): Jedes ml 134 Byte llozieren und kopieren Besser mn übergibt einen Zeiger uf eine konstnte Struktur void initport( const port_t *p ){ *p->port = 0; // cler ll pins *p->ddr = 0xff; // set ll to output // p->port = &PORTD; compile-time error, *p is const! void min(){ initport( &porta ); c dl GSPiC (Teil C, WS 12) 14 µc-systemrchitektur 14.6 Exkurs: Verbundtypen (struct, union) 14 18 c dl GSPiC (Teil C, WS 12) 14 µc-systemrchitektur 14.6 Exkurs: Verbundtypen (struct, union) 14 19

Bit-Strukturen: Bitfelder Unions Strukturelemente können uf Bit-Grnulrität festgelegt werden Der Compiler fsst Bitfelder zu pssenden Gnzzhltypen zusmmen Nützlich, um uf einzelne Bit-Bereiche eines Registers zuzugreifen Beispiel MCUCR MCU Control Register: Steuert Power-Mngement-Funktionen und Auslöser für externe Interrupt-Quellen INT0 und INT1. [1, S. 36+69] 7 6 5 4 3 2 1 0 SE SM2 SM1 SM0 ISC11 ISC10 ISC01 ISC00 R/W R/W R/W R/W R/W R/W R/W R/W typedef struct { uint8_t ISC0 : 2; // bit 0-1: interrupt sense control INT0 uint8_t ISC1 : 2; // bit 2-3: interrupt sense control INT1 uint8_t SM : 3; // bit 4-6: sleep mode to enter on sleep uint8_t SE : 1; // bit 7 : sleep enble MCUCR_t; In einer Struktur liegen die Elemente hintereinnder 14 15 im Speicher, in einer Union hingegen übereinnder Wert im Speicher lässt sich verschieden (Typ)-interpieren Nützlich für bitweise Typ-Csts Beispiel void min(){ union { uint16_t uint8_t u; u.vl = 0x4711; vl; bytes[2]; // show high-byte sb_7seg_showhexnumber( u.bytes[1] ); // show low-byte sb_7seg_showhexnumber( u.bytes[0] ); u.vl.bytes 0x4711 0x11 0x47 c dl GSPiC (Teil C, WS 12) 14 µc-systemrchitektur 14.6 Exkurs: Verbundtypen (struct, union) 14 20 c dl GSPiC (Teil C, WS 12) 14 µc-systemrchitektur 14.6 Exkurs: Verbundtypen (struct, union) 14 21 Unions und Bit-Strukturen: Anwendungsbeispiel Überblick: Teil C Systemnhe Softwreentwicklung Unions werden oft mit Bit-Feldern kombiniert, um ein Register whlweise im Gnzen oder bitweise nsprechen zu können typedef union { voltile uint8_t reg; // complete register voltile struct { uint8_t ISC0 : 2; // components uint8_t ISC1 : 2; uint8_t SM : 3; uint8_t SE : 1; ; MCUCR_t; void foo( void ) { MCUCR_t *mcucr = (MCUCR_t *) (0x35); uint8_t oldvl = mcucr->reg; // sve register mcucr->isc0 = 2; // use register mcucr->se = 1; // mcucr->reg = oldvl; // restore register V_GSPIC_hndout 12 Progrmmstruktur und Module 13 Zeiger und Felder 14 µc-systemrchitektur 15 Nebenläufigkeit 16 Speicherorgnistion c dl GSPiC (Teil C, WS 12) 14 µc-systemrchitektur 14.6 Exkurs: Verbundtypen (struct, union) 14 22

Ereignisbehndlung Interrupt Funktionsufruf von ußen Bei einem Peripheriegerät tritt ein Ereignis ( ) uf 14 5 Signl n einem Port-Pin wechselt von low uf high Ein Timer ist bgelufen Ein A/D-Wndler ht einen neuen Wert vorliegen... Wie bekommt ds Progrmm ds (nebenläufige) Ereignis mit? min() cll: explizite Aktivierung durch Funktionsufruf foo() foo() interrupt: implizite Aktivierung durch Hrdwresignl Zwei lterntive Verfhren Polling: Interrupt: Ds Progrmm überprüft den Zustnd regelmäßig und ruft ggf. eine Berbeitungsfunktion uf. Gerät meldet sich beim Prozessor, der drufhin in eine Berbeitungsfunktion verzweigt. isr() isr: interrupt service routine t 1 t 2 t 3 t 4 t 5 (z. B. Timer bgelufen) i c dl GSPiC (Teil C, WS 12) 15 Nebenläufigkeit 15.1 Interrupts: Einführung 15 1 c dl GSPiC (Teil C, WS 12) 15 Nebenläufigkeit 15.1 Interrupts: Einführung 15 2 Polling vs. Interrupts Vor- und Nchteile Interruptsperren Polling ( Periodisches / zeitgesteuertes System ) Ereignisberbeitung erfolgt synchron zum Progrmmbluf Ereigniserkennung über ds Progrmm verstreut (Trennung der Belnge) Hochfrequentes Pollen hohe Prozessorlst hoher Energieverbruch + Implizite Dtenkonsistenz durch festen, sequentiellen Progrmmbluf + Progrmmverhlten gut vorhersgbr Interrupts ( Ereignisgesteuertes System ) Ereignisberbeitung erfolgt synchron zum Progrmmbluf + Ereignisberbeitung knn im Progrmmtext gut sepriert werden + Prozessor wird nur bensprucht, wenn Ereignis ttsächlich eintritt Höhere Komplexität durch Nebenläufigkeit Synchronistion erforderlich Progrmmverhlten schwer vorhersgbr Beide Verfhren bieten spezifische Vor- und Nchteile Auswhl nhnd des konken Anwendungsszenrios Zustellung von Interrupts knn softwreseitig gesperrt werden Wird benötigt zur Synchronistion mit ISRs Einzelne ISR: Bit in gerätespezifischem Steuerregister Alle ISRs: Bit (IE, Interrupt Enble) im Sttusregister der CPU Auflufende IRQs werden (üblicherweise) gepuffert Mximl einer pro Quelle! Bei längeren Sperrzeiten können IRQs verloren gehen! IRQ Interrupt ReQuest Ds IE-Bit wird beeinflusst durch: Prozessor-Befehle: cli: IE 0 (cler interrupt, IRQs gesperrt) sei: IE 1 (set interrupt, IRQs erlubt) Nch einem : IE=0 IRQs sind zu Beginn des Huptprogrmms gesperrt Bei Beten einer ISR: IE=0 IRQs sind während der Interruptberbeitung gesperrt c dl GSPiC (Teil C, WS 12) 15 Nebenläufigkeit 15.1 Interrupts: Einführung 15 3 c dl GSPiC (Teil C, WS 12) 15 Nebenläufigkeit 15.2 Interrupts: Steuerung 15 4

Interruptsperren: Beispiel Abluf eines Interrupts Überblick IE=1 min() isr() IE=0 sei() cli() sei() Verzögerung t 1 t 2 t 3 t 4 t 5 t 6 (z. B. Timer bgelufen) t 1 Zu Beginn von min() sind IRQs gesperrt (IE=0) t 2, t 3 Mit sei() / cli() werden IRQs freigegeben (IE=1) / erneut gesperrt t 4 ber IE=0 Berbeitung ist unterdrückt, IRQ wird gepuffert t 5 min() gibt IRQs frei (IE=1) gepufferter IRQ schlägt durch t 5 t 6 Während der ISR-Berbeitung sind die IRQs gesperrt (IE=0) Unterbrochenes min() wird fortgesetzt t 6 i ➊ Gerät signlisiert Interrupt Anwendungsprogrmm wird unmittelbr (vor dem nächsten Mschinenbefehl mit IE=1) unterbrochen ➋ Die Zustellung weiterer Interrupts wird gesperrt (IE=0) Zwischenzeitlich uflufende Interrupts werden gepuffert (mximl einer pro Quelle!) ➌ Registerinhlte werden gesichert (z. B. im Dtenspeicher) PC und Sttusregister utomtisch von der Hrdwre Vielzweckregister müssen oft mnuell gesichert werden ➍ Aufzurufende ISR (Interrupt-Hndler) wird ermittelt ➎ ISR wird usgeführt ➏ ISR terminiert mit einem urn from interrupt -Befehl Registerinhlte werden resturiert Zustellung von Interrupts wird freigegeben (IE=1) Ds Anwendungsprogrmm wird fortgesetzt ➀ ➁ ➂➃ Interrupt-Hndler ➅ ➄ c dl GSPiC (Teil C, WS 12) 15 Nebenläufigkeit 15.2 Interrupts: Steuerung 15 5 Abluf eines Interrupts Detils c dl GSPiC (Teil C, WS 12) 15 Nebenläufigkeit 15.2 Interrupts: Steuerung 15 6 Abluf eines Interrupts Detils Zero bit IRQ pending bit IRQs enbled bit IP Z IE 0 0 1 SR PC Vcc SR` INT µc PC` R1 Bus R1` Progrmmspeicher min: ldi R1, 48 beq L1 cll f sub R1, 58 L1: f: dd R1, 11 isr: ldi R1,1 sts, R1 i 0x0002 0x0004 0x0006 0x0008 0x000A 0x0100 0x0102 0x0200 0x0202 0x0204 0x0206 PC = SR.IE && SR.IP flse w = *PC++ decode(w) true SR.IP = 0 SR` = SR SR.IE = 0 PC = isr R1` = R1 Zero bit IRQ pending bit IRQs enbled bit IP Z IE 1 0 1 SR PC Vcc SR` INT! µc PC` R1 Bus R1` Progrmmspeicher min: ldi R1, 48 beq L1 cll f sub R1, 58 L1: f: dd R1, 11 isr: ldi R1,1 sts, R1 i 0x0002 0x0004 0x0006 0x0008 0x000A 0x0100 0x0102 0x0200 0x0202 0x0204 0x0206 PC = SR.IE && SR.IP flse w = *PC++ decode(w) true SR.IP = 0 SR` = SR SR.IE = 0 PC = isr R1` = R1 Hier ls Erweiterung unseres einfchen Pseudoprozessors 14 4 Nur eine Interruptquelle Sämtliche Register werden von der Hrdwre getet w: cll <func> PC = func execute(w) w: PC = PC` w: i SR = SR` PC = PC` R1 = R1`! Gerät signlisiert Interrupt (ktueller Befehl wird noch fertiggestellt) w: cll <func> PC = func execute(w) w: PC = PC` w: i SR = SR` PC = PC` R1 = R1` c dl GSPiC (Teil C, WS 12) 15 Nebenläufigkeit 15.2 Interrupts: Steuerung 15 7 c dl GSPiC (Teil C, WS 12) 15 Nebenläufigkeit 15.2 Interrupts: Steuerung 15 7

Abluf eines Interrupts Detils Abluf eines Interrupts Detils Zero bit IRQ pending bit IRQs enbled bit IP Z IE 1 0 1 SR PC Vcc SR` INT µc PC` R1 Bus R1` Progrmmspeicher min: ldi R1, 48 beq L1 cll f sub R1, 58 L1: f: dd R1, 11 isr: ldi R1,1 sts, R1 i 0x0002 0x0004 0x0006 0x0008 0x000A 0x0100 0x0102 0x0200 0x0202 0x0204 0x0206 PC = SR.IE && SR.IP flse w = *PC++ decode(w) true SR.IP = 0 SR` = SR SR.IE = 0 PC = isr R1` = R1 Zero bit IRQ pending bit IRQs enbled bit IP Z IE 0 0 0! " Vcc INT SR PC SR` µc PC` R1 Bus R1` Progrmmspeicher min: ldi R1, 48 beq L1 cll f sub R1, 58 L1: f: dd R1, 11 isr: ldi R1,1 sts, R1 i 0x0002 0x0004 0x0006 0x0008 0x000A 0x0100 0x0102 0x0200 0x0202 0x0204 0x0206 PC = SR.IE && SR.IP flse w = *PC++ decode(w) true SR.IP = 0 SR` = SR SR.IE = 0 PC = isr R1` = R1 (Vor dem nächsten instruction fetch wird der Interruptsttus überprüft) w: cll <func> PC = func execute(w) w: PC = PC` w: i SR = SR` PC = PC` R1 = R1`! Die Zustellung weiterer Interrupts wird verzögert " Registerinhlte werden gesichert w: cll <func> PC = func execute(w) w: PC = PC` w: i SR = SR` PC = PC` R1 = R1` c dl GSPiC (Teil C, WS 12) 15 Nebenläufigkeit 15.2 Interrupts: Steuerung 15 7 Abluf eines Interrupts Detils c dl GSPiC (Teil C, WS 12) 15 Nebenläufigkeit 15.2 Interrupts: Steuerung 15 7 Abluf eines Interrupts Detils Zero bit IRQ pending bit IRQs enbled bit IP Z IE 0 0 0 SR PC! Vcc SR` INT µc PC` R1 Bus R1` Progrmmspeicher min: ldi R1, 48 beq L1 cll f sub R1, 58 L1: f: dd R1, 11 isr: ldi R1,1 sts, R1 i 0x0002 0x0004 0x0006 0x0008 0x000A 0x0100 0x0102 0x0200 0x0202 0x0204 0x0206 PC = SR.IE && SR.IP flse w = *PC++ decode(w) true SR.IP = 0 SR` = SR SR.IE = 0 PC = isr R1` = R1 Zero bit IRQ pending bit IRQs enbled bit IP Z IE 0 1 0 SR PC Vcc SR` INT µc PC` R1 0 Bus R1` Progrmmspeicher min: ldi R1, 48 beq L1 cll f sub R1, 58 L1: f: dd R1, 11 isr: ldi R1,1 sts, R1 i 0x0002 0x0004 0x0006 0x0008 0x000A 0x0100 0x0102 0x0200 0x0202 0x0204 0x0206 PC = SR.IE && SR.IP flse w = *PC++ decode(w) true SR.IP = 0 SR` = SR SR.IE = 0 PC = isr R1` = R1! Aufzurufende ISR wird ermittelt w: cll <func> PC = func execute(w) w: PC = PC` w: i SR = SR` PC = PC` R1 = R1`! ISR wird usgeführt w: cll <func> PC = func execute(w) w: PC = PC` w: i SR = SR` PC = PC` R1 = R1` c dl GSPiC (Teil C, WS 12) 15 Nebenläufigkeit 15.2 Interrupts: Steuerung 15 7 c dl GSPiC (Teil C, WS 12) 15 Nebenläufigkeit 15.2 Interrupts: Steuerung 15 7

Abluf eines Interrupts Detils Pegel- und Flnken-gesteuerte Interrupts IRQ pending bit! Vcc! INT IP Z IE 0 0 1 SR SR` Zero bit µc IRQs enbled bit PC PC` R1 R1`! Bus! Progrmmspeicher min: ldi R1, 48 beq L1 cll f sub R1, 58 L1: f: dd R1, 11 isr: ldi R1,1 sts, R1 i 0x0002 0x0004 0x0006 0x0008 0x000A 0x0100 0x0102 0x0200 0x0202 0x0204 0x0206 PC = SR.IE && SR.IP flse w = *PC++ decode(w) true SR.IP = 0 SR` = SR SR.IE = 0 PC = isr R1` = R1 Beispiel: Signl eines idelisierten Tsters (ctive low) Tster drücken Flnkengesteuerter Interrupt loslssen Interrupt wird durch den Pegelwechsel (Flnke) usgelöst Häufig ist konfigurierbr, welche Flnke (steigend/fllend/beide) einen Interrupt uslösen soll V cc GND! ISR terminiert mit i-befehl Registerinhlte werden resturiert Zustellung von Interrupts wird rektiviert Ds Anwendungsprogrmm wird fortgesetzt w: cll <func> PC = func execute(w) w: PC = PC` w: i SR = SR` PC = PC` R1 = R1` Pegelgesteuerter Interrupt Interrupt wird immer wieder usgelöst, so lnge der Pegel nliegt c dl GSPiC (Teil C, WS 12) 15 Nebenläufigkeit 15.2 Interrupts: Steuerung 15 7 c dl GSPiC (Teil C, WS 12) 15 Nebenläufigkeit 15.2 Interrupts: Steuerung 15 8 Interruptsteuerung beim AVR ATmeg Externe Interrupts: Register IRQ-Quellen beim ATmeg32 (IRQ Interrupt ReQuest) 21 IRQ-Quellen [1, S. 45] einzeln de-/ktivierbr IRQ Sprung n Vektor-Adresse Verschltung SPiCbord ( 14 14 2 4 ) INT0 PD2 Button0 (hrdwreseitig entprellt) INT1 PD3 Button1 Tble 11-1. Vector No. Reset nd Interrupt Vectors Progrm Address (2) Source Interrupt Definition 1 $000 (1) Externl Pin, Power-on Reset, Brown-out Reset, Wtchdog Reset, nd JTAG AVR Reset 2 $002 INT0 Externl Interrupt Request 0 3 $004 INT1 Externl Interrupt Request 1 4 $006 INT2 Externl Interrupt Request 2 5 $008 TIMER2 COMP Timer/Counter2 Compre Mtch 6 $00A TIMER2 OVF Timer/Counter2 Overflow 7 $00C TIMER1 CAPT Timer/Counter1 Cpture Event 8 $00E TIMER1 COMPA Timer/Counter1 Compre Mtch A 9 $010 TIMER1 COMPB Timer/Counter1 Compre Mtch B 10 $012 TIMER1 OVF Timer/Counter1 Overflow 11 $014 TIMER0 COMP Timer/Counter0 Compre Mtch 12 $016 TIMER0 OVF Timer/Counter0 Overflow 13 $018 SPI, STC Seril Trnsfer Complete 14 $01A USART, RXC USART, Rx Complete Steuerregister für INT0 und INT1 GICR Generl Interrupt Control Register: Legt fest, ob die Quellen INTi IRQs uslösen (Bit INTi=1) oder dektiviert sind (Bit INTi=0) [1, S. 71] 7 6 5 4 3 2 1 0 INT1 INT0 INT2 IVSEL IVCE R/W R/W R/W R R R R/W R/W MCUCR MCU Control Register: Legt für externe Interrupts INT0 und INT1 fest, wodurch ein IRQ usgelöst wird (Flnken-/Pegelsteuerung) [1, S. 69] 7 6 5 4 3 2 1 0 SE SM2 SM1 SM0 ISC11 ISC10 ISC01 ISC00 R/W R/W R/W R/W R/W R/W R/W R/W Jeweils zwei Interrupt-Sense-Control-Bits (ISCi0 und ISCi1) steuern dbei die Auslöser (Tbelle für INT1, für INT0 gilt entsprechendes): ISC11 ISC10 Description 0 0 The low level of INT1 genertes n interrupt request. 15 $01C USART, UDRE USART Dt Register Empty 16 $01E USART, TXC USART, Tx Complete 17 $020 ADC ADC Conversion Complete 18 $022 EE_RDY EEPROM Redy 19 $024 ANA_COMP Anlog Comprtor 20 $026 TWI Two-wire Seril Interfce 0 1 Any logicl chnge on INT1 genertes n interrupt request. 1 0 The flling edge of INT1 genertes n interrupt request. 1 1 The rising edge of INT1 genertes n interrupt request. 21 $028 SPM_RDY Store Progrm Memory Redy c dl GSPiC (Teil C, WS 12) 15 Nebenläufigkeit 15.3 Interrupts: Beispiel ATmeg 15 9 c dl GSPiC (Teil C, WS 12) 15 Nebenläufigkeit 15.3 Interrupts: Beispiel ATmeg 15 10

Externe Interrupts: Verwendung Externe Interrupts: Verwendung (Forts.) Schritt 1: Instlltion der Interrupt-Service-Routine ISR in Hochsprche Registerinhlte sichern und wiederherstellen Unterstützung durch die vrlibc: Mkro ISR( SOURCE_vect ) (Modul vr/interrupt.h) Schritt 2: Konfigurieren der Interrupt-Steuerung Steuerregister dem Wunsch entsprechend initilisieren Unterstützung durch die vrlibc: Mkros für Bit-Indizes (Modul vr/interrupt.h und vr/io.h) #include <vr/interrupt.h> #include <vr/io.h> ISR( INT1_vect ) { // invoked for every INT1 IRQ sttic uint8_t counter = 0; sb_7seg_shownumber( counter++ ); if( counter == 100 ) counter = 0; // setup DDRD &= ~(1<<PD3); // PD3: input with pull-up PORTD = (1<<PD3); MCUCR &= ~(1<<ISC10 1<<ISC11); // INT1: IRQ on level=low GICR = (1<<INT1); // INT1: enble sei(); // globl IRQ enble Schritt 3: Interrupts globl zulssen Nch Abschluss der Geräteinitilisierung Unterstützung durch die vrlibc: Befehl sei() (Modul vr/interrupt.h) c dl GSPiC (Teil C, WS 12) 15 Nebenläufigkeit 15.3 Interrupts: Beispiel ATmeg 15 11 c dl GSPiC (Teil C, WS 12) 15 Nebenläufigkeit 15.3 Interrupts: Beispiel ATmeg 15 12 Externe Interrupts: Verwendung (Forts.) Nebenläufigkeit Schritt 4: Wenn nichts zu tun, den Stromsprmodus beten Die sleep-instruktion hält die CPU n, bis ein IRQ eintrifft In diesem Zustnd wird nur sehr wenig Strom verbrucht Unterstützung durch die vrlibc (Modul vr/sleep.h): sleep_enble() / sleep_disble(): Sleep-Modus erluben / verbieten sleep_cpu(): Sleep-Modus beten #include <vr/sleep.h> sei(); while(1) { sleep_enble(); sleep_cpu(); sleep_disble(); // globl IRQ enble // wit for IRQ Atmel empfiehlt die Verwendung von sleep_enble() und sleep_disble() in dieser Form, um ds Risiko eines versehentliches Beten des Sleep-Zustnds (z. B. durch Progrmmierfehler oder Bit-Kipper in der Hrdwre) zu minimieren. Definition: Nebenläufigkeit Zwei Progrmmusführungen A und B sind nebenläufig (A B), wenn für einzelne Instruktionen us A und b us B nicht feststeht, ob oder b ttsächlich zuerst usgeführt wird (, b oder b, ). Nebenläufigkeit tritt uf durch Interrupts IRQs können ein Progrmm n beliebiger Stelle unterbrechen Echt-prllele Abläufe (durch die Hrdwre) ndere CPU / Peripherie greift jederzeit uf den Speicher zu Qusi-prllele Abläufe (z. B. Fäden in einem Betriebssystem) Betriebssystem knn jederzeit den Prozessor entziehen Problem: Nebenläufige Zugriffe uf gemeinsmen Zustnd c dl GSPiC (Teil C, WS 12) 15 Nebenläufigkeit 15.3 Interrupts: Beispiel ATmeg 15 13 c dl GSPiC (Teil C, WS 12) 15 Nebenläufigkeit 15.4 Nebenläufigkeit und Wettlufsitutionen 15 14

Nebenläufigkeitsprobleme Nebenläufigkeitsprobleme (Forts.) Szenrio Eine Lichtschrnke m Prkhuseingng soll Fhrzeuge zählen Alle 60 Sekunden wird der Wert n den Sicherheitsdienst übermittelt sttic voltile uint16_t crs; while(1) { witsec( 60 ); send( crs ); crs = 0; // photo sensor is connected // to INT2 ISR(INT2_vect){ crs++; Wo ist hier ds Problem? Sowohl min() ls uch ISR lesen und schreiben crs Potentielle Lost-Updte -Anomlie Größe der Vrible crs übersteigt die Registerbreite Potentielle Red-Write -Anomlie Wo sind hier die Probleme? Lost-Updte: Sowohl min() ls uch ISR lesen und schreiben crs Red-Write: Größe der Vrible crs übersteigt die Registerbreite Wird oft erst uf der Assemblerebene deutlich send( crs ); crs = 0; min: lds r24,crs lds r25,crs+1 rcll send sts crs+1, zero_reg sts crs, zero_reg // photosensor is connected // to INT2 ISR(INT2_vect){ crs++; INT2_vect: ; sve regs lds r24,crs ; lod crs.lo lds r25,crs+1 ; lod crs.hi diw r24,1 ; dd (16 bit) sts crs+1,r25 ; store crs.hi sts crs,r24 ; store crs.lo ; restore regs c dl GSPiC (Teil C, WS 12) 15 Nebenläufigkeit 15.4 Nebenläufigkeit und Wettlufsitutionen 15 15 c dl GSPiC (Teil C, WS 12) 15 Nebenläufigkeit 15.4 Nebenläufigkeit und Wettlufsitutionen 15 16 Nebenläufigkeitsprobleme: Lost-Updte -Anomlie Nebenläufigkeitsprobleme: Red-Write -Anomlie min: lds r24,crs lds r25,crs+1 rcll send sts crs+1, zero_reg sts crs, zero_reg INT2_vect: ; sve regs lds r24,crs lds r25,crs+1 diw r24,1 sts crs+1,r25 sts crs,r24 ; restore regs min: lds r24,crs lds r25,crs+1 rcll send sts crs+1, zero_reg sts crs, zero_reg INT2_vect: ; sve regs lds r24,crs lds r25,crs+1 diw r24,1 sts crs+1,r25 sts crs,r24 ; restore regs Sei crs=5 und n dieser Stelle tritt der IRQ ( ) uf min ht den Wert von crs (5) bereits in Register gelesen (Register lokle Vrible) INT2_vect wird usgeführt Register werden getet crs wird inkrementiert crs=6 Register werden wiederhergestellt min übergibt den verlteten Wert von crs (5) n send min nullt crs 1 Auto ist verloren gegngen Sei crs=255 und n dieser Stelle tritt der IRQ ( ) uf min ht bereits crs=255 Autos mit send gemeldet min ht bereits ds High-Byte von crs genullt crs=255, crs.lo=255, crs.hi=0 INT2_vect wird usgeführt crs wird gelesen und inkrementiert, Überluf ins High-Byte crs=256, crs.lo=0, crs.hi=1 min nullt ds Low-Byte von crs crs=256, crs.lo=0, crs.hi=1 Beim nächsten send werden 255 Autos zu viel gemeldet c dl GSPiC (Teil C, WS 12) 15 Nebenläufigkeit 15.4 Nebenläufigkeit und Wettlufsitutionen 15 17 c dl GSPiC (Teil C, WS 12) 15 Nebenläufigkeit 15.4 Nebenläufigkeit und Wettlufsitutionen 15 18

Interruptsperren: Dtenflussnomlien verhindern Nebenläufigkeitsprobleme (Forts.) while(1) { witsec( 60 ); cli(); send( crs ); crs = 0; sei(); kritisches Gebiet Wo genu ist ds kritische Gebiet? Lesen von crs und Nullen von crs müssen tomr usgeführt werden Dies knn hier mit Interruptsperren erreicht werden ISR unterbricht min, ber nie umgekehrt symmetrische Synchronistion Achtung: Interruptsperren sollten so kurz wie möglich sein Wie lnge brucht die Funktion send hier? Knn mn send us dem kritischen Gebiet herusziehen? Szenrio, Teil 2 (Funktion witsec()) Eine Lichtschrnke m Prkhuseingng soll Fhrzeuge zählen Alle 60 Sekunden wird der Wert n den Sicherheitsdienst übermittelt void witsec( uint8_t sec ) { // setup timer sleep_enble(); event = 0; while(!event ) { // wit for event sleep_cpu(); // until next irq sleep_disble(); Wo ist hier ds Problem? Test, ob nichts zu tun ist, gefolgt von Schlfen, bis etws zu tun ist Potentielle Lost-Wkeup -Anomlie sttic voltile int8_t event; // TIMER1 ISR // triggers when // witsec() expires ISR(TIMER1_COMPA_vect) { event = 1; c dl GSPiC (Teil C, WS 12) 15 Nebenläufigkeit 15.4 Nebenläufigkeit und Wettlufsitutionen 15 19 c dl GSPiC (Teil C, WS 12) 15 Nebenläufigkeit 15.4 Nebenläufigkeit und Wettlufsitutionen 15 20 Nebenläufigkeitsprobleme: Lost-Wkeup -Anomlie Lost-Wkeup: Dornröschenschlf verhindern void witsec( uint8_t sec ) { // setup timer sleep_enble(); event = 0; while(!event ) { sleep_cpu(); sleep_disble(); sttic voltile int8_t event; // TIMER1 ISR // triggers when // witsec() expires ISR(TIMER1_COMPA_vect) { event = 1; Angenommen, n dieser Stelle tritt der Timer-IRQ ( ) uf witsec ht bereits festgestellt, dss event nicht gesetzt ist ISR wird usgeführt event wird gesetzt Obwohl event gesetzt ist, wird der Schlfzustnd beten Flls kein weiterer IRQ kommt, Dornröschenschlf 1 void witsec( uint8_t sec ) { 2 // setup timer 3 sleep_enble(); 4 event = 0; 5 cli(); 6 while(!event ) { 7 sei(); kritisches Gebiet 8 sleep_cpu(); 9 cli(); 10 11 sei(); 12 sleep_disble(); 13 sttic voltile int8_t event; // TIMER1 ISR // triggers when // witsec() expires ISR(TIMER1_COMPA_vect) { event = 1; Wo genu ist ds kritische Gebiet? Test uf Vorbedingung und Beten des Schlfzustnds (Knn mn ds durch Interruptsperren bsichern?) Problem: Vor sleep_cpu() müssen IRQs freigegeben werden! Funktioniert dnk spezieller Hrdwreunterstützung: Befehlssequenz sei, sleep wird von der CPU tomr usgeführt c dl GSPiC (Teil C, WS 12) 15 Nebenläufigkeit 15.4 Nebenläufigkeit und Wettlufsitutionen 15 21 c dl GSPiC (Teil C, WS 12) 15 Nebenläufigkeit 15.4 Nebenläufigkeit und Wettlufsitutionen 15 22