Skip to content
Snippets Groups Projects
Commit 3893c9bb authored by Peter Gerwinski's avatar Peter Gerwinski
Browse files

Vorbereitung 15.11.2021

parent a26f450b
No related branches found
No related tags found
No related merge requests found
Showing
with 2082 additions and 0 deletions
%.elf: %.c
avr-gcc -Wall -Os -mmcu=atmega328p $< -o $@
%.hex: %.elf
avr-objcopy -O ihex $< $@
download:
./download.sh
#include <avr/io.h>
int main (void)
{
DDRA = 0xff;
DDRB = 0xff;
DDRC = 0xff;
DDRD = 0xff;
PORTA = 0x1f;
PORTB = 0x10;
PORTD = 0x10;
PORTC = 0xfc;
while (1);
return 0;
}
#include <stdio.h>
#include <string.h>
void insert_into_string (char src, char *target, int pos)
{
int len = strlen (target);
for (int i = pos; i < len; i++)
target[i+1] = target[i];
target[pos] = src;
}
int main (void)
{
char test[100] = "Hochshule Bochum";
insert_into_string ('c', test, 5);
printf ("%s\n", test);
return 0;
}
#include <avr/io.h>
int main (void)
{
DDRD = 0x40; /* binär: 0100 0000 */
PORTD = 0x40; /* binär: 0100 0000 */
while (1);
return 0;
}
#include <avr/io.h>
#define F_CPU 16000000l
#include <util/delay.h>
int main (void)
{
DDRD = 0x01;
PORTD |= 0x01;
while (1)
{
_delay_ms (500);
PORTD &= ~0x01;
_delay_ms (500);
PORTD |= 0x01;
}
return 0;
}
#include <avr/io.h>
#define F_CPU 16000000l
#include <util/delay.h>
int main (void)
{
DDRD = 0x02;
PORTD = 0x02;
while (1)
{
_delay_ms (250);
PORTD ^= 0x02;
}
return 0;
}
#include <avr/io.h>
#define F_CPU 16000000
#include <util/delay.h>
int main (void)
{
DDRD = 0x01;
PORTD = 0x01;
while (1)
{
while ((PIND & 0x02) == 0)
; /* just wait */
PORTD ^= 0x01;
}
return 0;
}
#include <avr/io.h>
#define F_CPU 16000000
#include <util/delay.h>
int main (void)
{
DDRD = 0x01;
PORTD = 0x01;
while (1)
{
while ((PIND & 0x02) == 0)
; /* just wait */
PORTD ^= 0x01;
_delay_ms (200);
}
return 0;
}
port=$(ls -rt /dev/ttyACM* | tail -1)
echo avrdude -P $port -c arduino -p m328p -U flash:w:$(ls -rt *.hex | tail -1)
avrdude -P $port -c arduino -p m328p -U flash:w:$(ls -rt *.hex | tail -1) 2>/dev/null
File added
This diff is collapsed.
File added
% hp-musterloesung-20211115.pdf - Solutions to the Exercises on Low-Level Programming
% Copyright (C) 2013, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Peter Gerwinski
%
% This document is free software: you can redistribute it and/or
% modify it either under the terms of the Creative Commons
% Attribution-ShareAlike 3.0 License, or under the terms of the
% GNU General Public License as published by the Free Software
% Foundation, either version 3 of the License, or (at your option)
% any later version.
%
% This document is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this document. If not, see <http://www.gnu.org/licenses/>.
%
% You should have received a copy of the Creative Commons
% Attribution-ShareAlike 3.0 Unported License along with this
% document. If not, see <http://creativecommons.org/licenses/>.
% README: Zahlensysteme, Mikrocontroller, Einfügen in Strings
\documentclass[a4paper]{article}
\usepackage{pgscript}
\begin{document}
\section*{Hardwarenahe Programmierung\\
Musterlösung zu den Übungsaufgaben -- l5.\ November 2021}
\exercise{Zahlensysteme}
Wandeln Sie ohne Hilfsmittel
\begin{minipage}[t]{0.3\textwidth}
\begin{itemize}
\item
nach Dezimal:
\begin{itemize}
\item[(a)]
0010\,0000$_2$
\item[(b)]
42$_{16}$
\item[(c)]
17$_8$
\end{itemize}
\end{itemize}
\end{minipage}\hfill
\begin{minipage}[t]{0.3\textwidth}
\begin{itemize}
\item
nach Hexadezimal:
\begin{itemize}
\item[(d)]
0010\,0000$_2$
\item[(e)]
42$_{10}$
\item[(f)]
192.168.20.254$_{256}$
\end{itemize}
\end{itemize}
\end{minipage}\hfill
\begin{minipage}[t]{0.3\textwidth}
\begin{itemize}
\item
nach Binär:
\begin{itemize}
\item[(g)]
750$_8$
\item[(h)]
42$_{10}$
\item[(i)]
AFFE$_{16}$
\end{itemize}
\end{itemize}
\end{minipage}
\medskip
Berechnen Sie ohne Hilfsmittel:
\begin{itemize}
\item[(j)]
750$_8$ \& 666$_8$
\item[(k)]
A380$_{16}$ + B747$_{16}$
\item[(l)]
AFFE$_{16} >> 1$
\end{itemize}
Die tiefgestellte Zahl steht für die Basis des Zahlensystems.
Jede Teilaufgabe zählt 1 Punkt. \addtocounter{points}{12}
(In der Klausur sind Hilfsmittel zugelassen,
daher ist dies \emph{keine\/} typische Klausuraufgabe.)
\solution
Wandeln Sie ohne Hilfsmittel
\begin{itemize}
\item
nach Dezimal:
\begin{itemize}
\item[(a)]
$0010\,0000_2 = 32_{10}$
Eine Eins mit fünf Nullen dahinter steht binär für $2^5 = 32$:\\
mit $1$ anfangen und fünfmal verdoppeln.
\item[(b)]
$42_{16} = 4 \cdot 16 + 2 \cdot 1 = 64 + 2 = 66$
\item[(c)]
$17_8 = 1 \cdot 8 + 7 \cdot 1 = 8 + 7 = 15$
\end{itemize}
Umwandlung von und nach Dezimal ist immer rechenaufwendig.
Umwandlungen zwischen Binär, Oktal und Hexadezimal gehen ziffernweise
und sind daher wesentlich einfacher.
\item
nach Hexadezimal:
\begin{itemize}
\item[(d)]
$0010\,0000_2 = 20_{16}$
Umwandlung von Binär nach Hexadezimal geht ziffernweise:\\
Vier Binärziffern werden zu einer Hex-Ziffer.
\item[(e)]
$\rm 42_{10} = 32_{10} + 10_{10} = 20_{16} + A_{16} = 2A_{16}$
\item[(f)]
$\rm 192.168.20.254_{256} = C0\,A8\,14\,FE_{16}$
Umwandlung von der Basis 256 nach Hexadezimal geht ziffernweise:\\
Eine 256er-Ziffer wird zu zwei Hex-Ziffern.
Da die 256er-Ziffern dezimal angegeben sind,
müssen wir viermal Dezimal nach Hexadezimal umwandeln.
Hierfür bieten sich unterschiedliche Wege an.
$\rm 192_{10} = 128_{10} + 64_{10} = 1100\,0000_{2} = C0_{16}$
$\rm 168_{10} = 10_{10} \cdot 16_{10} + 8_{10} = A_{16} \cdot 10_{16} + 8_{16} = A8_{16}$
$20_{10} = 16_{10} + 4_{10} = 10_{16} + 4_{16} = 14$
$\rm 254_{10} = 255_{10} - 1_{10} = FF_{16} - 1_{16} = FE_{16}$
\end{itemize}
\item
nach Binär:
\begin{itemize}
\item[(g)]
$750_8 = 111\,101\,000_2$
Umwandlung von Oktal nach Binär geht ziffernweise:\\
Eine Oktalziffer wird zu drei Binärziffern.
\item[(h)]
$\rm 42_{10} = 2A_{16}$ (siehe oben) $= 0010\,1010_{16}$
Umwandlung von Hexadezimal nach Binär geht ziffernweise:\\
Eine Hex-Ziffer wird zu vier Binärziffern.
\item[(i)]
$\rm AFFE_{16} = 1010\,1111\,1111\,1110_2$
Umwandlung von Hexadezimal nach Binär geht ziffernweise:\\
Eine Hex-Ziffer wird zu vier Binärziffern.
\end{itemize}
\end{itemize}
\medskip
Berechnen Sie ohne Hilfsmittel:
\begin{itemize}
\item[(j)]
$750_8\,\&\,666_8
= 111\,101\,000_2\,\&\,110\,110\,110_2
= 110\,100\,000_2
= 640_8$
Binäre Und-Operationen lassen sich am leichtesten
in binärer Schreibweise durchführen.
Umwandlung zwischen Oktal und Binär geht ziffernweise:
Eine Oktalziffer wird zu drei Binärziffern und umgekehrt.
Mit etwas Übung funktionieren diese Operationen
auch direkt mit Oktalzahlen im Kopf.
\item[(k)]
$\rm\phantom{+}A380_{16}$\\
$\rm+\kern2ptB747_{16}$\\[-\medskipamount]
\rule{1.4cm}{0.5pt}\\
$\rm 15AC7_{16}$
\begin{picture}(0,0)
\put(-1.4,0.35){\mbox{\scriptsize\bf 1}}
\end{picture}
Mit Hexadezimalzahlen (und Binär- und Oktal- und sonstigen Zahlen)
kann man genau wie mit Dezimalzahlen schriftlich rechnen.
Man muß nur daran denken, daß der "`Zehner"'-Überlauf nicht bei
$10_{10}$ stattfindet, sondern erst bei $10_{16} = 16_{10}$
(hier: $\rm 8_{16} + 4_{16} = C_{16}$ und
$\rm 3_{16} + 7_{16} = A_{16}$, aber
$\rm A_{16} + B_{16} = 10_{10} + 11_{10}
= 21_{10} = 16_{10} + 5_{10} = 10_{16} + 5_{16} = 15_{16}$).
\item[(l)]
$\rm AFFE_{16} >> 1
= 1010\,1111\,1111\,1110_2 >> 1
= 0101\,0111\,1111\,1111_2
= 57FF_{16}$
Bit-Verschiebungen lassen sich am leichtesten
in binärer Schreibweise durchführen.
Umwandlung zwischen Hexadezimal und Binär geht ziffernweise:
Eine Hex-Ziffer wird zu vier Binärziffern und umgekehrt.
Mit etwas Übung funktionieren diese Operationen
auch direkt mit Hexadezimalzahlen im Kopf.
\end{itemize}
\exercise{Mikrocontroller}
\begin{minipage}[t]{10cm}
An die vier Ports eines ATmega16-Mikrocontrollers sind Leuchtdioden angeschlossen:
\begin{itemize}
\item
von links nach rechts an die Ports A, B, C und D,
\item
von oben nach unten an die Bits Nr.\ 0 bis 7.
\end{itemize}
Wir betrachten das folgende Programm (\gitfile{hp}{2021ws/20211115}{aufgabe-2.c}):
\begin{lstlisting}[gobble=6]
#include <avr/io.h>
int main (void)
{
DDRA = 0xff;
DDRB = 0xff;
DDRC = 0xff;
DDRD = 0xff;
PORTA = 0x1f;
PORTB = 0x10;
PORTD = 0x10;
PORTC = 0xfc;
while (1);
return 0;
}
\end{lstlisting}
\end{minipage}\hfill
\begin{minipage}[t]{3cm}
\strut\\[-\baselineskip]
\includegraphics[width=3cm]{leds.jpg}
\end{minipage}
\vspace*{-3cm}
\strut\hfill
\begin{minipage}{11.8cm}
\begin{itemize}
\item[(a)]
Was bewirkt dieses Programm? \points{4}
\item[(b)]
Wozu dienen die ersten vier Zeilen des Hauptprogramms? \points{2}
\item[(c)]
Was würde stattdessen die Zeile \lstinline{DDRA, DDRB, DDRC, DDRD = 0xff;} bewirken?
\points{2}
\item[(d)]
Schreiben Sie das Programm so um,
daß die durch das Programm dargestellte Figur spiegelverkehrt erscheint. \points{3}
\item[(e)]
Wozu dient das \lstinline{while (1)}? \points{2}
\item
Alle Antworten bitte mit Begründung.
\end{itemize}
\end{minipage}
\solution
\begin{itemize}
\item[(a)]
\textbf{Was bewirkt dieses Programm?}
\newcommand{\x}{$\bullet$}
\renewcommand{\o}{$\circ$}
\begin{minipage}[t]{0.75\textwidth}\parskip\smallskipamount
Es läßt die LEDs in dem rechts abgebildeten Muster aufleuchten,\\
das z.\,B.\ als die Ziffer 4 gelesen werden kann.
(Das Zeichen \x\ steht für eine leuchtende, \o\ für eine nicht leuchtende LED.)
Die erste Spalte (Port A) von unten nach oben gelesen (Bit 7 bis 0)\\
entspricht der Binärdarstellung von \lstinline{0x1f}: 0001\,1111.
Die dritte Spalte (Port C) von unten nach oben gelesen (Bit 7 bis 0)\\
entspricht der Binärdarstellung von \lstinline{0xfc}: 1111\,1100.
Die zweite und vierte Spalte (Port B und D) von unten nach oben gelesen\\
(Bit 7 bis 0) entsprechen der Binärdarstellung von \lstinline{0x10}: 0001\,0000.
Achtung: Die Zuweisung der Werte an die Ports erfolgt im Programm\\
\emph{nicht\/} in der Reihenfolge A B C D, sondern in der Reihenfolge A B D C.
\end{minipage}\hfill
\begin{minipage}[t]{0.15\textwidth}
\vspace*{-0.5cm}%
\begin{tabular}{cccc}
\x & \o & \o & \o \\
\x & \o & \o & \o \\
\x & \o & \x & \o \\
\x & \o & \x & \o \\
\x & \x & \x & \x \\
\o & \o & \x & \o \\
\o & \o & \x & \o \\
\o & \o & \x & \o \\
\end{tabular}
\end{minipage}
\item[(b)]
\textbf{Wozu dienen die ersten vier Zeilen des Hauptprogramms?}
Mit diesen Zeilen werden alle jeweils 8 Bits aller 4 Ports
als Output-Ports konfiguriert.
\item[(c)]
\textbf{Was würde stattdessen die Zeile \lstinline{DDRA, DDRB, DDRC, DDRD = 0xff;} bewirken?}
Der Komma-Operator in C bewirkt, daß der erste Wert berechnet
und wieder verworfen wird und stattdessen der zweite Wert weiterverarbeitet wird.
Konkret hier hätte das zur Folge,
daß \lstinline{DDRA}, \lstinline{DDRB} und \lstinline{DDRC}
gelesen und die gelesenen Werte ignoriert werden;
anschließend wird \lstinline{DDRD} der Wert \lstinline{0xff} zugewiesen.
Damit würde also nur einer von vier Ports überhaupt konfiguriert.
Da es sich bei den \lstinline{DDR}-Variablen
um \lstinline{volatile}-Variable handelt,
nimmt der Compiler an, daß der Lesezugriff schon irgendeinen Sinn hätte.
Der Fehler bliebe also unbemerkt.
\item[(d)]
\textbf{Schreiben Sie das Programm so um,
daß die durch das Programm dargestellte Figur spiegelverkehrt erscheint.}
Hierzu vertauschen wir die Zuweisungen
an \lstinline{PORTA} und \lstinline{PORTD}
sowie die Zuweisungen
an \lstinline{PORTB} und \lstinline{PORTC}:
\begin{lstlisting}[gobble=8]
PORTD = 0x1f;
PORTC = 0x10;
PORTA = 0x10;
PORTB = 0xfc;
\end{lstlisting}
Damit ergibt sich eine Spiegelung an der vertikalen Achse.
Alternativ kann man auch an der horizontalen Achse spiegeln.
Dafür muß man die Bits in den Hexadezimalzahlen umdrehen:
\begin{lstlisting}[gobble=8]
PORTA = 0xf8;
PORTB = 0x08;
PORTD = 0x08;
PORTC = 0x3f;
\end{lstlisting}
Die Frage, welche der beiden Spiegelungen gewünscht ist,
wäre übrigens \emph{auch in der Klausur zulässig}.
\item[(e)]
\textbf{Wozu dient das \lstinline{while (1)}?}
Mit dem \lstinline{return}-Befehl am Ende des Hauptprogramms
gibt das Programm die Kontrolle an das Betriebssystem zurück.
Dieses Programm jedoch läuft auf einem Mikrocontroller,
auf dem es kein Betriebssystem gibt.
Wenn das \lstinline{return} ausgeführt würde,
hätte es ein undefiniertes Verhalten zur Folge.
Um dies zu verhindern, endet das Programm in einer Endlosschleife,
mit der wir den Mikrocontroller anweisen,
nach der Ausführung des Programms \emph{nichts mehr\/} zu tun
(im Gegensatz zu: \emph{irgendetwas Undefiniertes\/} zu tun).
\end{itemize}
\exercise{Einfügen in Strings}
Wir betrachten das folgende Programm (\gitfile{hp}{2021ws/20211115}{aufgabe-2.c}):
% \begin{lstlisting}[style=numbered]
\begin{lstlisting}
#include <stdio.h>
#include <string.h>
void insert_into_string (char src, char *target, int pos)
{
int len = strlen (target);
for (int i = pos; i < len; i++)
target[i+1] = target[i];
target[pos] = src;
}
int main (void)
{
char test[100] = "Hochshule Bochum";
insert_into_string ('c', test, 5);
printf ("%s\n", test);
return 0;
}
\end{lstlisting}
Die Ausgabe des Programms lautet:
\lstinline[style=terminal]{Hochschhhhhhhhhhh}
\begin{enumerate}[\quad(a)]
\item
Erklären Sie, wie die Ausgabe zustandekommt.
\points{3}
% \workspace{12}
\item
Schreiben Sie die Funktion \lstinline|insert_into_string()| so um,
daß sie den Buchstaben \lstinline{src} an der Stelle \lstinline{pos}
in den String \lstinline{target} einfügt.\par
Die Ausgabe des Programms müßte dann
\lstinline[style=terminal]{Hochschule Bochum} lauten.
\points{2}
% \workspace{13}
\item
Was kann passieren, wenn Sie die Zeile
\lstinline{char test[100] = "Hochshule Bochum";}\\
durch
\lstinline{char test[] = "Hochshule Bochum";} ersetzen?
Begründen Sie Ihre Antwort.
\points{2}
% \workspace{10}
\item
Was kann passieren, wenn Sie die Zeile
\lstinline{char test[100] = "Hochshule Bochum";}\\
durch
\lstinline{char *test = "Hochshule Bochum";} ersetzen?
Begründen Sie Ihre Antwort.
\points{2}
% \workspace{10}
% \item
% Schreiben Sie eine Funktion
% \lstinline{void insert_into_string_sorted (char src, char *target)},
% die voraussetzt, daß der String \lstinline{target} alphabetisch sortiert ist
% und den Buchstaben \lstinline{src} an der alphabetisch richtigen Stelle
% einfügt. Diese Funktion darf die bereits vorhandene Funktion
% \lstinline|insert_into_string()| aufrufen.\\
% \points{4}\par
% Zum Testen eignen sich die folgenden Zeilen im Hauptprogramm:
% \begin{lstlisting}[gobble=8]
% char test[100] = "";
% insert_into_string_sorted ('c', test);
% insert_into_string_sorted ('a', test);
% insert_into_string_sorted ('d', test);
% insert_into_string_sorted ('b', test);
% \end{lstlisting}
% Danach sollte \lstinline{test[]} die Zeichenfolge \lstinline{"abcd"} enthalten.
% \workspace{14}
% \item
% Wie schnell (Landau-Symbol in Abhängigkeit von der Länge $n$ des Strings)
% arbeitet Ihre Funktion
% \lstinline{void insert_into_string_sorted (char src, char *target)}
% und warum?
% \points{1}
% \workspace{10}
% \item
% Beschreiben Sie -- in Worten oder als C-Quelltext --, wie man die Funktion\\
% \lstinline{void insert_into_string_sorted (char src, char *target)}
% so gestalten kann,\\
% daß sie in $\mathcal{O}(\log n)$ arbeitet.
% \points{3}
% \workspace{35}
\end{enumerate}
\solution
\begin{enumerate}[\quad(a)]
\item
\textbf{Erklären Sie, wie die Ausgabe zustandekommt.}
In der Schleife wird \emph{zuerst\/} der nächste Buchstabe \lstinline{target[i + 1]}
gleich dem aktuellen gesetzt
und \emph{danach\/} der Zähler \lstinline{i} erhöht.
Dadurch wird im nächsten Schleifendurchlauf der bereits verschobene Buchstabe
noch weiter geschoben und letztlich alle Buchstaben in \lstinline{target[]}
durch den an der Stelle \lstinline{pos} ersetzt.
\item
\textbf{Schreiben Sie die Funktion \lstinline|insert_into_string()| so um,
daß sie den Buchstben \lstinline{src} an der Stelle \lstinline{pos}
in den String \lstinline{target} einfügt.}\par
\textbf{Die Ausgabe des Programms müßte dann
\lstinline[style=terminal]{Hochschule Bochum} lauten.}
Um im String "`Platz zu schaffen"', muß man von hinten beginnen,
also die Schleife umdrehen\\
(siehe: \gitfile{hp}{2021ws/20211115}{loesung-3.c}):
\begin{lstlisting}{gobble=8}
for (int i = len; i >= pos; i--)
target[i + 1] = target[i];
\end{lstlisting}
\item
\textbf{Was kann passieren, wenn Sie die Zeile
\lstinline{char test[100] = "Hochshule Bochum";}\\
durch
\lstinline{char test[] = "Hochshule Bochum";}
ersetzen und warum?}
Die Schreibweise \lstinline{test[]} bedeutet,
daß der Compiler selbst zählt, wieviel Speicherplatz der String benötigt,
un dann genau die richtige Menge Speicher reserviert
(anstatt, wie wir es manuell getan haben, pauschal Platz für 100 Zeichen).
Wenn wir nun in den String ein zusätzliches Zeichen einfügen,
ist dafür kein Speicherplatz reserviert worden,
und wir \textbf{überschreiben} dann Speicher, an dem sich andere Variable befinden,
was zu einem \textbf{Absturz} führen kann.
Da wir hier nur ein einziges Zeichen schreiben,
wird dieser Fehler nicht sofort auffallen.
Dies ist schlimmer, als wenn das Programm direkt beim ersten Test abstürzt,
denn dadurch entsteht bei uns der Eindruck, es sei in Ordnung.
Wenn danach der Fehler in einer Produktivumgebung auftritt,
kann dadurch Schaden entstehen -- je nach Einsatzgebiet der Software
u.\,U.\ erheblicher Vermögens-, Sach- und/oder Personenschaden
(z.\,B.\ Absturz eines Raumflugkörpers).
\item
\textbf{Was kann passieren, wenn Sie
\lstinline{char test[100] = "Hochshule Bochum";}\\
durch
\lstinline{char *test = "Hochshule Bochum";}
ersetzen und warum?}
In diesem Fall wird der Speicher für den eigentlichen String
in einem unbenannten, \textbf{nicht schreibbaren} Teil des Speichers reserviert.
Unser Versuch, dorthin ein zusätzliches Zeichen zu schreiben,
fürt dann normalerweise zu einem \textbf{Absturz}.
In manchen Systemen (Betriebssystem, Compiler, \dots)
ist der Speicherbereich tatsächlich sehr wohl schreibbar.
In diesem Fall tritt der Absturz nicht immer und nicht immer sofort auf --
genau wie in Aufgabenteil (c).
\end{enumerate}
\end{document}
File added
% hp-uebung-20211115.pdf - Exercises on Low-Level Programming
% Copyright (C) 2013, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Peter Gerwinski
%
% This document is free software: you can redistribute it and/or
% modify it either under the terms of the Creative Commons
% Attribution-ShareAlike 3.0 License, or under the terms of the
% GNU General Public License as published by the Free Software
% Foundation, either version 3 of the License, or (at your option)
% any later version.
%
% This document is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this document. If not, see <http://www.gnu.org/licenses/>.
%
% You should have received a copy of the Creative Commons
% Attribution-ShareAlike 3.0 Unported License along with this
% document. If not, see <http://creativecommons.org/licenses/>.
% README: Zahlensysteme, Mikrocontroller, Einfügen in Strings (Ergänzung)
\documentclass[a4paper]{article}
\usepackage{pgscript}
\begin{document}
% \thispagestyle{empty}
\section*{Hardwarenahe Programmierung\\
Übungsaufgaben -- 15.\ November 2021}
Diese Übung enthält Punkteangaben wie in einer Klausur.
Um zu "`bestehen"', müssen Sie innerhalb von 85 Minuten
unter Verwendung ausschließlich zugelassener Hilfsmittel
17 Punkte (von insgesamt \totalpoints) erreichen.
\exercise{Zahlensysteme}
Wandeln Sie ohne Hilfsmittel
\begin{minipage}[t]{0.3\textwidth}
\begin{itemize}
\item
nach Dezimal:
\begin{itemize}
\item[(a)]
0010\,0000$_2$
\item[(b)]
42$_{16}$
\item[(c)]
17$_8$
\end{itemize}
\end{itemize}
\end{minipage}\hfill
\begin{minipage}[t]{0.3\textwidth}
\begin{itemize}
\item
nach Hexadezimal:
\begin{itemize}
\item[(d)]
0010\,0000$_2$
\item[(e)]
42$_{10}$
\item[(f)]
192.168.20.254$_{256}$
\end{itemize}
\end{itemize}
\end{minipage}\hfill
\begin{minipage}[t]{0.3\textwidth}
\begin{itemize}
\item
nach Binär:
\begin{itemize}
\item[(g)]
750$_8$
\item[(h)]
42$_{10}$
\item[(i)]
AFFE$_{16}$
\end{itemize}
\end{itemize}
\end{minipage}
\medskip
Berechnen Sie ohne Hilfsmittel:
\begin{itemize}
\item[(j)]
750$_8$ \& 666$_8$
\item[(k)]
A380$_{16}$ + B747$_{16}$
\item[(l)]
AFFE$_{16} >> 1$
\end{itemize}
Die tiefgestellte Zahl steht für die Basis des Zahlensystems.
Jede Teilaufgabe zählt 1 Punkt. \addtocounter{points}{12}
(In der Klausur sind Hilfsmittel zugelassen,
daher ist dies \emph{keine\/} typische Klausuraufgabe.)
\exercise{Mikrocontroller}
\begin{minipage}[t]{10cm}
An die vier Ports eines ATmega16-Mikrocontrollers sind Leuchtdioden angeschlossen:
\begin{itemize}
\item
von links nach rechts an die Ports A, B, C und D,
\item
von oben nach unten an die Bits Nr.\ 0 bis 7.
\end{itemize}
Wir betrachten das folgende Programm (\gitfile{hp}{2021ws/20211115}{aufgabe-2.c}):
\begin{lstlisting}[gobble=6]
#include <avr/io.h>
int main (void)
{
DDRA = 0xff;
DDRB = 0xff;
DDRC = 0xff;
DDRD = 0xff;
PORTA = 0x1f;
PORTB = 0x10;
PORTD = 0x10;
PORTC = 0xfc;
while (1);
return 0;
}
\end{lstlisting}
\end{minipage}\hfill
\begin{minipage}[t]{3cm}
\strut\\[-\baselineskip]
\includegraphics[width=3cm]{leds.jpg}
\end{minipage}
\vspace*{-3cm}
\strut\hfill
\begin{minipage}{11.8cm}
\begin{itemize}
\item[(a)]
Was bewirkt dieses Programm? \points{4}
\item[(b)]
Wozu dienen die ersten vier Zeilen des Hauptprogramms? \points{2}
\item[(c)]
Was würde stattdessen die Zeile \lstinline{DDRA, DDRB, DDRC, DDRD = 0xff;} bewirken?
\points{2}
\item[(d)]
Schreiben Sie das Programm so um,
daß die durch das Programm dargestellte Figur spiegelverkehrt erscheint. \points{3}
\item[(e)]
Wozu dient das \lstinline{while (1)}? \points{2}
\item
Alle Antworten bitte mit Begründung.
\end{itemize}
\end{minipage}
\exercise{Einfügen in Strings}
Wir betrachten das folgende Programm (\gitfile{hp}{2021ws/20211115}{aufgabe-3.c}):
% \begin{lstlisting}[style=numbered]
\begin{lstlisting}
#include <stdio.h>
#include <string.h>
void insert_into_string (char src, char *target, int pos)
{
int len = strlen (target);
for (int i = pos; i < len; i++)
target[i+1] = target[i];
target[pos] = src;
}
int main (void)
{
char test[100] = "Hochshule Bochum";
insert_into_string ('c', test, 5);
printf ("%s\n", test);
return 0;
}
\end{lstlisting}
Die Ausgabe des Programms lautet:
\lstinline[style=terminal]{Hochschhhhhhhhhhh}
\begin{enumerate}[\quad(a)]
\item
Erklären Sie, wie die Ausgabe zustandekommt.
\points{3}
% \workspace{12}
\item
Schreiben Sie die Funktion \lstinline|insert_into_string()| so um,
daß sie den Buchstaben \lstinline{src} an der Stelle \lstinline{pos}
in den String \lstinline{target} einfügt.\par
Die Ausgabe des Programms müßte dann
\lstinline[style=terminal]{Hochschule Bochum} lauten.
\points{2}
% \workspace{13}
\item
Was kann passieren, wenn Sie die Zeile
\lstinline{char test[100] = "Hochshule Bochum";}\\
durch
\lstinline{char test[] = "Hochshule Bochum";} ersetzen?
Begründen Sie Ihre Antwort.
\points{2}
% \workspace{10}
\item
Was kann passieren, wenn Sie die Zeile
\lstinline{char test[100] = "Hochshule Bochum";}\\
durch
\lstinline{char *test = "Hochshule Bochum";} ersetzen?
Begründen Sie Ihre Antwort.
\points{2}
% \workspace{10}
% \item
% Schreiben Sie eine Funktion
% \lstinline{void insert_into_string_sorted (char src, char *target)},
% die voraussetzt, daß der String \lstinline{target} alphabetisch sortiert ist
% und den Buchstaben \lstinline{src} an der alphabetisch richtigen Stelle
% einfügt. Diese Funktion darf die bereits vorhandene Funktion
% \lstinline|insert_into_string()| aufrufen.\\
% \points{4}\par
% Zum Testen eignen sich die folgenden Zeilen im Hauptprogramm:
% \begin{lstlisting}[gobble=8]
% char test[100] = "";
% insert_into_string_sorted ('c', test);
% insert_into_string_sorted ('a', test);
% insert_into_string_sorted ('d', test);
% insert_into_string_sorted ('b', test);
% \end{lstlisting}
% Danach sollte \lstinline{test[]} die Zeichenfolge \lstinline{"abcd"} enthalten.
% \workspace{14}
% \item
% Wie schnell (Landau-Symbol in Abhängigkeit von der Länge $n$ des Strings)
% arbeitet Ihre Funktion
% \lstinline{void insert_into_string_sorted (char src, char *target)}
% und warum?
% \points{1}
% \workspace{10}
% \item
% Beschreiben Sie -- in Worten oder als C-Quelltext --, wie man die Funktion\\
% \lstinline{void insert_into_string_sorted (char src, char *target)}
% so gestalten kann,\\
% daß sie in $\mathcal{O}(\log n)$ arbeitet.
% \points{3}
% \workspace{35}
\end{enumerate}
\begin{flushright}
\textit{Viel Erfolg!}
\end{flushright}
\makeatletter
\immediate\write\@mainaux{\string\gdef\string\totalpoints{\arabic{points}}}
\makeatother
\end{document}
../common/io-ports-and-interrupts.pdf
\ No newline at end of file
../common/leds.jpg
\ No newline at end of file
#include <stdio.h>
#include <string.h>
void insert_into_string (char src, char *target, int pos)
{
int len = strlen (target);
for (int i = len; i >= pos; i--)
target[i + 1] = target[i];
target[pos] = src;
}
int main (void)
{
char test[100] = "Hochshule Bochum";
insert_into_string ('c', test, 5);
printf ("%s\n", test);
return 0;
}
../common/logo-hochschule-bochum-cvh-text-v2.pdf
\ No newline at end of file
../common/logo-hochschule-bochum.pdf
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment