diff --git a/20220613/bs-20220613.pdf b/20220613/bs-20220613.pdf index 754137dd44cac64b8f2a66f23f322334ad112ed8..9bb2d01cab317d4fd7b70a283fbf56e4efd76983 100644 Binary files a/20220613/bs-20220613.pdf and b/20220613/bs-20220613.pdf differ diff --git a/20220613/bs-20220613.tex b/20220613/bs-20220613.tex index 5de1ad4372d839c56bca66bb75ae68b04c132b58..3a6e00ad27e66211093dd6357df8f4d277727df7 100644 --- a/20220613/bs-20220613.tex +++ b/20220613/bs-20220613.tex @@ -237,11 +237,11 @@ Wertvolle Ressourcen \begin{itemize} \item - Fähigkeiten einer Raumsonde optimieren - % (Marsumlaufbahn: ab ca.~127\,000 Euro pro kg) + Fähigkeiten einer Raumsonde optimieren\\ + (Marsumlaufbahn:\\ab ca.~127\,000 Euro pro kg) % 70000000 / 550000 = 127._27 % http://www.bernd-leitenberger.de/blog/2009/09/29/reduktion-der-kosten-von-planetenmissionen/ - \only<.(1)>{\\[\bigskipamount]\strut\hfill\makebox(0,0)[r]{\includegraphics[height=3.5cm]{curiosity.jpg}}\vspace*{-1cm}} + \only<.(1)>{\\[\bigskipamount]\strut\hfill\makebox(0,0)[r]{\vspace*{1cm}\includegraphics[height=3.5cm]{curiosity.jpg}}\vspace*{-1cm}} \pause \item Implantat: Platz- und Stromverbrauch minimieren diff --git a/20220613/bs-20220613.txt b/20220613/bs-20220613.txt new file mode 100644 index 0000000000000000000000000000000000000000..240fdb2975a8ec36a20283a07b3cc1b4a02aa67f --- /dev/null +++ b/20220613/bs-20220613.txt @@ -0,0 +1,164 @@ +Wertebereiche von Bitfeldern, 13.06.2022, 11:58:01 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Syntax: + + struct { + unsigned LEDsR:3; + unsigned LEDsL:3; + unsigned reserved:2; + }; + +LEDsR ist ein vorzeichenloses Bit-Feld, bestehend aus 3 Bits. +Wertebereich: 0 bis 7 + +Dasselbe als vorzeichenbehaftetes Bit-Feld: + + struct { + int LEDsR:3; + int LEDsL:3; + int reserved:2; + }; + +Wertebereich bei 3 Bit: -4 bis 3 + +Warum? + + * 3 Bits --> Wir haben 8 Werte zur Verfügung. + + * Welche wir als positiv und welche als negativ interpretieren, + ist Sache der Konvention. + + Damit die Hardware mit den Zahlen effizient rechnen kann, + verwenden wir kein Offset, sondern behalten das Bitmuster + 000 für den Wert 0, 001 für 1 usw. + 000 001 010 011 100 101 110 111 + - alle positiv --> vorzeichenlose Zahl 0 1 2 3 4 5 6 7 + - -1 bis 6 0 1 2 3 4 5 6 -1 + - -2 bis 5 0 1 2 3 4 5 -2 -1 + - ... + - -7 bis 0 0 -7 -6 -5 -4 -3 -2 -1 + + In Hardware implementierte Konvention: MSB = Vorzeichen-Bit + Vorteil: Die Hardware erkennt anhand des MSB das Vorzeichen. + + 000 001 010 011 100 101 110 111 + 0 1 2 3 -4 -3 -2 -1 + +Aufgabe: Welchen Wertebereich hat eine vorzeichenbehaftete 1-Bit-Zahl? + +Lösung (per Mehrheitsbeschluß;-): 0 und -1 + +Überprüfung (unions-03.c): Stimmt. :-) + +Begründung: Das einzige Bit ist gleichzeitig das MSB. + Wenn es gesetzt ist, muß der Wert negativ interpretiert werden. + Dann sind alle Bits = 1, was der Zahl -1 entspricht. + +Was ist ein Callback? 13.06.2022, 13:15:47 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Ziel: Reaktion auf ein Ereignis +Beispiel: Ereignis: Bumper hat Hindernis erkannt. Reaktion: Anhalten. + +Weg dorthin: Bibliothek stellt einen "Callback"-Mechanismus zur Verfügung. + +Wir schreiben für die Reaktion eine Funktion. Hier z.B.: anhalten und blinken + + void bumpersStateChanged(void) + { + if(bumper_left || bumper_right) + { + moveAtSpeed(0,0); + setLEDs(0b010000); + startStopwatch1(); + } + } + +Vor dem Losfahren teilen wir der Bibliothek mit, daß sie diese Funktion +aufrufen soll, wenn das Ereignis (hier: Bumper löst aus) eintritt. + + BUMPERS_setStateChangedHandler(bumpersStateChanged); + +"Wenn sich der Zustand der Bumper ändert, +bitte die Funktion bumpersStateChanged() aufrufen." + +Später läuft dann die Hauptschleife der Bibliothek. +Diese ruft dann bei Bedarf die übergebene Funktion +("Callback-Funktion") auf. + +Variante dieses Konzepts: virtuelle Methode überschreiben + +Beispiel: GUI-Bibliothek +Ein GUI-Element hat eine virtuelle Methode, um seinen Inhalt darzustellen. +Wenn ich ein neues GUI-Element definiere, muß ich diese Methode überschreiben, +damit es seinen spezifischen Inhalt darstellen kann. + +Die GUI ruft dann bei Bedarf die virtuelle Methode auf ("Callback"). + +Beispiel: GUI-Bibliothek + - GTK in C: Callback-Funktion installieren + - GTK in C++: virtuelle Methode überschreiben + +Wie funktionieren Callbacks? 13.06.2022, 13:14:34 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Bumpers State changed handler: + + void BUMPERS_stateChanged_DUMMY(void){} + static void (*BUMPERS_stateChangedHandler)(void) = BUMPERS_stateChanged_DUMMY; + /** + * Use this function to set the Bumpers state change handler. + * + */ + void BUMPERS_setStateChangedHandler(void (*bumperHandler)(void)) + { + BUMPERS_stateChangedHandler = bumperHandler; + } + +Callback installieren: Funktion BUMPERS_setStateChangedHandler() + +Parameter der Funktion: void (*bumperHandler)(void) + "Funktion mit dem Namen '(*bumperHandler)'" + --> *bumerHandler ist eine Funktion. + --> Das, worauf bumerHandler zeigt, ist eine Funktion. + --> bumerHandler ist ein Zeiger auf eine Funktion. + +Aufruf von BUMPERS_setStateChangedHandler: + + BUMPERS_setStateChangedHandler(bumpersStateChanged); + + Wir übergeben die Adresse der Funktion bumpersStateChanged(). + Insbesondere rufen wir die Funktion bumpersStateChanged() nicht auf. + (Um sie aufzurufen, bräuchte man das Klammerpaar.) + +BUMPERS_setStateChangedHandler() merkt sich den Funktionszeiger +auf einer globalen Variablen BUMPERS_stateChangedHandler gleichen Typs. + +Diese Variable, ein Zeiger auf eine Funktion, zeigte vorher auf eine +Funktion BUMPERS_stateChanged_DUMMY, die nichts macht. + +Aber wer ruft nun tatsächlich die Callback-Funktion auf? + +Dies geschieht in der Funktion task_Bumpers(). +Diese Funktion + - schaut auf die Uhr: Sie wird höchstens alle 50 Millisekunden aktiv (weiche Echtzeit). + - fragt den Zustand der Bumper ab. + - ruft, sofern sich der Zustand der Bumper geändert hat, die Callback-Funktion auf. + +Verbleibende Fragen: + - Wie funktioniert die Abfrage des Zustands der Bumper? + - Wer ruft task_Bumpers() auf? + +Wie funktioniert die Abfrage des Zustands der Bumper? + - Der linke Bumper und LED Nr. 6 teilen sich einen Port + (Bumper als Input, LED als Output). + - Wir schalten LED Nr. 6 aus. + - Wir schalten den Port als Input. + - Wir warten einen Taktzyklus, damit der Prozessor den Input auslesen kann. + - Wir lesen den Input-Port. + - Sofern LED Nr. 6 leuchten soll, schalten wir den Port zurück auf Output + und die LED ein. + +Wer ruft task_Bumpers() auf? + - task_RP6System() ruft task_Bumpers() auf. + - Das Hauptprogramm ruft in seiner Hauptschleife task_RP6System() auf + ("kooperatives Multitasking"). + Ohne dies würden die Bumper nicht funktionieren. diff --git a/20220613/unions-03.c b/20220613/unions-03.c new file mode 100644 index 0000000000000000000000000000000000000000..d301f78fecd28719cb0dafa090a88cc08e5cbb5f --- /dev/null +++ b/20220613/unions-03.c @@ -0,0 +1,23 @@ +#include <stdio.h> +#include <stdint.h> + +typedef union +{ + uint8_t byte; + struct + { + unsigned bit0 : 1; + unsigned bit1 : 1; + int bit2 : 1; + int bit3 : 1; + }; +} data; + +int main (void) +{ + data d; + d.byte = 0x0a; + printf ("d.bit0 = %d, d.bit1 = %d, d.bit2 = %d, d.bit3 = %d\n", + d.bit0, d.bit1, d.bit2, d.bit3); + return 0; +}