mirror of
https://github.com/rust-embedded/rust-raspberrypi-OS-tutorials.git
synced 2024-11-03 15:40:21 +00:00
.. | ||
.vscode | ||
src | ||
Cargo.lock | ||
Cargo.toml | ||
kernel | ||
kernel8.img | ||
Makefile | ||
README.md |
Tutorial 06 - Drivers: GPIO and UART
tl;dr
Now that we enabled safe globals in the previous tutorial, the infrastructure is laid for adding the first real device drivers. We throw out the magic QEMU console and use a real UART now. Like serious embedded hackers do!
Notable additions
- For the first time, we will be able to run the code on the real hardware.
- Therefore, building is now differentiated between the RPi 3 and the RPi4.
- By default, all
Makefile
targets will build for the RPi 3. - In order to build for the the RPi4, prepend
BSP=rpi4
to each target. For example:BSP=rpi4 make
BSP=rpi4 make doc
- Unfortunately, QEMU does not yet support the RPi4, so
BSP=rpi4 make qemu
won't work.
- A
driver::interface::DeviceDriver
trait is added for abstractingBSP
driver implementations from kernel code. - Drivers are stored in
src/bsp/device_driver
, and can be reused betweenBSP
s.- We introduce the
GPIO
driver, which pinmuxes the RPi's PL011 UART. - Most importantly, the
PL011Uart
driver: It implements theconsole::interface::*
traits and is from now on used as the main system console output.
- We introduce the
BSP
s now contain a memory map insrc/bsp/memory.rs
. In the specific case, they contain the Raspberry'sMMIO
addresses which are used to instantiate the respectivedevice drivers.- We also modify the
panic!
handler, so that it does not anymore rely onprintln!
, which uses the globally-shared instance of theUART
that might be locked when an error is encountered (for now this can't happen due to theNullLock
, but with a real lock it becomes an issue).- Instead, it creates a new UART driver instance, re-initializes the device and uses that one to print. This increases the chances that the system is able to print a final important message before it suspends itself.
Boot it from SD card
Some steps for preparing the SD card differ between RPi3 and RPi4, so be careful.
Common for both
- Make a single
FAT32
partition namedboot
. - On the card, generate a file named
config.txt
with the following contents:
init_uart_clock=48000000
Pi 3
- Copy the following files from the Raspberry Pi firmware repo onto the SD card:
- Run
make
and copy the kernel8.img onto the SD card.
Pi 4
- Copy the following files from the Raspberry Pi firmware repo onto the SD card:
- Run
BSP=rpi4 make
and copy the kernel8.img onto the SD card.
Note: Should it not work on your RPi4, try renaming start4.elf
to start.elf
(without the 4)
on the SD card.
Common again
- Insert the SD card into the RPi and connect the USB serial to your host PC.
- Wiring diagram at top-level README.
- Run
screen
(you might need to install it first):
sudo screen /dev/ttyUSB0 230400
- Hit Enter to kick off the kernel boot process. Observe the output:
[0] Booting on: Raspberry Pi 3
[1] Drivers loaded:
1. BCM GPIO
2. BCM PL011 UART
[2] Chars written: 93
[3] Echoing input now
- Exit screen by pressing ctrl-a ctrl-d or disconnecting the USB serial.