kodeOS internals
Overview
How kodeOS works inside: its boot, console, screens, tests and releases. For people working on kodeOS itself, not for writing an app.
What it is
This section is the inside of kodeOS: how it boots, the console and its commands, how each screen is built, its memory, tests and releases. It is for people who work on kodeOS itself or want to know how it is made. To learn what kodeOS is and how to use it, read ecosystem/kodeos. To write an app, start at build/setup: none of this is needed for that.
kodeOS is the firmware a Kode Dot runs when you switch it on. It draws the face with the clock, lists the installed apps, shows the settings, rests the board when nobody uses it, runs entries on a clock, answers text commands from a computer and installs and starts apps. It is the one firmware every Kode Dot ships with.
kodeOS is built from the SDK (sdk/overview) the same way your app is. Its main/main.c is two calls. kode_init() starts the drivers, the Active Objects that own every chip and the console. kgui_start() starts the screens. The SDK supplies everything those calls start. The screens, the bootloader override and the way the flash is used live in the kodeOS repository, kodediy/KodeOS.
An app is a whole firmware. kodeOS writes the app's .bin into a region of the flash and the bootloader starts it in place. While it runs, kodeOS does not. Any reset brings the board back to kodeOS, because the app never writes the record that says which kodeOS slot starts. The one exception is a sketch uploaded from the Arduino IDE, which restarts after the resets its own host causes (internals/boot-model).
To build an app, start at build/setup, build/first-build and build/flash. To build kodeOS itself, read internals/building-and-flashing.
How it is connected
flowchart LR person["buttons and touch"] --> kgui["kgui_start(): face, Apps, Settings"] host["computer: USB-C, Bluetooth, charging base"] --> console["AO_Console"] main["main/main.c"] --> init["kode_init()"] main --> kgui init --> console init --> owners["owner Active Objects"] kgui --> owners console --> owners bl["bootloader override"] --> app["app in the apps region"] class person,host ext class console,owners ao class app app class bl chip
A person reaches kodeOS through the screen and the six buttons under it.
A computer reaches it through the console, a text command line. The console runs on:
- the USB-C cable (the native USB-Serial/JTAG port);
- Bluetooth;
- with
CONFIG_KHAL_CONSOLE_DOCK=y, the magnetic pads of the charging base.
A computer can also write the flash directly with esptool.
Every chip has one owner, an Active Object. The screens, the console and your own code ask the owner by event and never touch the chip. sdk/kaos/overview has the owners and sdk/design-rules the reason.
The flash holds three copies of kodeOS (factory, ota_0, ota_1), the apps region, the app_pending mailbox and a 2 MB FAT volume (internals/boot-model has the table). The bootloader is the standard ESP-IDF one plus a few steps of kodeOS's own that start an app when a boot request names one.
Opening the console port reboots the board. The USB-Serial/JTAG peripheral resets the P4 on attach, so a script that needs a Wi-Fi join or an MQTT session does the whole sequence inside one open session.
Specifications
| Thing | Value |
|---|---|
| Chip | ESP32-P4, two RISC-V cores at 400 MHz (CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_400) |
| Memory | 640 KB of internal RAM, 32 MB of HEX PSRAM at 250 MHz (internals/memory-budget) |
| Flash | 32 MB NOR; the cache maps 32-bit addresses |
| Radio | ESP32-C5 coprocessor over SDIO, with its own firmware |
| Toolchain | ESP-IDF v6.1 |
| Framework | QP/C 8.1.4 (Active Objects), LVGL 9.6.0 (screens) |
| Entry point | main/main.c: kode_init(), then kgui_start() |
| Firmware role | CONFIG_KODEOS_BOOT_ROLE_OS=y in kodeOS; an app defaults to _APP, which never writes otadata |
| Ways in | The screen and buttons, the console, the flash |
| Ways to install an app | The launcher from a .bin, install over the console, the app_pending mailbox |
The parts
Every page of the kodeOS section, in sidebar order, in groups.
How kodeOS starts and what it holds
| Page | What it covers |
|---|---|
internals/overview | This page: what kodeOS is and a map of the section |
internals/boot-model | Which firmware starts after a reset: the partition table, otadata, the boot request and the bootloader override |
internals/apps-region | Where installed apps live in the flash, the mailbox, and the app data folder |
internals/memory-budget | Who uses the 640 KB of internal RAM, and how a build and a board are checked |
internals/power-and-sleep | The four levels of rest (awake, asleep, off, ship mode), what wakes the board, and why a cable keeps it up |
internals/settings | Every stored setting, its owner, values and default, and the config verb |
Apps
| Page | What it covers |
|---|---|
internals/apps-and-examples | What an app is, the fifteen SDK examples and how a project is set up |
internals/arduino | Running a sketch from the Arduino IDE as an app |
internals/app-icon | Giving an installed app an icon, a colour, a name and a version |
The console
| Page | What it covers |
|---|---|
internals/console-protocol | The wire format of a command, its records and the log lines |
internals/command-set | Every console verb and its records |
internals/ble-console | The console over Bluetooth |
internals/dock-console | The console on the charging base |
internals/kode-channel | The MQTT channel kodeOS joins by itself when it has Wi-Fi, and the commands it holds while the board is away |
internals/variables-and-functions | Console variables and functions of your own, declared in an app |
internals/mirror | Watching and driving the glass from a computer |
The screens
| Page | What it covers |
|---|---|
internals/gui/overview | The screens of kodeOS and how kgui draws them |
internals/gui/face | The face: the clock, the date, Kody, the doors to Apps and Settings, and Rest |
internals/gui/launcher | Apps: the rail of folders and apps, the details of an app and Remove |
internals/gui/settings-screen | The control centre and the Settings rail of pages |
internals/gui/sheets | The full-glass cards and pages: the system cards (write screen, Turn off, pairing and the rest), the keypad and the details |
internals/gui/kody-pack | The animation pack Kody plays and how to install one |
internals/gui/buttons-and-gestures | What every button and swipe does on every screen |
Building, testing and releasing
| Page | What it covers |
|---|---|
internals/building-and-flashing | Building kodeOS and writing it to a board |
internals/bench-tools | kcli.py, kble.py and the other host programs that talk to the board |
internals/host-tests | The tests that run on a computer with no board |
internals/test-pipeline | The checks each repository runs before a merge |
internals/release-pipeline | How a release is built, checked and published |
internals/production-test | The test verb and the hardware rows run on every unit |
In the SDK
main/main.c: the two calls that start kodeOS.components/kgui: the screens, above the SDK.components/kode: the facade whosekode_init()starts the system.