cleanup: remove unused source images and button BMPs

This commit is contained in:
cyy_mac
2026-06-16 15:10:18 +08:00
parent 2f06dc02dd
commit 24a042fc0b

216
README.md
View File

@@ -1,31 +1,136 @@
# mini_desktop — GEC6818 Desktop System # mini_desktop — GEC6818 桌面系统
800×480 framebuffer + touch desktop with photo album and IR remote control. 粤嵌 GEC6818ARM Cortex-A53 armv7l, Linux 3.4.39-gec
嵌入式桌面系统。800×480 LCD 触摸屏,集成电子相册、红外遥控和游戏启动器。
## Architecture ## 功能
``` ```
desktop → album (swipe photo browser) 桌面 ── 图库 (触摸滑动 / 遥控翻页浏览照片)
→ ir_app (learn / send / receive IR codes) ├─ 游戏 3D 光线投射游戏)
└─ 红外 (学习 / 发送 / 接收红外遥控码)
└─ 后台接收 → 遥控桌面导航
``` ```
## Non-blocking I/O pattern - **桌面**3 个圆角图标(图库、游戏、红外),支持触摸点击和遥控框选
- **图库**BMP 照片浏览,触摸左右滑动或遥控翻页,上键/点顶栏退出
- **游戏**:通过 `system()` 启动外部 `raycast_game_static`,退出后 fb_reset 恢复
- **红外**5 键学习(上下左右中),发送/接收页面,后台常驻识别遥控码
- **遥控导航**:左右键移动白色选框,中键进入应用
All I/O uses `O_NONBLOCK` + drain-events-into-cache. Never block on `read()`. ## 硬件
Touch events are drained per-frame via `ts_read()` — after the `while(ts_read > 0)` | 项目 | 详情 |
loop exits (no more events), remaining logic (serial polling, etc.) runs once, |------|------|
then the outer loop repeats. This keeps the UI responsive to both touch and serial. | 开发板 | 粤嵌 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) |
| 红外 | 串口 /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' 写入)|
### Do NOT let `ts_read()` return 1 with stale data ## 项目结构
`ts_read()` uses a `static int has_new` flag. It MUST be reset to `0` at the top ```
of every call. If you forget this, `has_new` sticks at `1` after the first touch, mini_desktop/
every `ts_read()` call returns 1 forever, and `while (ts_read(...) > 0)` loops ├── main.c # 入口
spin endlessly — **code after the loop is never reached**. This bit us when ├── Makefile
`page_learn()` could never read from the IR serial port. ├── 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/ # 分步测试
```
## Build ## 板子初始化
首次拿到板子或烧录系统后,需要配置网络和 SSH。
### 固定 IP
编辑 `/etc/profile`,在末尾添加:
```bash
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检查网线是否插好、交换机/路由器是否通电:
```bash
# 查看所有网口
ifconfig -a
# 手动启用
ifconfig eth0 up
```
某些镜像的 eth0 默认是 down 状态,加到 `/etc/profile` 里开机自动启用即可。
### 安装 SSHdropbear
板子默认可能没有 SSH 服务。检查:
```bash
ls /usr/sbin/dropbear # dropbear 服务端
ls /usr/bin/dbclient # dropbear 客户端SSH 登录用)
```
如果缺失,从交叉编译工具链或同型号板子拷贝:
```bash
# 在能 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 并启动:
```bash
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
```
确认启动:
```bash
ps | grep dropbear
```
设置开机自启(加到 `/etc/profile` 末尾):
```bash
dropbear -p 22 &
```
之后即可从电脑 SSH 登录:`ssh root@192.168.1.88`
## 编译
```bash ```bash
docker run --platform linux/amd64 --rm \ docker run --platform linux/amd64 --rm \
@@ -34,9 +139,84 @@ docker run --platform linux/amd64 --rm \
gec6818-dev:ubuntu18 bash -c 'make static' gec6818-dev:ubuntu18 bash -c 'make static'
``` ```
## Deploy 工具链路径:[`gec6818_env_toolchain/toolchain/`](../gec6818_env_toolchain/toolchain/)ARM 32-bit soft-floatGCC 5.4.0。
## 部署
板子 IP `192.168.1.88`,目标目录 `/home/cyy/`
```bash ```bash
# 停止旧进程
ssh root@192.168.1.88 'killall mini_desktop 2>/dev/null; sleep 1' 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/ 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` 由程序自动生成,无需预部署。
## 运行
在板子上:
```bash
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 控制器忽略)