Compare commits

...

2 Commits

Author SHA1 Message Date
2d2bd69780 feat(rk3588s): package lvgl demo and display backend 2026-05-23 17:01:44 +08:00
48f64a6858 feat(led): add rk3588 lvgl display backend 2026-05-23 16:01:31 +08:00
5 changed files with 141 additions and 1 deletions

View File

@@ -158,6 +158,22 @@ chmod +x "$INSTALL_DIR/bin/clawd.js"
info "clawd symlinked to /usr/local/bin/clawd"
# Install RK3588S LVGL demo
DEVICE_MODEL="$(tr -d '\0' </proc/device-tree/model 2>/dev/null || true)"
if echo "$DEVICE_MODEL" | grep -qi 'RK3588S'; then
DEMO_SRC="$INSTALL_DIR/lib/resource/3588s/demo"
DEMO_DST="/usr/bin/demo"
if [ -f "$DEMO_SRC" ]; then
info "RK3588S detected, installing LVGL demo to $DEMO_DST"
if [ -f "$DEMO_DST" ] && [ ! -f "${DEMO_DST}.clawd-bak" ]; then
cp "$DEMO_DST" "${DEMO_DST}.clawd-bak"
info "Backup created: ${DEMO_DST}.clawd-bak"
fi
install -m 0755 "$DEMO_SRC" "$DEMO_DST"
else
warn "RK3588S demo binary not found: $DEMO_SRC"
fi
fi
# Write default config files
mkdir -p "$CONFIG_DIR"

View File

@@ -11,7 +11,7 @@ function loadImpl() {
if (forced) {
name = forced;
} else if (isRK3588()) {
name = 'noop';
name = 'rk3588-lvgl';
} else if (isRK3566()) {
name = 'rk3566';
} else {
@@ -23,6 +23,10 @@ function loadImpl() {
log.info('led', `LED/VFD backend → rk3566-openvfd (${model || 'unknown model'})`);
return require('./led/rk3566-openvfd');
}
if (name === 'rk3588-lvgl' || name === '3588' || name === 'rk3588') {
log.info('led', `LED/VFD backend → rk3588-lvgl (${model || 'unknown model'})`);
return require('./led/rk3588-lvgl');
}
if (name === 'noop' || name === 'none' || name === 'off') {
log.info('led', `LED/VFD backend → noop (${model || 'unknown model'})`);
return require('./led/noop');

81
lib/led/rk3588-lvgl.js Normal file
View File

@@ -0,0 +1,81 @@
'use strict';
const fs = require('fs');
const log = require('../logger');
const LVGL_CMD_FIFO = process.env.CLAWD_LVGL_CMD_FIFO || '/tmp/lvgl_cmd';
function writeLvglCommand(command) {
try {
const fd = fs.openSync(LVGL_CMD_FIFO, fs.constants.O_WRONLY | fs.constants.O_NONBLOCK);
fs.writeSync(fd, `${command}\n`);
fs.closeSync(fd);
return true;
} catch (e) {
log.warn('display', `lvgl cmd failed (${command}): ${e.message}`);
return false;
}
}
class BasicLed {
constructor(name) {
this.name = name;
this._current = null;
}
on() { this._current = 'on'; log.debug('led', `[rk3588-lvgl] ${this.name} on`); }
off() { this._current = 'off'; log.debug('led', `[rk3588-lvgl] ${this.name} off`); }
blink() { this._current = 'blink'; log.debug('led', `[rk3588-lvgl] ${this.name} blink`); }
destroy() { this._current = 'off'; log.debug('led', `[rk3588-lvgl] ${this.name} destroy`); }
}
class StatusLed {
setSetup() { log.debug('led', '[rk3588-lvgl] status setup'); }
setApps() { log.debug('led', '[rk3588-lvgl] status apps'); }
off() { log.debug('led', '[rk3588-lvgl] status off'); }
}
class Display {
showAP() {
if (writeLvglCommand('show_text:AP')) {
log.info('display', '显示屏 → AP');
}
}
showConn() {
if (writeLvglCommand('show_text:Conn')) {
log.info('display', '显示屏 → Conn');
}
}
showErr0() {
if (writeLvglCommand('show_text:Err0')) {
log.info('display', '显示屏 → Err0');
}
}
showTime() {
if (writeLvglCommand('show_time')) {
log.info('display', '显示屏 → 时间');
}
}
showPin(pin) {
const s = String(pin || '').padStart(4, '0').slice(-4);
if (writeLvglCommand(`show_text:${s}`)) {
log.info('display', `显示屏 → PIN: ${s}`);
}
}
}
class LanLed {
start() { log.debug('led', '[rk3588-lvgl] LAN start ignored'); }
stop() { log.debug('led', '[rk3588-lvgl] LAN stop ignored'); }
}
const led = new BasicLed('wifi');
led.bt = new BasicLed('bt');
led.status = new StatusLed();
led.display = new Display();
led.lan = new LanLed();
module.exports = led;

View File

@@ -0,0 +1,39 @@
# RK3588S demo resource
This directory contains the LVGL demo binary deployed on RK3588S devices by `install.sh`.
## Files
- `demo` — prebuilt LVGL UI binary installed to `/usr/bin/demo` on RK3588S boards
## Source
Current binary source on the build machine:
- `/home/sts/share/小屏demo开发指南/lvgl源码/lv_port_linux_v2/lv_port_linux/build/bin/demo`
## Purpose
This demo provides the small-screen UI used on RK3588S devices, including FIFO-based control through:
- `/tmp/lvgl_cmd`
Supported commands expected by the current clawd RK3588 LVGL backend include:
- `show_text:AP`
- `show_text:Conn`
- `show_text:Err0`
- `show_text:<PIN>`
- `show_time`
## Install behavior
During `install.sh`, if `/proc/device-tree/model` matches `RK3588S`, clawd will:
1. Back up existing `/usr/bin/demo` to `/usr/bin/demo.clawd-bak` if not already backed up
2. Install this `demo` binary to `/usr/bin/demo`
## Notes
- The binary is hardware-specific and intended for RK3588S boards.
- Replacing the binary should be done together with verification of `/tmp/lvgl_cmd` behavior and screen rendering.

BIN
lib/resource/3588s/demo Executable file

Binary file not shown.