About this project
这是什么
把 AmoledOS 从 ESP32-S3 搬到 WS63,跑在一块能握在手里的 240×320 电容触摸屏上。7 个表盘、15 个应用、SD 卡上的中文点阵字库,以及一套让它能被脚本驱动、被抓屏、被逐页巡查的工具链。
上游那套界面原本长在 ESP32-S3 的 368×448 圆角 AMOLED 上。这个项目把它搬到 WS63(HiSpark 的 RISC-V Wi-Fi / 蓝牙 / 星闪芯片)和微雪 2 寸电容触摸屏上,并按新分辨率重排了每一页的布局——不是等比缩小。

上面和下面所有界面图,都是从板子上抓的真实像素,不是仿真截图,也不是设计稿。
界面
7 个表盘,随时切换:数字、指针、极简、圆环、翻页、二进制、辉光管。

面板从上游的 368×448 换成 240×320,aos_face_*.c 里的坐标常量都改过,所以和上游对不上是预期内的。
启动器有三种样式:列表、分页网格、蜂窝;支持文件夹归类,菜单布局从 SD 卡的 menu.txt 读取(上游是编译期写死的)。
文件管理是上游没有、本移植新增的:浏览、新建、删除、重命名、文本分页阅读(记阅读位置)、图片与 GIF 预览、容量显示。它背后是一整套 FAT 文件系统栈。
设置是手机样式的多页结构:设备信息、Wi-Fi、热点、蓝牙、星闪 SLE、显示与亮度。Wi-Fi 扫描连接、蓝牙改广播名、星闪开关都是真的走射频。
天气接和风天气的 HTTPS 接口,数据是 gzip 压缩的,板上就地解压。
15 个应用
已经启用 15 个:

| 应用 | 说明 |
|---|---|
| 天气 | 和风天气 HTTPS 接口,返回的 gzip 在板上就地解压 |
| 秒表 | 分圈计时,切到别的页面也照走,回来接着看 |
| 计时器 | 预设时长的倒计时,剩余时间画成一圈进度弧 |
| 番茄钟 | 工作与休息四轮连锁,今日完成数跨重启保留 |
| 世界时钟 | 八座城市同屏,各自的时区偏移在板上自己算 |
| 文件管理 | 浏览、新建、删除、重命名;文本分页阅读会记住读到哪页;图片与 GIF 能预览,附容量显示 |
| 日历 | 月视图(周一起始)与年视图 |
| 闹钟 | 每个闹钟自己挑要生效的星期几 |
| 相册 | 扫卡上 0:/photos/ 的图片,交给 LVGL 解码显示 |
| 计算器 | Braun ET66 风格的键盘,四则运算、百分号与正负号 |
| 换算 | 十个族类的单位互换,每族是一张基准值加比例的表 |
| 手电筒 | 屏幕三色满亮 |
| 电源信息 | WS63 没有电源管理单元,这一页报的是芯片温度与堆内存水位 |
| 设置 | 手机样式的多页结构:设备信息、Wi-Fi、热点、蓝牙、星闪 SLE、显示 |
| 生命游戏 | 92×92 格上的康威生命游戏,另有兰顿蚂蚁与三种种子图案 |
另外 9 个源码在、没有注册:其中 8 个各自在等一块硬件或一个服务(水平仪、运动、音乐、打鸭子、空中鼠标、配对、通知、遥控)——不是没做;剩下那个是被 WS63 版替代的上游设置。比如音乐只差 aos_hal_player_* / aos_hal_volume_* 六个 HAL 函数(需要音频解码和 I2S 输出),通知和遥控缺的是手机侧的服务,不是芯片能力:WS63 有完整的 BLE 协议栈,固件里那部分(.bth_text_flash + .btc_text_flash)合计 705029 字节,约 688 KB。
逐项的启用状态、缺什么、为什么,见 docs/Features.md。
硬件
接线只有两个坑,但都会让人卡很久,而且现象都不指向真正的原因:
SD 卡的 VCC 要接 5V,不能接 3.3V。 模块板载 LDO,3V3 轨供不出 SD 卡初始化时的电流脉冲。看起来像是驱动写错了——屏幕完全正常、背光亮、能显示,而 SD 卡全程静默,命令发出去没有任何回应,日志里连错误码都没有。
MISO 必须用 GPIO5。 WS63 的 SPI0 输入只有 GPIO11 和 GPIO5 两个可选脚,但 GPIO9 与 GPIO11 是上电配置字,同时为高会被判为“禁止”,芯片直接进下载模式。模块上的电平转换芯片会把 MISO 线拉高——于是接 GPIO11 就等于把板子按住不让它启动。表现是烧录成功但板子不跑新固件,很容易误判成烧录失败。
完整接线表、每个引脚的作用、以及为什么片选必须是软件 GPIO,见 docs/Hardware.md。
装起来
本工程是 WS63 SDK 里的一个样例,所以要先有 SDK:
git clone https://gitcode.com/HiSpark/fbb_ws63.git
需要上面那块板子、一张 FAT32 的 microSD 卡、一根能传数据的 USB 线。工具链随 SDK 提供,cmake 要在 PATH 里。
1. 放进工程
把本仓库的 waveshare_2inch_amoledos/ 整个复制到 <SDK>/src/application/samples/peripheral/。
2. 接入 SDK
改 3 个文件、加 1 个目录;也可以让脚本一次做完:
python tools/install_into_sdk.py --sdk <SDK>/src
脚本幂等,--dry-run 可预演。逐条步骤和每一步的理由在 docs/SOP.md 第 3 节,那里也有一张可以照着核对的总表。
这一步会是这个项目里最容易出错的地方,而且错了多半是静默的:Kconfig 会把不认识的开关悄悄丢掉、样例开关关闭时构建照样成功。所以 SOP 里把每一个坑的现象都写出来了——构建成功但功能不对时,先回那一节对照。
3. 编译
cd <SDK>/src
rm -rf output
python build.py ws63-liteos-app
python build.py 是 SDK 自带的入口,不需要额外装什么。改过 Kconfig 之后必须先清 output/,否则 CMake 不会重新 configure。
4. 准备 SD 卡
卡上要有字库,否则界面能跑但汉字显示不出来。字库不用自己生成——waveshare_2inch_amoledos/sd_assets/fonts/hzk16.bin 里有一份现成的(678 KB,从 Noto Sans SC 渲染,OFL 许可),拷到卡的 fonts/ 下就行。
要换字体、调字重可以自己生成,命令见 docs/SOP.md 第 4 节。
天气要自己注册凭据。 和风天气的 API host 与 key 是每个使用者自己的,不随仓库分发:
cd <SDK>/src/application/samples/peripheral/waveshare_2inch_amoledos/amoledos_port
cp qweather_config.h.example qweather_config.h
不填也能编过固件,只是天气页拿不到数据。
5. 烧录
按 SDK 的常规方式烧录,串口 115200。首次烧录或板子跑飞时可能不响应下载握手,按一下板上的 RESET 再试。
起来的标志是串口出现这三行:
[WS63][UI] original runtime started; touch=yes
[WS63][FS] mount ok
[WS63][FS] selftest PASS ro=0
第三行是开机自检——它跑一遍完整的写路径(建目录、写、读回比对、重命名、删除),任何一段坏了都会在这里停下并报出是哪一段。
卡带上一处本层修不了的损坏时(掉电或拔卡打断过写入的卡),自检多报两行,并把写路径换到 0:/_fstest1/ 验完:
[WS63][FS] selftest residue dir=0:/_fstest entries=2 first=psobe.bin
[WS63][FS] selftest PASS ro=0 residue=1
residue=1 说的是 0:/_fstest/ 里有 f_readdir 列得出、f_unlink 永远匹配不上的目录项:FatFs 按大写的 8.3 字节逐个比较名字(ff.c:2485),而 create_name 写出去的 SFN 一定是大写(ff.c:2948),字节不符合这个形态的项就留在那里,名字对它无效。写通道不受影响;PC 上的 FAT 驱动按大小写不敏感匹配名字,这类项在 PC 上删得掉。
在电脑上看界面
改版式不必每次刷机。同一套界面代码可以在 PC 上编译运行:
bash host_tools/build_port.sh run
AOS_SIM_VIEW=aos.settings bash host_tools/build_port.sh run
它跑的是本仓库的界面代码,屏幕尺寸取自本工程的 aos_hal.h(240×320),所以版式和板子上一致。还能跑官方那套布局审计——遍历 LVGL 对象树,报文字溢出、跑出屏幕这类问题,比肉眼靠谱。
板端出图可信,PC 端试版式快,两条路互补。见 host_tools/README.md。
项目结构
WS63_AmoledOS/
├── waveshare_2inch_amoledos/ 固件源码,放进 SDK 的那个目录
│ ├── amoledos_port/ 移植层:界面运行时、15 个应用、7 个表盘
│ ├── fs/ 文件系统服务层(卷/目录/文件/路径/内存/自检/字库)
│ ├── sd_spi/ SD 卡与屏的总线驱动(共用 SPI0)
│ ├── src/ 显示与触摸驱动、上位机协议、抓屏
│ ├── sd_assets/ SD 卡上要放什么(含现成字库)
│ ├── third_party/ 随工程走的两个组件:fatfs、inflate
│ └── tools/ 诊断与验证脚本(Python)
├── sdk_config/ 要追加到 SDK 的 LVGL 开关清单
├── host_tools/ 在 PC 上跑界面、出截图
└── docs/ 文档
软件架构
依赖方向自上而下,单向:
amoledos_port/ 界面层 —— 上游 UI 运行时、15 个应用、7 个表盘
↓ aos_hal_*(屏幕 / 偏好 / 网络 / 蓝牙 / 字体 / 播放器)
fs/ 服务层 —— 卷 / 目录 / 文件 / 路径 / 内存 / 自检,不碰 LVGL
↓ disk_read / disk_write
sd_spi/ 驱动层 —— SD 卡与屏共用 SPI0,负责总线仲裁
↓ uapi_spi_* / uapi_i2c_* / uapi_gpio_*
WS63 SDK LiteOS、外设驱动、LVGL
换平台时重写的只有 amoledos_port/ws63_adapter.c 与板级那几个文件:界面层从上游原样搬来,服务层与驱动层不含上游代码。
分层约束可以用命令检验(两条都应无输出):
cd waveshare_2inch_amoledos
grep -rn "uapi_" amoledos_port/aos_app_*.c
grep -rnE '\b(FATFS|FIL|f_open)\b' amoledos_port/aos_app_files.c
一条数据走完全程的路径(以“打开 SD 卡上的一张图片”为例)、以及各处刻意的设计取舍,见 docs/Architecture.md。
这些数字是怎么来的
这个仓库里的注释和文档,解释“为什么”多于“是什么”,而且很多记的是量出来的东西,不是推断的。举几例:
- MISO 为什么不能用 GPIO11:不是“不推荐”,是 GPIO9(HW_ID[1])与 GPIO11(HW_ID[2])同时为高会进下载模式——模块上的电平转换芯片会把 MISO 拉高,于是接上去等于按住板子不让它启动。现象是“烧录成功但板子不跑”。
- SPI 速率为什么是 8 MHz:20 MHz 在杜邦线上能挂载,但读全部失败。这是信号完整性,不是配置问题——换更短的线或做板会不一样。
- 抓屏为什么要分条:整屏快照要
240×320×2 = 153600字节连续堆,而这块板子实测最大连续块只有约 112 KB。所以抓屏走镜像通道,让像素顺着 flush 的脏矩形分条出来(flush 块 240×32 = 15 KB 原始像素,镜像再按 16 行一条编码,RLE 后单包不超过 960 字节)。 - 48 号字为什么只有 53 个字形:它只用来显示数字和单位,裁剪后位图池从 216.7 KB 降到 21.8 KB——而固件总余量只有 224 KB。
- 上游的
AOS_BSS_PSRAM在这里展开为空:那是把大块静态数据放进 PSRAM 的标记,本平台没有 PSRAM。这类差异最容易漏——代码能编过,内存水位却不一样。
文档
docs/ 下的文档分五层,越往下越贴近代码:L1 讲这个项目是什么,L2 讲每个模块,L3 讲契约,L4 讲运行时,L5 讲状态机。写文档的规则见 docs/DocStyle.md。
| 层 | 文档 | 内容 |
|---|---|---|
| L1 项目 | docs/SOP.md | 操作手册:从零到跑通的每一步、每个坑的现象与机理 |
| L1 项目 | docs/Features.md | 功能清单:有什么、没什么、为什么 |
| L1 项目 | docs/Hardware.md | 接线、引脚、电气注意 |
| L1 项目 | docs/Architecture.md | 分层与依赖方向,以及可被命令检验的约束 |
| L1 项目 | docs/Build.md | 构建参考:命令、开关、产物、体积 |
| L1 项目 | docs/DirectoryStructure.md | 目录逐项说明 |
| L2 模块 | docs/modules/ | 21 篇模块文档:每个模块负责什么、对外给什么、依赖谁 |
| L3 接口 | docs/interfaces/fs-service.md | 契约:谁拥有对象、能不能跨线程调、失败怎么表示 |
| L4 运行时 | docs/TaskDesign.md | 四个任务、两把锁、拿锁顺序 |
| L4 运行时 | docs/ISRDesign.md | 中断上下文里做什么、喂狗点分布 |
| L4 运行时 | docs/EventFlow.md | 一次触摸、一帧画面、一次联网怎么穿过各层 |
| L5 状态机 | docs/StateMachine.md | 四处状态机与迁移条件 |
| 后续 | docs/DocStyle.md | 分层规则、语气与图的硬性要求 |
依赖
| 依赖 | 说明 |
|---|---|
| WS63 SDK | HiSpark fbb_ws63,提供驱动、LiteOS 与构建系统 |
| LVGL 9.4.0 | 图形库,随 SDK 的 open_source/ 提供 |
| FatFs R0.13c | FAT 文件系统,随工程提供(third_party/fatfs/) |
| inflate | 解压,随工程提供;天气接口返回的是 gzip 压缩的 JSON |
| cJSON | 天气接口的 JSON 解析,随 SDK 提供 |
| 和风天气 API | 天气数据源,host 与 key 需自行注册 |
许可证
本移植层的代码遵循上游 AmoledOS 的 MIT 许可证,见 LICENSE 与 LICENSE.AmoledOS。
第三方库各自遵循其原始许可证:LVGL(MIT)、FatFs(FatFs License)、cJSON(MIT)、inflate、字体(见 fonts/LICENSE)。SD 卡上的字库从 Noto Sans SC 渲染(SIL OFL 1.1)。
致谢
- AmoledOS —— 界面运行时与大部分应用的来源,MIT。这个项目做的是把它从一个平台搬到另一个平台
- 微雪电子 —— 2 寸电容触摸屏及其驱动参考资料
维护:海星社区
Comments
0 commentsNo comments yet — start the conversation.
