Oblig 1 - Introduksjon til Raspberry Pi

I denne obligen skal du sette opp din Raspberry Pi (referert til som RPi fra nå av), og koble den til internett. Deretter skal du kjøre noen enkle linux kommandoer og C-programmer på den, samt skrive et enkelt C-program.

Før du kan begynne med obligen må du kjøpe inn en RPi (Se innkjøpsliste). Kurset tar utgangspunkt i en Raspberry Pi 4 model B, så vi anbefaler sterkt at dere benytter denne modellen. Det vil også være mulig å bruke en Raspberry Pi 3 model B+ dersom du har et sterkt ønske om det. Dersom du velger RPi3B+ må du ha med egen HDMI kabel på laben, ettersom laben er satt opp for tilkobling av RPi4B. I oblig 4 vil det være en konkurranse

Du trenger også følgende utstyr:

Dersom du har kjøpt et Raspberry Pi 4 B Kit vil Raspberry Pi OS allerede være installert på ditt SD-kort, og du kan hoppe videre til Sette opp RPi. Dersom du har kjøpt SD-kortet på en annen måte må du først installere Raspberry Pi OS. Dersom du har et Raspberry Pi 3 B+ kit anbefaler vi også å starte på Installere Raspberry Pi OS fordi det kan hende at din installasjon av Raspberry Pi OS har en versjon av python som ikke støtter gdbgui, et program vi vil bruke i oblig 3. Det er også mulig å oppgradere versjonen av python, men vi har ikke en guide tilgjengelig for dette.

Installere Raspberry Pi OS

Du trenger en annen PC med SD-kort leser for å kunne installere Raspberry Pi OS på ditt SD-kort.

1. Sett inn ditt SD-kort i PCen.

2. Installer Raspberry Pi Imager fra Raspberry Pis offisielle nettside.

3. Velg den anbefalte versjonen av Raspberry Pi OS(øverst) under operating system, og SD-kortet ditt under storage.

4. Trykk på write og et Raspberry Pi OS image vil skrives til SD-kortet ditt. (Merk at dette vil slette alt innhold som var på sd-kortet fra før)

Sette opp RPi

1. Sett inn ditt SD-kort i RPien.

2. Koble så til mus og tastatur via USB portene, og skjerm via HDMI kabel.

3. Forsikre deg om at skjermen er på, og stilt inn på riktig kilde. (HDMIen koblet til din RPi)

3. Til slutt kobler du til strømforsyningen. RPien vil da starte.

Koble til eduroam

Vi skal nå koble RPien til internett.

1. I hovedmenyen naviger til Preferences -> Raspberry pi configuration.

2. Trykk på Localisation fanen.

3. Under Set wifi country code velg Norge.

4. Under Timezone velg Europa -> Oslo.

5. Du kan også endre keyboard layout under Keyboard.

6. Koble til uioguest nettverket. (Obs! Du må åpne en browser og logge inn.) Dersom klokka på RPien går feil må du restarte RPien.

7. Åpne en terminal.

8. Kjør følgende kommandoer i terminalen:

sudo apt update
sudo apt upgrade
sudo apt install network-manager network-manager-gnome

9. Åpne filen: /etc/dhcpcd.conf og legg til denne linja i slutten av filen:

denyinterfaces wlan0

10. Kjør følgende i terminalen:

sudo systemctl restart dhcpcd

11. Åpne filen /etc/NetworkManager/NetworkManager.conf med administratorrettigheter. (f.eks. med sudo nano /etc/NetworkManager/NetworkManager.conf i terminalen)

12. Endre filen så den ser slik ut:

[main]
plugins=ifupdown,keyfile
dhcp=internal
 
[ifupdown]
managed=true

13. Kjør følgende i terminalen:

sudo reboot

14. Raspberry Pien vil restarte. Når den har restartet skal det være et ekstra Wifi symbol i øverste høyre hjørne, i tillegg til det som var der originalt. Klikk på dette og koble deg til uioguest nettverket.

15. Last ned python scriptet du finner her. Pass på at operativsystem er satt til linux.

16. Naviger i terminalen til mappen der scriptet ligger, og kjør scriptet med:

python "scriptets_navn".py

17. Du skal nå være koblet til eduroam!

Oppgaver

Etter å ha satt opp din RPi skal vi nå bli bedre kjent med operativsystemet (Raspberry Pi OS - Linux) og komme i gang med en enkel programmeringsoppgave.

Oppgaven skal leveres som en ZIP-et mappe med besvarelse på tekstoppgavene som en PDF-fil og eventuelle andre filer du blir bedt om å produsere lagt ved.

Linux og bash

Som en liten oppvarming skal vi først starte med å bli litt kjent med Linux og terminalen på vår RPi.

Åpne et terminalvindu og lag en ny mappe som heter in2060. Mapper lages med programmet mkdir.

mkdir in2060

Deretter skal vi bevege oss inn i mappen, før vi gjør det kan det være lurt å sjekke hvilken mappe vi står i akkurat nå, dette gjøres med pwd. For å se de andre mappene i nåværende mappe kan vi bruke kommandoen ls som burde vise mappen in2060 vi laget ovenfor. Et annet kjekt verktøy er kommandoen tree som viser mapper og undermapper som en trestruktur. For å bevege oss inn i mappen vi har laget bruker vi cd kommandoen etterfulgt av navnet på mappen vi ønsker å bevege oss inn i.

cd in2060

Inne i denne mappen skal vi gjøre den første oppgaven. Vi ønsker å finne ut hvor mange pakker Raspberry Pi OS har som inneholder ordet assembly. Vi kan bruke verkøyene apt eller apt-cache for å søke etter programmer. Vi skriver apt search søkeord.

Tips: For å ta skjermbilde på RPi trykk på tasten PrtScn eller kjør kommandoen scrot.

Innlevering:

Kompilere C kode

Det neste vi skal gjøre er å kompilere og kjøre et C program. Under har vi limt inn et program som skriver ut setningen Hello World!. For at vår RPi skal kunne kjøre denne koden må vi kompilere den med gcc.

La oss først se på koden:


#include <stdio.h>

int main(int argc, char** argv) {
    printf("Hello World!\n");
    return 0;
}

Den første linjen inneholder #include <stdio.h> dette forteller kompilatoren at vi ønsker å inkludere system filen stdio, som inneholder blandt annet funksjonen printf.

Den neste linjen med kode inneholder int main(int argc, char** argv), dette forteller kompilatoren at vi ønsker å definere en metode, som skal returnere et heltall (int), metoden skal hete main og den tar to argumenter (disse argumentene kan brukes for å hente inn input fra brukeren når programmet kjøres, men vi skal ikke bruke disse i denne obligen). Når vi definerer en metode med navnet main vil kompilatoren merke seg at dette er metoden som skal brukes som startpunkt når programmet vårt kjører.

Etter dette følger printf("Hello World!\n");. Dette er et metodekall til printf som vil skrive til terminalvinduet vårt. Her ser vi hvorfor vi trengte å inkludere systemfilen tidligere, siden vi ønsket å bruke printf definert i stdio.h. Legg merke til at med printf så inkluderes det ikke en ny linje og vi må manuelt skrive ut dette med \n på slutten.

Helt til slutt avsluttes metoden main ved return 0;. return forteller at vi ønsker å returnere fra metoden, men siden dette er en spesiell metode (main) så har returverdien en spesiell betydning. Å returnere 0 forteller terminalvinduet vårt at programmet avsluttet på riktig måte, mens return 1; ville indikert at det oppstod en feil under kjøring.

Kompilere og kjøre koden

Vi skal nå kompilere koden, for å gjøre dette trenger vi tilgang til programmet gcc som allerede burde være installert (hvis ikke kan det installeres med sudo apt install gcc).

Lim koden over inn i en fil i mappen in2060 ved navn helloworld.c og kjør følgende.

gcc -o hello helloworld.c
./hello

Innlevering:

FizzBuzz

Siste utfordring i denne obligen blir å endre litt på et C program. Vi skal løse det "kjente" problemet FizzBuzz.

FizzBuzz går ut på å skrive ut tallene mellom 1 og 100, men når tallet er delelig på 3 skrive ut "Fizz", når det er delelig på 5 "Buzz" og når det er delelig på begge skrive ut "Fizz Buzz". Vi har gjengitt de første fem utskriftene under.

1, 2, Fizz, 4, Buzz, ...

Bruk følgende C program og gjør nødvendig endringer slik at det oppfyller kravene til FizzBuzz ovenfor.


#include <stdio.h>

int main(int argc, char** argv) {
    for(int i = 1; i <= 30; i++) {
        if(i % 3 == 0) {
            printf("Fizz");
        } else {
            printf("%d", i);
        }
        printf(", ");
    }
    return 0;
}

Lim koden inn i en fil ved navn fizzbuzz.c og gjør endringer slik at programmet utfører FizzBuzz korrekt for tallene mellom 1 og 100. Når du er ferdig(og underveis) sjekk at programmet kompileres med gcc -o fizz fizzbuzz.c, og kjør det med ./fizz.

Innlevering:

Tips rundt kompilering

Når man kompilerer C kode kan det være lurt å spørre kompilatoren om det vi gjør virker fornuftig. I gcc kan dette gjøres ved å legge til flaggene -Wall og -Wextra. Disse flaggene gjør at gcc prøver så godt den kan å advare oss når vi gjør dumme ting.

Som et eksempel på dette så er følgende resultatet når løsningsforslaget til FizzBuzz blir kompilert.

$ gcc -o fizz fizzbuzz.c -Wall -Wextra
fizzbuzz.c: In function ‘main’:
fizzbuzz.c:3:14: warning: unused parameter ‘argc’ [-Wunused-parameter]
    3 | int main(int argc, char** argv) {
      |          ~~~~^~~~
fizzbuzz.c:3:27: warning: unused parameter ‘argv’ [-Wunused-parameter]
    3 | int main(int argc, char** argv) {
      |                    ~~~~~~~^~~~

Her kan vi se at gcc har oppdaget at vi ikke bruker argumentene til funksjonen og kanskje burde vurdere å ta de bort eller benytte oss av dem.

Dessverre inneholder gcc alt for mange ekstra flag til at vi kan liste de opp her. Vi anbefaler at man alltid bruker minst flaggene -Wall og -Wextra når man utvikler C kode slik at kompilatoren best mulig kan hjelpe til.