Dokumentasi

Core Runtime

Pahami model eksekusinya sebelum menyalakan modul apa pun: cadence task, due check, event routing, watchdog, panic flow, dan batas model cooperative.

Kenapa halaman ini penting

Halaman ini menjelaskan bagaimana Core Runtime masuk ke model eksekusi ZeroKernel yang lebih besar, masalah apa yang sebenarnya diselesaikan, dan trade-off apa yang benar-benar Anda bayar saat fitur ini dipakai di firmware produksi. Tujuannya bukan melihat Core Runtime sebagai satu API terpisah, tetapi memahami posisinya di dalam bounded scheduling, disiplin queue, visibilitas fault, dan pemilihan profile.

Baca topik ini sebagai kontrak operasional. Mulai dari jalur paling kecil yang benar-benar jalan, pasang dulu di profile lean, lalu baru naik ke routing, diagnostics, atau state transport yang lebih kaya setelah Anda bisa membuktikan hasil timing-nya tetap layak dibanding tambahan flash dan RAM. Pola pikir ini yang menjaga ZeroKernel tetap berguna di board kecil dan tidak berubah jadi abstraksi yang gemuk.

Pola paling aman selalu sama: tentukan batas runtime-nya, jaga hot path tetap pendek, ukur efeknya dengan compare script, lalu baru naikkan kompleksitas. Contoh di bawah bukan pemanis; itu adalah pola minimum yang bisa Anda ambil ke firmware nyata saat Anda butuh integrasi yang rapi, bukan loop manual yang sulit dipertahankan.

Tiga pola yang langsung bisa dipakai

Pola cadence inti

Pakai satu task bounded untuk hot path, lalu biarkan scheduler menjaga phase alignment seiring waktu.

C++
    ZeroKernel.begin(boardMillis);
ZeroKernel.addTask("Fast", fastTask, 10, 0, true);
ZeroKernel.tick();
  
Pola deferred work

Pindahkan routing dan transport non-kritikal dari body task utama agar fast path tetap terprediksi.

C++
    const auto key = ZeroKernel.makeTopicKey("telemetry.sample");
ZeroKernel.publishDeferredFast(key, sampleValue);
ZeroKernel.flushEvents();
  
Pola visibilitas runtime

Baca timing report dan stats bersamaan agar Anda bisa membuktikan biaya tiap lapisan abstraksi.

C++
    const auto stats = ZeroKernel.getStats();
const auto timing = ZeroKernel.getTimingReport();
Serial.println(timing.maxTickMs);
  

Apa yang perlu Anda cek saat memakainya

  • Validasi timing lebih dulu, baru bentuk API. API yang terlihat rapi bukan kemenangan kalau fast miss justru naik.
  • Pilih profile paling kecil yang masih cocok, lalu aktifkan modul opsional hanya saat payoff terukurnya benar-benar jelas.
  • Jaga callback dan langkah transport tetap bounded supaya watchdog, panic flow, dan batas queue tetap punya arti.

Kesalahan umum yang membuat hasil jadi menyesatkan

  • Jangan menyalin pola demo ke firmware produksi tanpa mengukurnya di board dan profile build yang benar-benar akan dipakai.
  • Jangan membaca angka sukses tanpa membaca queue depth, timing, dan label workload di sampingnya.
  • Jangan menyalakan diagnostics atau kompatibilitas berat di target lean hanya karena default-nya terasa nyaman.

Urutan kerja yang disarankan

Mulai dari jalur paling kecil yang valid

Boot runtime, daftar task minimum yang berguna, lalu buktikan baseline timing bersih sebelum menambah lapisan opsional.

Tambah satu lapisan, lalu ukur

Masukkan routing, diagnostics, atau transport satu lapisan demi satu agar biaya dan payoff-nya tetap jelas.

Publikasikan hanya hasil yang bisa diulang

Update docs, chart, atau klaim publik hanya setelah workload yang sama lolos jalur validasi yang sama lebih dari sekali.

Apa yang benar-benar dipegang core runtime

Core runtime adalah lapisan yang menentukan kapan pekerjaan boleh jalan, berapa banyak deferred work yang boleh dikuras dalam satu putaran scheduler, dan seberapa cepat fault berubah dari “diam” menjadi terlihat. Ini bukan framework transport, bukan abstraksi sensor, dan bukan pengganti desain firmware yang disiplin. Ini adalah lapisan eksekusi bounded yang membuat bagian-bagian di atasnya lebih konsisten.

Secara praktis, runtime inti memegang lima hal: cadence task, disiplin queue, visibilitas fault, kernel state, dan batas konfigurasi global. Begitu lima hal ini dipahami, sisa fitur ZeroKernel akan terasa lebih mudah karena semuanya kembali ke fondasi yang sama.

Pola pikir yang benar adalah menganggap core runtime sebagai lapisan kecil dan terprediksi. Ia membantu mengatur eksekusi, tetapi tidak akan diam-diam memperbaiki driver blocking, memutus socket yang macet, atau mengubah model cooperative menjadi RTOS preemptive.

Model scheduler dan pemilihan task due

ZeroKernel bersifat cooperative dan phase-aligned. Task menjadi eligible saat interval-nya due, lalu scheduler memilih satu task due, menjalankannya, dan mengembalikan kontrol ke loop utama. Bila masih ada pekerjaan lain, ia akan ditangani pada panggilan tick() berikutnya, bukan lewat loop tersembunyi yang menjalankan semuanya sekaligus.

Priority hanya mempengaruhi tie-break antar task yang sama-sama due. Priority tidak menciptakan preemption. Artinya task prioritas tinggi bisa dipilih lebih dulu, tetapi tidak bisa menyela task prioritas rendah yang sudah sedang berjalan. Karena itu callback tetap harus bounded.

PerilakuArtinya di firmware
CooperativeTask selesai lalu mengembalikan kontrol; tidak ada interrupt paksa dari scheduler.
Phase-alignedTask periodik tetap nempel ke jadwalnya dan tidak drift terus-menerus setelah satu run lambat.
Priority-awareSaat beberapa task due bersamaan, scheduler memilih yang paling penting lebih dulu.
Bounded drainPekerjaan deferred dikuras sedikit-sedikit, bukan menjadi loop tak terbatas.

Lapisan safety runtime

Model safety ZeroKernel bukan sekadar satu toggle watchdog. Ia terdiri dari beberapa lapisan yang saling melengkapi: execution contract mendefinisikan perilaku yang diterima, watchdog memantau heartbeat dan overrun, kernel state menyimpan status eskalasi, dan capability gating memungkinkan runtime menghentikan kelas pekerjaan tertentu tanpa harus membuang registrasi task.

Model berlapis ini penting karena recovery di firmware nyata jarang bersifat biner. Sistem yang sehat seharusnya bisa masuk degraded mode, mematikan pekerjaan non-kritikal, mempertahankan sensing atau control loop yang penting, lalu hanya masuk panic saat sistem memang sudah tidak bisa melanjutkan progress yang aman.

LapisanFungsi
WatchdogMemantau heartbeat dan execution window, lalu melakukan eskalasi ke degraded, safe mode, atau panic.
Execution contractMendeklarasikan pentingnya task, perilaku run, dan ambang eskalasi.
Kernel stateStatus formal seperti NORMAL, DEGRADED, SAFE_MODE, RECOVERY, dan PANIC.
CapabilitiesMenggating kelas pekerjaan tanpa harus menghapus registrasi task.
TelemetryMembuka timing, queue pressure, dan failure counter agar compare tetap jujur.

Tiga pola boot runtime yang sering dipakai

C++
    ZeroKernel.begin(boardMillis);
ZeroKernel.tick();
  

Ini bentuk boot runtime paling minimum. Cocok untuk bring-up saat Anda hanya ingin memastikan runtime hidup dan clock board sudah tersambung benar.

C++
    ZeroKernel.begin(boardMillis);
ZeroKernel.addTask("Sample", sampleTask, 100, 0, true);
ZeroKernel.setTaskPriority("Sample", zerokernel::kPriorityHigh);
ZeroKernel.tick();
  

Ini bentuk awal firmware yang paling umum: satu task, cadence eksplisit, priority eksplisit, dan loop utama yang tetap bersih.

C++
    ZeroKernel.begin(boardMillis);
ZeroKernel.setIdleStrategy(zerokernel::kIdleYield);
ZeroKernel.setSignalHandler(onKernelSignal);
ZeroKernel.tick();
  

Ini cocok untuk bring-up dan diagnostics saat Anda butuh visibilitas runtime tanpa harus menyalakan profile debug yang terlalu berat.

Batas yang harus dihormati

Model cooperative punya batas yang jelas: callback blocking tetap bisa menahan loop. ZeroKernel membuat dampaknya lebih terukur dan lebih mudah direspons, tetapi tidak akan mem-preempt pekerjaan yang memang sudah telanjur blocking.

Runtime juga tidak menggantikan disiplin transport. Jika HTTP, MQTT, atau WiFi menjadi berat, pekerjaan itu seharusnya dipindahkan ke deferred queue atau modul network opsional, bukan ditaruh di hot path yang sama dengan task sampling cepat.

  • Jangan menaruh transaksi blocking panjang langsung di task tercepat.
  • Pakai deferred work atau modul network saat sensing mulai bercampur dengan transport.
  • Baca timing metrics bersama queue depth; satu angka saja hampir selalu menyesatkan.

FAQ core runtime

Apakah priority membuat ini jadi preemptive?

Tidak. Priority hanya mempengaruhi pemilihan task di antara task yang sudah due. Begitu callback berjalan, ia tetap memegang CPU sampai selesai.

Apakah ZeroKernel otomatis memperbaiki driver blocking?

Tidak. ZeroKernel membuat runtime lebih disiplin dan bisa mendeteksi overrun, tetapi aplikasi tetap harus menjaga driver dan jalur I/O tetap bounded.

Kapan saya boleh menyalahkan runtime, bukan task code saya?

Saat Anda sudah membuktikan task body bounded, transport sudah dipisah, dan compare script tetap menunjukkan regression. Dalam banyak kasus, masalah yang terlihat seperti scheduler justru berasal dari desain hot path aplikasi.