05. GPIO Control - Controlling Hardware Pins¶
GPIO (General Purpose Input/Output) pins are the Raspberry Pi's interface to the physical world. Let's learn how to control LEDs, read buttons, and interact with external hardware.
What is GPIO?¶
The Raspberry Pi 4B has 40 GPIO pins on its header. These pins can be configured as: - Output: Control LEDs, relays, motors - Input: Read buttons, sensors - Alternate Functions: UART, SPI, I2C, PWM
GPIO Pin Layout (Raspberry Pi 4B)¶
Voltage Levels
Raspberry Pi GPIO operates at 3.3V. Connecting 5V directly can damage the board!
GPIO Register Overview¶
BCM2711 GPIO Registers¶
| Register | Offset | Purpose |
|---|---|---|
GPFSEL0-5 |
0x00-0x14 | Function Select (input/output/alt) |
GPSET0-1 |
0x1C-0x20 | Set Pin High |
GPCLR0-1 |
0x28-0x2C | Clear Pin Low |
GPLEV0-1 |
0x34-0x38 | Read Pin Level |
GPIO_PUP_PDN_CNTRL |
0xE4+ | Pull-up/Pull-down Control (RPi 4) |
Base address: 0xFE200000 (RPi 4)
Function Select Register (GPFSEL)¶
Each pin uses 3 bits to select its function:
| Value | Function |
|---|---|
| 000 | Input |
| 001 | Output |
| 100 | Alt Function 0 |
| 101 | Alt Function 1 |
| ... | ... |
Example: To set GPIO 21 as output:
- GPIO 21 is in GPFSEL2 (pins 20-29)
- Bit offset: (21 % 10) * 3 = 3
- Set bits [5:3] to 001
Implementing the GPIO Driver¶
Header File: include/gpio.h¶
Driver Implementation: drivers/gpio.c¶
1. Setting Pin Function¶
2. Setting Pin High/Low¶
Write-Only Registers
GPSET and GPCLR are write-only. Write a 1 to the bit position to set/clear that pin.
3. Reading Pin State¶
LED Blinking Demo¶
Hardware Setup¶
Connect an LED to GPIO 21 (Pin 40):
Software: kernel/main.c¶
Building and Testing¶
1. Build¶
2. Deploy¶
Copy kernel8.img to SD card (with firmware files).
3. Connect Hardware¶
- LED on GPIO 21 (Pin 40)
- Resistor (220Ω - 1kΩ)
- Ground (Pin 39)
4. Power On¶
The LED should blink every second!
Expected Serial Output¶
Reading Button Input (Bonus)¶
Here's how to read a button on GPIO 16:
Hardware: - Button: One side to GPIO 16, other side to GND - Internal pull-up enabled (no external resistor needed)
Complete Source Code¶
Troubleshooting¶
| Problem | Solution |
|---|---|
| LED doesn't blink | Check wiring (anode/cathode) |
| LED always on/off | Verify pin number (GPIO 21 = Pin 40) |
| No serial output | UART still working? Check baud rate |
| Dim LED | Resistor too large, try 220Ω |
GPIO Safety Tips¶
- Never exceed 3.3V on any GPIO pin
- Current limit: Max ~16mA per pin, ~50mA total
- Use resistors with LEDs (recommended: 220Ω-1kΩ)
- Short circuit protection: None! Be careful
What's Next?¶
Now that we can control GPIO, the next article covers Interrupts and Exception Handling, which will allow us to: - Respond to button presses instantly (no polling) - Handle timer interrupts for multitasking - Catch and handle CPU exceptions (e.g., data aborts)
Stay tuned!