RISC-V Bare-metal Integration Guide
The Artok HMI Runtime is highly portable and supports the growing RISC-V ecosystem, including the WCH CH32V series and GD32V series. On these platforms, Artok provides a lean, efficient UI solution that operates without the overhead of an operating system.
📦 1. Hardware Requirements
RISC-V cores are known for their efficiency. To ensure the Artok engine performs optimally on bare-metal RISC-V hardware, the following specs are recommended:
| Component | Minimum Spec | Benefit |
|---|---|---|
| Core | RV32IMAC (e.g., QingKe V4) | Fast execution of HMI logic and Lua scripts. |
| SRAM | 32KB+ Available | Stores the Artok object registry and draw buffers. |
| Storage | External SPI Flash | Houses the ui.bin asset bundle. |
🔧 2. Hardware Abstraction (HAL)
In a bare-metal RISC-V environment, you typically interface directly with the vendor's Peripheral Library (e.g., CH32V SDK).
Flash & Display Bridge
#include "atk_runtime.h"
// 1. SPI Flash Read Implementation
uint32_t riscv_flash_read(uint8_t* p_buffer, uint32_t address, uint32_t size) {
// Direct SPI/QSPI call to your Flash driver
SPI_Flash_Read(p_buffer, address, size);
return size;
}
// 2. Display Flush Callback
void riscv_disp_flush(void *p_disp_drv, int32_t x1, int32_t y1, int32_t x2, int32_t y2, void *p_color) {
// Map to your TFT driver (SPI or 8080 Parallel)
LCD_Address_Set(x1, y1, x2, y2);
uint32_t size = (x2 - x1 + 1) * (y2 - y1 + 1);
LCD_Push_Data((uint16_t*)p_color, size);
// Signal transfer complete
ART_FlushComplete();
}
🚀 3. The 4-Tier Initialization Sequence
The boot sequence on RISC-V remains consistent with our tiered architecture. Ensure your clock configuration (HSE/PLL) is stable before calling ART_Init().
HMI_Hardware_Interface_t riscv_hal;
void main(void) {
SystemCoreClockUpdate();
Delay_Init();
// TIER 1: Core System Init
ART_Init();
// Prepare HAL Structure
riscv_hal.read_flash = riscv_flash_read;
riscv_hal.disp_flush_cb = riscv_disp_flush;
riscv_hal.disp_buffer_1 = user_malloc(240 * 10 * 2);
riscv_hal.disp_buffer_size_bytes = 240 * 10 * 2;
riscv_hal.comm_send = uart_send_data;
// TIER 2: Connectivity & Graphics Pipe
ART_InitComm(&riscv_hal, NULL, 0);
ART_InitDisplay(&riscv_hal);
// TIER 3: Input (Optional)
ART_InitInput(&riscv_hal);
// TIER 4: Launch HMI (Binary at Flash address 0x0)
if (ART_StartHMI(0x00000000, &riscv_hal)) {
// HMI is now running
}
while(1) {
ART_MainLoop();
}
}
🎮 4. Interaction API
Control the UI from your RISC-V application using widget UUIDs. This prevents your business logic from breaking if the UI layout is modified in Artok-Vite.
// Example: Update an RPM gauge from an encoder interrupt
void update_tachometer(int32_t rpm) {
atk_api_set_value("UUID_GAUGE_RPM", rpm);
if (rpm > 8000) {
atk_api_set_color("UUID_GAUGE_RPM", 0xFF0000); // Red alert
} else {
atk_api_set_color("UUID_GAUGE_RPM", 0xFFFFFF); // Normal white
}
}
🛡️ 5. RISC-V Deployment Notes
-
Alignment: RISC-V hardware often requires 4-byte alignment for memory access. The Artok Runtime handles this internally for the binary parser, but ensure your disp_buffer_1 is word-aligned.
-
Interrupt Handlers: For smooth touch response, ensure your ART_IncTick(1) is called inside a high-priority timer interrupt (e.g., SysTick or TIM2).
-
Compiler Flags: When compiling for RISC-V, ensure -march and -mabi match your specific core to avoid instruction set mismatches in the static library.