2026-06-16 15:17:41 +08:00
2026-06-16 08:44:45 +08:00
2026-06-16 08:44:45 +08:00
2026-06-16 10:00:35 +08:00
2026-06-16 08:44:45 +08:00
2026-06-16 08:44:45 +08:00
2026-06-16 08:44:45 +08:00
2026-06-16 08:44:45 +08:00
2026-06-16 08:44:45 +08:00
2026-06-16 08:44:45 +08:00
2026-06-16 08:44:45 +08:00
2026-06-16 08:44:45 +08:00
2026-06-16 10:00:35 +08:00
2026-06-16 15:17:41 +08:00

mini_desktop — GEC6818 桌面系统

粤嵌 GEC6818ARM Cortex-A53 armv7l, Linux 3.4.39-gec 嵌入式桌面系统。800×480 LCD 触摸屏,集成电子相册、红外遥控和游戏启动器。

功能

桌面 ── 图库     (触摸滑动 / 遥控翻页浏览照片)
    ├─ 游戏     3D 光线投射游戏)
    └─ 红外     (学习 / 发送 / 接收红外遥控码)
            └─ 后台接收 → 遥控桌面导航
  • 桌面3 个圆角图标(图库、游戏、红外),支持触摸点击和遥控框选
  • 图库BMP 照片浏览,触摸左右滑动或遥控翻页,上键/点顶栏退出
  • 游戏:通过 system() 启动外部 raycast_game_static,退出后 fb_reset 恢复
  • 红外5 键学习(上下左右中),发送/接收页面,后台常驻识别遥控码
  • 遥控导航:左右键移动白色选框,中键进入应用

硬件

项目 详情
开发板 粤嵌 GEC6818
主控 Samsung S5P6818, ARM Cortex-A53, armv7l
系统 Linux 3.4.39-gec, BusyBox
屏幕 800×480 LCD, 32bpp framebuffer (/dev/fb0)
触摸 gslX680, 1024×600 raw → 800×480 校准 (/dev/input/event0)
红外 YS-IRTM 红外模块,串口 /dev/ttySAC1, 9600 8N1, 模块自动去 A1F1 头,输出 3 字节用户码
蜂鸣器 /sys/kernel/gec_ctrl/beep4 字节小端 int 写入shell echo 会写入 0\n 误解析为非零值)
LED /sys/class/leds/ledN/brightness1 字节 ASCII '0'/'1' 写入)

项目结构

mini_desktop/
├── main.c                  # 入口
├── Makefile
├── common/                 # 硬件抽象层
│   ├── device.c/.h         # framebuffer / 触摸 / BMP / 字体 / 蜂鸣器 / LED
│   ├── param.h             # 屏幕参数、触摸校准
│   └── tools.c/.h
├── button/                 # 按钮系统
│   └── button.c/.h         # 圆角矩形、文字标签、BMP 背景、绿色已学标记
├── album/                  # 电子相册
│   └── album.c/.h
├── ir_app/                 # 红外功能
│   └── ir_app.c/.h         # 学习 / 发送 / 接收 / 后台遥控
├── desktop/                # 桌面
│   └── desktop.c/.h        # 图标布局、触摸分发、遥控导航
├── fonts/
│   └── font_16x16.h        # 16×16 等宽字模A-Z + 0-9, Monaco 14pt 生成)
├── images/                 # 相册照片800×480 BMP
├── icon/                   # 桌面图标 + 背景BMP
└── test/                   # 分步测试

板子初始化

首次拿到板子或烧录系统后,需要配置网络和 SSH。

固定 IP

编辑 /etc/profile,在末尾添加:

ifconfig eth0 up
ifconfig eth0 192.168.1.88 netmask 255.255.255.0
route add default gw 192.168.1.1

重启或执行 source /etc/profile 生效。注意板子 IP 需要和电脑在同一网段。

启用 eth0

如果 ifconfig 看不到 eth0检查网线是否插好、交换机/路由器是否通电:

# 查看所有网口
ifconfig -a

# 手动启用
ifconfig eth0 up

某些镜像的 eth0 默认是 down 状态,加到 /etc/profile 里开机自动启用即可。

安装 SSHdropbear

板子默认可能没有 SSH 服务。检查:

ls /usr/sbin/dropbear   # dropbear 服务端
ls /usr/bin/dbclient    # dropbear 客户端SSH 登录用)

如果缺失,从交叉编译工具链或同型号板子拷贝:

# 在能 SSH 的板子上导出
scp /usr/sbin/dropbear /usr/bin/dbclient root@<目标IP>:/tmp/

# 在目标板子上
cp /tmp/dropbear  /usr/sbin/dropbear
cp /tmp/dbclient  /usr/bin/dbclient
chmod +x /usr/sbin/dropbear /usr/bin/dbclient

创建 host key 并启动:

mkdir -p /etc/dropbear
dropbearkey -t rsa -f /etc/dropbear/dropbear_rsa_host_key
dropbearkey -t dss -f /etc/dropbear/dropbear_dss_host_key
dropbear -p 22

确认启动:

ps | grep dropbear

设置开机自启(加到 /etc/profile 末尾):

dropbear -p 22 &

之后即可从电脑 SSH 登录:ssh root@192.168.1.88

编译

docker run --platform linux/amd64 --rm \
  -v /path/to/toolchain:/opt/gec6818-toolchain:ro \
  -v /path/to/mini_desktop:/work -w /work \
  gec6818-dev:ubuntu18 bash -c 'make static'

工具链路径:gec6818_env_toolchain/toolchain/ARM 32-bit soft-floatGCC 5.4.0。

部署

板子 IP 192.168.1.88,目标目录 /home/cyy/

# 停止旧进程
ssh root@192.168.1.88 'killall mini_desktop 2>/dev/null; sleep 1'

# 主程序
scp -O mini_desktop root@192.168.1.88:/home/cyy/

# 资源文件
ssh root@192.168.1.88 'mkdir -p /home/cyy/icon /home/cyy/images'
scp -O icon/*.bmp   root@192.168.1.88:/home/cyy/icon/
scp -O images/*.bmp root@192.168.1.88:/home/cyy/images/

# 游戏(单独部署)
scp -O raycast_game_static root@192.168.1.88:/home/cyy/

需要部署的 BMP 清单

icon/
├── background.bmp    # 桌面背景800×480
├── photo_icon.bmp    # 图库图标(~80×80圆角
├── game_icon.bmp     # 游戏图标
├── ir_icon.bmp       # 红外图标
├── bg_page.bmp       # 红外子页面背景800×480
└── bar_top.bmp       # 红外顶栏800×44

images/
├── photo_1.bmp       # 相册照片800×480
├── photo_2.bmp
└── photo_3.bmp

IR 学习数据 ir_send_*.txt / ir_recv_*.txt 由程序自动生成,无需预部署。

运行

在板子上:

cd /home/cyy
./mini_desktop

触摸顶栏返回上级菜单,触摸图标进入应用。遥控器需先在「红外 → Learn → RECV 模式」学习 5 个键(上下左右中),之后桌面和图库中可用遥控操作。

设计约定

非阻塞 I/O

所有 I/O 使用 O_NONBLOCK + 事件排空模式。每帧先 while(ts_read > 0) 排空触摸, 循环退出后执行其他逻辑串口轮询等最后回到外层循环。UI 对触摸和串口同时响应。

ts_read()has_new 陷阱

ts_read() 内有 static int has_new每次调用必须重置为 0。 忘记重置会导致首次触摸后 ts_read() 永远返回 1 while(ts_read > 0) 死循环,后续代码永不执行。 此前曾导致红外学习页面无法读到串口数据。

触摸排空

子应用返回时务必排空触摸 + 红外缓冲,防止上一个触摸/遥控事件泄漏到下个页面。 使用 drain_both()(排空触摸 + ir_flush())。

游戏退出后的 framebuffer

游戏使用双缓冲 FBIOPAN_DISPLAY 翻页,退出后 yoffset 可能非零。 必须在游戏返回后调 fb_reset() 复位 yoffset 并重读参数。

BMP 渲染性能

  • bmp_display全屏背景stride 匹配时一次 memcpy,否则逐行 memcpy
  • show_bmp(图标/局部):无裁剪时一次 memcpy,有裁剪时逐行 memcpy
  • 不再逐像素处理透明alpha 字节由 LCD 控制器忽略)
Description
No description provided
Readme 26 MiB
Languages
C 98.4%
Makefile 1.6%