Kompilasi oleh : Reza Ervani bin Asmanu
Pendahuluan
Setelah memahami struktur internal bit pada register GPFSEL (Function Select), langkah selanjutnya dalam pemahaman arsitektur BCM2835 adalah menganalisis tata letak (memory layout) register secara eksternal.
Fokus utama artikel ini adalah menjawab pertanyaan fundamental terkait pengalamatan memori: “Mengapa register GPSET0 berada tepat pada offset 0x1C? Mengapa tidak berurutan langsung setelah register seleksi fungsi?”
Artikel ini akan menguraikan aritmatika penunjuk memori (memory pointer) yang digunakan dalam driver GPIO.
1. Konsep Alokasi Memori Sekuensial
Memori kontrol GPIO pada arsitektur 32-bit disusun dalam blok-blok berurutan berukuran 4 Byte (32-bit). Alamat dasar (Offset 0x00) ditempati oleh register pertama, dan register berikutnya akan menempati alamat Base + 4, dan seterusnya.
Berdasarkan Datasheet BCM2835 ARM Peripherals, urutan blok memori untuk konfigurasi mode GPIO adalah sebagai berikut:
- GPFSEL0 (Offset
0x00): Mengatur mode GPIO 0 – 9. - GPFSEL1 (Offset
0x04): Mengatur mode GPIO 10 – 19. - GPFSEL2 (Offset
0x08): Mengatur mode GPIO 20 – 29. - GPFSEL3 (Offset
0x0C): Mengatur mode GPIO 30 – 39. - GPFSEL4 (Offset
0x10): Mengatur mode GPIO 40 – 49. - GPFSEL5 (Offset
0x14): Mengatur mode GPIO 50 – 53.
Hingga titik ini (Offset 0x14), sistem telah mengalokasikan 6 blok register (total 24 byte) untuk pengaturan mode fungsi.
2. Blok Memori Cadangan (Reserved Gap)
Jika kita mengikuti logika urutan linier, register berikutnya seharusnya berada di offset 0x18 (yaitu 0x14 + 0x04).
Namun, Broadcom mendesain adanya celah memori (memory gap) pada alamat ini. Alamat offset 0x18 berstatus Reserved (Dicadangkan). Tidak ada register fungsional GPIO yang dipetakan ke alamat ini. Hal ini umumnya berkaitan dengan penyelarasan memori (memory alignment) internal pada desain silikon chip.
Oleh karena itu, pointer memori harus “melompati” blok kosong ini sejauh 4 byte.
3. Lokasi GPSET0: Hasil Penjumlahan Akhir
Setelah melewati blok Reserved di 0x18, register fungsional berikutnya—yaitu GPSET0 (GPIO Pin Output Set 0)—ditempatkan pada offset 0x1C.
Kalkulasinya adalah: 0x18 (Reserved) + 0x04 (Ukuran Blok) = 0x1C.
Berikut adalah tabel peta memori (memory map) yang telah dikoreksi:
| Urutan | Nama Register | Offset (Hex) | Cakupan Kontrol |
| 1 | GPFSEL0 | 0x00 | Mode GPIO 0 – 9 |
| 2 | GPFSEL1 | 0x04 | Mode GPIO 10 – 19 |
| 3 | GPFSEL2 | 0x08 | Mode GPIO 20 – 29 |
| 4 | GPFSEL3 | 0x0C | Mode GPIO 30 – 39 |
| 5 | GPFSEL4 | 0x10 | Mode GPIO 40 – 49 |
| 6 | GPFSEL5 | 0x14 | Mode GPIO 50 – 53 |
| 7 | (Reserved) | 0x18 | JEDA MEMORI (KOSONG) |
| 8 | GPSET0 | 0x1C | Set Output GPIO 0 – 31 |
| 9 | GPSET1 | 0x20 | Set Output GPIO 32 – 53 |
4. Segmentasi Bank: Mengapa GPSET0?
Sistem pada Chip (SoC) BCM2835 memiliki total 54 jalur GPIO. Karena arsitektur register hanya memiliki lebar data 32-bit, satu register tidak dapat menampung tombol kendali untuk seluruh 54 jalur sekaligus.
Oleh karena itu, kendali dibagi menjadi dua segmen atau Bank:
- Bank 0 (GPSET0): Mengendalikan GPIO 0 s.d. GPIO 31.
- Bank 1 (GPSET1): Mengendalikan GPIO 32 s.d. GPIO 53.
Dalam kasus pengendalian LED indikator (ACT LED) pada Raspberry Pi 1, jalur yang digunakan adalah GPIO 16. Karena angka 16 berada dalam rentang 0–31, maka register yang wajib digunakan adalah GPSET0.
5. Implementasi pada Kode C
Pemahaman struktur memori di atas menjadi landasan bagi definisi pointer dalam kode C:
volatile uint32_t* const GPSET0 = (volatile uint32_t*)(GPIO_BASE + 0x1C);
Logika aritmatika di balik baris kode tersebut adalah:
- Start:
GPIO_BASE(0x20200000). - Offset GPFSEL: Melewati 6 register fungsi ($6 \times 4 \text{ byte} = 24 \text{ byte}$ atau
0x18). - Offset Reserved: Melewati 1 blok kosong (4 byte).
- Total Offset:
0x18 + 0x04 = 0x1C.
Dengan demikian, alamat memori mendarat tepat pada 0x2020001C, yang merupakan pintu masuk untuk menyalakan sinyal listrik pada GPIO 0 hingga GPIO 31.
