Docs menu

Exported Firmware

ForgeUI Runtime SDK

Connect firmware to ForgeUI widgets through generated APIs, searchable component help and genuine user-action hooks above raw LVGL.

SDK & Widget Hookup

ForgeUI does not stop at design. Hosted Studio includes searchable, widget-specific Help for component properties, generated APIs, firmware hookup and I/O guidance. The exact generated headers remain authoritative for each exported project.

Search any documented component for its properties, generated API, firmware hookup and I/O guidance.
text
sensor / GPIO / ADC / CAN / UART / application state
  → user firmware
  → generated ForgeUI API
  → widget

user touch
  → generated FG_On_*
  → developer application logic
c
float rpm = read_motor_rpm();
FG_Set_Premium_Rpm_Value(rpm);

A generated interface above raw LVGL

Every exported ForgeUI interface exposes a generated, interface-specific programming surface above its private native LVGL implementation. Application code calls the public declarations exposed through 90_Studio_Export.h, including feature-gated 96_FiRuntime presentation APIs, and implements genuine-user hooks declared in 95_UserEvents.h.

The physical hardware boundary

text
PHYSICAL HARDWARE
  → developer-owned code
  → generated Runtime SDK
  → ForgeUI UI

FORGEUI UI
  → genuine generated UserEvent
  → developer-owned code
  → PHYSICAL HARDWARE

Hardware Example 01 proves both directions. Developer-owned GPIO code reads GPIO2 and GPIO4 and calls FG_Set_Indicator1(bool) and FG_Set_Indicator2(bool). Genuine touchscreen UserEvents FG_On_LED1_Toggle_Changed(bool) and FG_On_LED2_Toggle_Changed(bool) delegate to developer-owned code that drives GPIO3 and GPIO5.

Generated Fi Runtime separation

LayerResponsibility
90Generated native LVGL object creation, initial presentation, runtime binding and optional click event adapter.
95Developer-owned input hooks and application I/O; optional Fi click hooks live here.
96Generated Fi visibility, opacity and colour APIs with retained per-instance state.
c
FG_Set_Living_Room_AirPlay_Color(0xF2A900);
FG_Set_Living_Room_AirPlay_Opacity(220);
FG_Set_Living_Room_AirPlay_Visible(true);

void FG_On_Living_Room_AirPlay_Clicked(void)
{
    /* Developer I/O or application logic. */
}

Public setters and commands

Public symbols use the FG_ prefix. Exact names depend on the component name used in Studio after C-identifier sanitization; duplicate names receive deterministic _2, _3 and later suffixes so multiple instances retain independent state.

c
void FG_Set_Status_LED(bool enabled);
void FG_Set_Progress_Bar(int32_t value);
void FG_Set_Spinbox_Value(int32_t value);
void FG_Set_Tab_View_Selected(uint32_t index);

Generated setters normalize or clamp their inputs, guard unavailable objects and remain silent: construction, hydration and programmatic setter calls do not invoke UserEvent hooks. Repeated effective values are suppressed where the widget contract requires it.

From standard widgets to Native Components

Native Component APIs expose application meaning while labels, bars, switches and containers remain private. Names derive from stable component identity, and duplicate instances receive collision-safe namespaces. Live Studio and Standalone Export share this generator.

c
FG_Set_Status_LED(true);
FG_Set_Progress_Bar(75);
FG_Set_Engine_RPM_Value(1825.0f);
FG_Set_Engine_RPM_Status("Normal", 0x22C55E);
FG_Set_Main_Relays_Channel(0, true);
FG_Set_Main_Relays_All(false);

Native Component SDK coverage

All 14 current Native Components generate identity-scoped semantic APIs through the same Live Studio and Standalone composition path. Angle-bracket names below are placeholders; the exact current 90_Studio_Export.h remains authoritative.

c
FG_Set_<DashboardCard>_Value("72");
FG_Set_<SensorTile>_Value(1825.0f);
FG_Set_<RelayPanel>_Channel(0, true);
FG_Set_<PWMController>_Value(75.0f);
FG_Add_<TrendChart>_Point(1825.0f);
FG_Add_<TrendChartPro>_Point(1825.0f);
FG_Add_<AlarmPanel>_Alarm(alarm_id, message, timestamp, priority, state);
FG_Set_<IOMonitor>_DigitalInput("DI1", true);
FG_Set_<BatteryCard>_Percentage(82.0f);
FG_Set_<TankLevelCard>_Level(72.0f);
FG_Set_<NetworkStatusCard>_Connected(true);
FG_Set_<DeviceSummaryCard>_Status(1);
FG_Set_<KPICard>_Value("87.4");
FG_Set_<PowerFlowCard>_Grid_Value("1.8 kW");
  • Semantic APIs keep private LVGL composition private.
  • Setters are silent, bounded and identity-scoped.
  • Persisted IDs keep generated symbols stable through display-name changes.
  • Duplicate instances receive isolated symbols and fixed per-instance storage.
  • Monitoring-only components generate zero UserEvents.
  • Live Studio and Standalone Export share the normalized project hardware profile and generated contract.

UserEvent callback hooks

Interactive widgets route genuine LVGL interaction through generated FG_On_* declarations. The generated transition layer updates retained state first and emits exactly one callback per effective user action; setter-generated LVGL events are guarded from crossing into developer code.

c
void FG_On_Spinbox_Changed(int32_t value);
void FG_On_Tab_View_Changed(uint32_t tab_index);

Widget-specific API availability

Widget capabilityGenerated SDK surface
Interactive semantic stateSilent setter plus genuine-user hook
Output semantic stateSetter or command only
Serialized presentationNo runtime API unless the Registry defines meaningful runtime state
No semantic runtime stateNo public API

Generation is feature-gated: only APIs, public types, sources, dependencies and feature defines required by the serialized interface are emitted. The Widget Registry is authoritative for whether each widget supports a Runtime API, UserEvents, children or interaction.

Values, text and lifetime

Spinbox values are integer-backed int32_t values; configured decimal places affect display rather than changing the public value to floating point. Text APIs use const char * where applicable. Treat text passed into a generated setter or received by a callback as call-scoped unless that widget's generated contract explicitly documents retained ownership; copy it into developer-owned storage when it must outlive the call.

Generated and developer-owned boundaries

AreaOwnership
90_Studio_Export.c / .hGenerated and replaceable native LVGL, retained state and public Runtime SDK
Live 95_UserEvents.c / .hMatching developer callback bodies survive; declarations, definitions and call sites reconcile to the current project contract; stale deleted-component callbacks are removed
Standalone 95_UserEvents.c / .hDeveloper-owned application integration after export
Developer modulesProduct logic, drivers, tasks, services and long-lived state

Live Studio and Standalone parity

Live Studio firmware and Standalone Export consume the same generated native LVGL and Runtime SDK architecture. Board Profiles own target identity, dimensions and hardware capabilities; 00_ForgeUI_Features.h and generated CMake selections keep each export aligned with its selected hardware and widget requirements.

Proof status and future direction

Spinbox is physically proven through the complete Registry-to-hardware pipeline, including multiple instances, collision-safe names, silent setters and one callback per effective physical edit. TabView user I/O is also physically proven on the ESP32-P4 reference target: genuine touch selection emitted the expected FG_On_Tab_View_Changed callbacks across tab indices 0, 1 and 2 while Wi-Fi remained connected and SD storage remained ready.

The SDK direction is a searchable, widget-by-widget capability reference tied to Registry metadata, Board Profiles and physical evidence. It does not currently promise a universal binary-compatible SDK, remote device management or device-side reflection.