Menulis firmware yang boleh dipercaya untuk menggerakkan mesin dan menyelamatkan nyawa: memahami MISRA C sebagai bahasa yang dijinakkan, prinsip functional safety dengan fail-safe design, dan praktik safety review pada kode nyata

Sejauh ini kalian membangun firmware yang bekerja dan aman dari serangan. Episode ini menaikkan standar sekali lagi: firmware yang boleh dipercaya untuk sistem yang bisa membahayakan manusia — rem ABS, pengendali mesin, alat bantu pernapasan. Dalam sistem seperti ini, bug bukan kehilangan data; bug bisa berarti kehilangan nyawa.
Dunia safety memakai bahasa dan disiplin yang berbeda: MISRA C (standar penulisan C yang meminimalkan kesalahan), functional safety (analisis kegagalan sistematis), dan fail-safe design (perilaku saat terjadi kesalahan). Episode ini membangun fondasi untuk membaca, menulis, dan men-review kode dengan lensa safety.
C adalah bahasa yang kuat dan berbahaya — mudah menulis kode ambigu yang kompilernya "terima" tapi perilakunya tidak pasti. MISRA C (Motor Industry Software Reliability Association) adalah seperangkat aturan yang melarang konstruksi berisiko itu, sehingga kode menjadi lebih mudah dianalisis dan lebih sedikit kemungkinan salah.
| Kategori | Contoh aturan MISRA | Alasan |
|---|---|---|
| Undefined behavior | Jangan mengubah variable lebih dari sekali dalam satu ekspresi | Perilaku C tidak pasti |
| Tipe & cast | Jangan cast pointer ke tipe lain secara implisit | Mencegah bug layout |
| Integer | Aturan ketat tentang signed/unsigned | Perangkap perbandingan |
| Control flow | Batasi goto; struktur harus jelas | Kode bisa dianalisis |
| Kualitas | Semua identitas harus unik dan jelas | Mudah di-review |
Aturan-aturan ini dijalankan oleh static analyzer (misal Coverity, Cppcheck, atau tool vendor) dan di-review manusia. Contoh nyata perbedaan gaya:
/* Sebelum — berisiko: tipe tidak eksplisit, perbandingan campur signed/unsigned */
int i;
for (i = 0; i < sizeof(buf); i++) { /* sizeof mengembalikan size_t (unsigned) */
process(buf[i]);
}
/* Sesudah — MISRA-friendly: tipe konsisten, loop eksplisit */
uint32_t i;
for (i = 0u; i < (uint32_t)sizeof(buf); i++) {
process(buf[i]);
}Perbedaan int vs size_t terdengar sepele, tapi di C yang undefined behavior-nya "bisa apa saja", penanganan tipe yang teliti adalah fondasi safety. Kalian juga akan melihat idiom MISRA seperti literal bertanda u (0u, 1u) di semua kode yang kita tulis sepanjang series ini — sekarang kalian tahu alasannya.
Functional safety bukan "kode harus benar", melainkan: jika gagal, kegagalannya harus diketahui dan ditangani. Pendekatan kuncinya adalah analisis sistematis:
Contoh mitigasi praktis yang sering terlihat di firmware safety:
| Kegagalan | Deteksi | Respons |
|---|---|---|
| CPU hang | Watchdog timer | Reset + fail-safe state |
| Nilai sensor liar | Range check + sanity check | Pakai nilai default aman |
| RAM korup | RAM test berkala (MBIST) | Restart / tanda error |
| Flash berubah | CRC/checksum berkala | Perbaiki dari golden copy |
| Dua core tidak sinkron | Cross-check & voting | Fallback ke mode aman |
Pola pentingnya: sistem safety tidak pernah percaya buta — ia terus-menerus memverifikasi dirinya sendiri. Redundansi dan verifikasi adalah bahasa kesehariannya.
Prinsip paling kuat dalam safety: saat ragu, perangkat harus jatuh ke kondisi paling aman. Untuk mesin, itu berarti berhenti. Untuk alat pernapasan, itu berarti tetap menyalurkan udara. Aturannya: "default" sistem bukan "bekerja seperti biasa", melainkan "keadaan aman yang jelas".
/* Contoh: kontrol valve dengan fail-safe */
typedef enum { VALVE_CLOSED, VALVE_OPEN, VALVE_FAULT } valve_state_t;
void watchdog_timeout(void) {
/* Mesin tidak merespons -> tutup valve (state aman) */
set_valve(VALVE_CLOSED);
enter_fault_state();
}
valve_state_t read_valve_cmd(void) {
uint32_t raw = read_cmd_register();
/* Validasi: nilai di luar range yang dikenal = korup = jangan percaya */
if (raw > VALVE_OPEN) {
set_valve(VALVE_CLOSED);
return VALVE_FAULT;
}
return (valve_state_t)raw;
}Perhatikan dua pola: jika ragu, jangan percaya input (validasi), dan jika salah, pilih kondisi aman (tutup valve). Kombinasi validasi input + safe default adalah tulang punggung fail-safe design.
Important
Perbedaan mindset terbesar antara engineer biasa dan engineer safety: engineer biasa menanyakan "apakah kode ini benar?", engineer safety menanyakan "apa yang terjadi jika kode ini salah — dan apakah sistem tetap aman?" Keduanya penting, tapi pertanyaan kedua yang menyelamatkan nyawa. Mulailah menanyakan pertanyaan kedua pada setiap fungsi yang kalian tulis.
Safety review adalah praktik review kode yang difokuskan pada kegagalan. Pertanyaan yang selalu ditanyakan:
Contoh temuan review yang umum: fungsi yang menelan error dengan return; tanpa fallback; watchdog yang di-feed di satu tempat padahal satu task hung; state machine yang tidak punya transisi ke state fault. Semua ini adalah akumulasi kecil yang dalam situasi kritis menjadi besar.
Note
Safety bukan teknologi, melainkan budaya dan proses. Cukup menambahkan analyzer tanpa mengubah cara tim menulis, men-review, dan mendokumentasikan tidak akan membuat sistem aman. Prosesnya: standar → analisis → review → pengujian → dokumentasi — diulang terus. Di episode 20 kalian akan melihat bagaimana proses ini dirangkai menjadi sertifikasi resmi.
cppcheck --enable=all --misra-c=2012 module.c dan baca hasilnya.Inti yang harus dibawa pulang:
Di episode 20 selanjutnya kita mewujudkan semua proses ini menjadi dokumen dan sertifikat: compliance & certification — IEC 61508, ISO 26262 untuk otomotif, dan CE/FCC untuk pemasaran produk. Sertifikat inilah yang membuat produk kalian legal dan dipercaya di pasar global. Sampai jumpa di episode 20!