Memahami posisi firmware dalam sistem embedded: perbedaan firmware vs software aplikasi, memory map flash dan RAM, proses boot dari reset vector sampai main, alur build menjadi binary, dan praktik memetakan sistem kalian sendiri.

Setelah di episode 1 kita memahami peran dan karir Firmware Engineer, pada episode ini kita membangun fondasi konseptual yang paling penting: di mana firmware hidup dan bagaimana ia dijalankan. Kalian tidak bisa men-debug firmware tanpa tahu peta memori, dan tidak bisa memahami cara kerja bootloader (episode 13) tanpa memahami proses boot.
Bayangkan firmware seperti instruktur olahraga: ia bukan orang yang merancang gedung (hardware) dan bukan orang yang menonton pertandingan (aplikasi pengguna) — ia yang berdiri di lantai, mengendalikan setiap gerakan atlet secara langsung dan menyesuaikan diri dengan kemampuan fisiknya.
Firmware dan software sama-sama program, tapi hidup di dunia berbeda:
| Aspek | Firmware | Software Aplikasi |
|---|---|---|
| Tempat tinggal | Flash MCU (non-volatile) | Disk server/komputer |
| Runtime | Tanpa OS, atau RTOS kecil | OS modern (Linux/Windows) |
| Memori | KB sampai MB | GB ke atas |
| Interaksi | Register, interrupt, timing | Syscall, API, framework |
| Update | Bootloader/OTA, jarang | Package manager, sering |
| Kegagalan | Hang, reboot loop, perangkat mati | Crash, exception yang bisa di-log |
Kata "firm" (keras/tetap) menunjukkan sifatnya: firmware melekat pada perangkat keras tertentu dan jarang berubah. Ia adalah lapisan yang menjembatani hardware dan aplikasi:
Dalam sistem embedded kecil, firmware kadang merangkap semua peran — driver dan aplikasi dalam satu binary. Dalam sistem besar (misal smartphone), firmware hanyalah lapisan paling bawah di bawah OS.
Setiap MCU memetakan seluruh sumber dayanya ke satu ruang alamat 32-bit. Untuk STM32F103 (ARM Cortex-M3):
| Alamat | Isi | Keterangan |
|---|---|---|
0x0800_0000 | Flash | Program + data konstan; non-volatile |
0x2000_0000 | SRAM | Variabel runtime; volatile |
0x4000_0000 | Peripheral registers | GPIO, UART, timer, ADC |
0xE000_0000 | Cortex-M system (NVIC, SysTick) | Internal core |
Perhatikan tiga wilayah utama: flash untuk program, RAM untuk data, dan register peripheral yang mengontrol hardware. Alamat-alamat inilah yang akan kalian baca di datasheet dan tulis lewat kode C. Memory map ditentukan oleh vendor — jangan pernah mengira-ngira, selalu buka memory map section di reference manual.
Saat listrik menyala, apa yang terjadi sebelum main? Rangkaiannya:
0x0800_0000 (nilai stack pointer awal) dan 0x0800_0004 (alamat Reset_Handler).startup_xxx.s): menyalin section .data dari flash ke RAM, mengosongkan section .bss, mengatur clock, lalu memanggil main.; Vector table awal
.word _estack ; 0x08000000: nilai SP saat reset
.word Reset_Handler ; 0x08000004: alamat Reset_Handler
Reset_Handler:
ldr r0, =_sdata
ldr r1, =_edata
ldr r2, =_sidata
copy_data:
cmp r0, r1
bge zero_bss
ldr r3, [r2], #4
str r3, [r0], #4
b copy_data
zero_bss:
... ; nol-kan .bss, lalu call main
bl mainStartup code biasanya dihasilkan otomatis oleh vendor (CMSIS/STM32Cube) atau platform (PlatformIO). Kalian tidak perlu menulisnya dari nol, tapi wajib paham perannya — karena semua alamat yang dibahas di sini menentukan apakah program kalian jalan atau HardFault di detik pertama.
Perjalanan kode C menjadi binary yang di-flash:
main.c --[preprocess]--> main.i --[compile]--> main.o
\--[link]--> firmware.elf
[objcopy]--> firmware.bin / .hex| Tahap | Tool | Output | Fungsi |
|---|---|---|---|
| Preprocess | cpp | main.i | Ekspansi macro, include |
| Compile | gcc -c | main.o | C → assembly/objek mesin |
| Assemble | as | main.o | Assembly → objek |
| Link | ld | firmware.elf | Gabung objek + script linker |
| Convert | objcopy | .bin/.hex | ELF → format flash |
Urutan ini penting karena tiap tahap bisa gagal dengan pesan yang berbeda, dan debugging "kok tidak jalan?" sering berakar di tahap ini. Script linker (linker script) — yang menentukan ke mana tiap section ditaruh — kita bedah tuntas di episode 8.
Sebelum menulis kode, latihan paling berharga adalah memetakan sistem: identifikasi sumber daya dan interaksi produk yang kalian targetkan.
CPU : STM32F103 @ 72 MHz, ARM Cortex-M3
Flash : 64 KB (program) - total 64 KB
RAM : 20 KB SRAM (variabel + stack)
Peripheral : GPIO (LED, button), Timer2 (PWM), UART1 (debug),
I2C1 (sensor), RTC (waktu)
Power : 3.3V USB; target arus idle < 5 mA
Interaksi : button → ubah warna LED via PWM; UART → logIsi kategori yang sama untuk board kalian (Nucleo atau ESP32). Latihan ini memaksa kalian membaca datasheet — kebiasaan paling khas firmware engineer. Peta ini juga menjadi "kontrak" yang menentukan keputusan arsitektur di episode-episode berikutnya.
Tip
Aturan emas firmware: baca reference manual, bukan tutorial. Datasheet memberi angka pasti (alamat, timing, batas) yang tidak bisa ditebak dari blog. Mulai dari bab "Memory map" dan "System overview" untuk papan kalian — 30 menit membaca manual menghemat 3 jam debugging.
const yang salah tempat membuat program membengkak atau RAM penuh.preprocess → compile → link → objcopy menyelamatkan kalian dari error aneh di toolchain.Inti yang harus dibawa pulang:
main.Di episode 3 selanjutnya kita masuk ke senjata utama firmware: C untuk Firmware — pointer yang benar-benar dipakai, memory-mapped I/O, volatile, dan embedded C patterns yang menjadi dasar semua kode di series ini. Pastikan tetap semangat!