Skip to main content
Version: v2.4.0 (Current)

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:

ComponentMinimum SpecBenefit
CoreRV32IMAC (e.g., QingKe V4)Fast execution of HMI logic and Lua scripts.
SRAM32KB+ AvailableStores the Artok object registry and draw buffers.
StorageExternal SPI FlashHouses 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.