Firmware Integration
Integrating the Artok HMI Runtime into your project requires a bridge between the core engine and your specific hardware peripherals. This is achieved through a standardized Hardware Abstraction Layer (HAL) structure.
🏗️ The 4-Tier Initialization
To ensure the system boots reliably across different architectures (STM32, ESP32, RISC-V), Artok follows a mandatory 4-tier startup sequence. This sequence must be executed after your system clocks and basic peripherals are configured.
1. Core Initialization
Initialize the internal memory pools and the HMI object registry.
ART_Init();
2. Connectivity & Graphics Pipe
Define your communication interface (for Artok Studio synchronization) and your display flush callback.
hmi_hal.read_flash = my_flash_read;
hmi_hal.disp_flush_cb = my_disp_flush;
hmi_hal.comm_send = my_uart_send;
ART_InitComm(&hmi_hal, NULL, 0);
ART_InitDisplay(&hmi_hal);
3. Input Drivers
Initialize the touch screen or keypad interface mapping.
ART_InitInput(&hmi_hal);
4. Engine Launch
Start the HMI by pointing to the memory address of your compiled ui.bin.
ART_StartHMI(0x00200000, &hmi_hal);
🔧 Critical HAL Callbacks
You must implement the following functions in your firmware to allow the runtime to interact with your hardware.
Display Flushing
This function is called by the runtime whenever a screen area needs to be updated. It provides the coordinates and the pixel data (RGB565).
void my_disp_flush(void *drv, int32_t x1, int32_t y1, int32_t x2, int32_t y2, void *color) {
// 1. Set LCD address window (x1, y1 to x2, y2)
// 2. Push 'color' data via SPI/8080/LTDC
// 3. IMPORTANT: Notify the engine when the transfer is finished
ART_FlushComplete();
}
Flash Reading
The engine "pulls" assets (images, fonts) from the external flash as needed. Your implementation should wrap your SPI/QSPI flash read driver.
uint32_t my_flash_read(uint8_t* buf, uint32_t addr, uint32_t size) {
// Read 'size' bytes from 'addr' into 'buf'
return W25Q_Read(buf, addr, size);
}
🔄 The Main Loop (Heartbeat)
The Artok HMI Runtime is non-blocking but requires a consistent heartbeat to process animations, Lua scripts, and touch events.
void main() {
// ... Initialization ...
while (1) {
// Must be called as frequently as possible
ART_MainLoop();
// Your application logic here
maintain_system_safety();
}
}
Note on Timing: You must also provide a 1ms timebase to the engine. Typically, this is done by calling ART_IncTick(1) inside your SysTick interrupt or a high-priority timer ISR.
🛡️ Error Handling
The ART_StartHMI() function returns a boolean value. Always check this result to handle deployment failures gracefully:
-
Returns true: Binary is valid, CRC matches, and the UI is live.
-
Returns false: Binary is missing or corrupted. You should trigger a "Recovery Mode" or notify the user via the Serial console.