把 RISC-V 积木教学软件搬到香橙派 RV2:一次 OpenHarmony 移植复盘
把 RISC-V 积木教学软件搬到香橙派 RV2:一次 OpenHarmony 移植复盘
我们最开始以为,OpenHarmony 版本只是把 Web 页面塞进一个 HAP 包里。真正跑到香橙派 RV2 上以后,才发现问题不在“能不能显示页面”这么简单,而在 SDK 版本、签名、系统能力、ArkWeb 输入事件、屏幕布局和课堂演示节奏这些细节上。
这篇文章记录的是一次比较真实的移植过程。项目没有重写成完整 ArkUI,也没有把软件模拟说成真实硬件控制。我们做的是把现有 RISC-V 可视化教学软件稳定放到 OpenHarmony 设备端运行,并围绕触屏、教学屏和演示场景做适配。
项目背景
我们的软件面向 RISC-V 指令教学。学生可以用积木拼出 add、addi、lw、sw、beq、jal 等指令,再观察 PC、寄存器和存储器如何变化。
早期主线是 Windows / Web 版本,核心功能已经比较完整:
- 左侧选择指令和操作数积木;
- 中间拼接程序;
- 右侧查看机器状态、汇编代码和教学说明;
- 支持单步执行、自动执行、暂停和重置;
- 用动画显示寄存器、存储器和 PC 的变化。
OpenHarmony 版本的目标不是另起一套 UI,而是把这套教学闭环搬到香橙派 RV2 上。香橙派 RV2 本身是 RISC-V 开发板,运行 OpenHarmony 后,正好可以作为后续实体积木和外设控制路线的主控设备。
为什么没有直接重写 ArkUI
当时摆在面前有两条路。
一条是用 ArkUI 重写界面,积木拖拽、吸附、缩放、撤销、案例导入、执行动画全部重新实现。这样看起来“更原生”,但周期太长,而且很容易让 Windows 版和 OpenHarmony 版分叉。
另一条是保留 Web 主线,把页面作为 rawfile 放进 OpenHarmony 工程,用 ArkTS 创建 ArkWeb 来加载本地页面。我们最后选了这条路。
当前结构大致是:
app/ 主线 Web 界面
→ npm run oh:sync 同步静态资源
→ openharmony-port/entry/src/main/resources/rawfile/app/
→ ArkTS Index.ets 创建 ArkWeb
→ ArkWeb 加载 app/index.html
→ JSBridge 预留原生接口
这个选择保住了已有的教学逻辑。解析器、模拟器、机器状态动画和大部分 UI 都继续来自 app/,OpenHarmony 工程只负责承载、适配和以后接原生能力。
第一个坑:SDK 版本和设备版本并不天然匹配
DevEco Studio 同步工程时,我们先遇到 SDK 路径不合法和找不到 ArkTS、toolchains 的问题。后来发现本机安装的 OpenHarmony SDK 是扁平目录,而 hvigor 期望按 API 版本组织目录。为避免改 DevEco 安装目录,我们在项目里做了一个本地 SDK 镜像,让工程指向 .oh-sdk/24。
同步成功以后,真机安装又报过两类问题。
第一类是系统能力不匹配。DevEco 提示设备 rpcid.json 不包含一串系统能力,比如多媒体转码、后台进程管理、部分 ArkUI 能力等。我们的应用并不需要这些能力,于是通过 syscap.json 把不需要的能力从产物里移除。
第二类是 compatibleSdkVersion、releaseType 和设备不匹配。香橙派 RV2 上读取到的是 OpenHarmony 5.0.0.71,API 版本为 12,releaseType 是 Release。工程最初按较新的 SDK 元数据生成,HAP 信息和设备不一致。后来把兼容版本调整到 12,并在本地 SDK 镜像里处理 Release 元数据,才让安装流程走通。
这个阶段最大的经验是:不要只看 DevEco 里能不能 Build。真机的 apiVersion、releaseType、syscap 都要核对。否则工程能编译,设备照样不收。
第二个坑:签名不是点一下就结束
第一次部署时,HAP 能传到设备上,但安装失败:
Install Failed
error: no signature file
原因很直接,DevEco 当时生成的是 unsigned HAP。后来配置调试签名后,才生成 entry-default-signed.hap,并成功完成:
bm install 成功
aa start 成功
com.riscv.visualteaching successfully launched
OpenHarmony 工程签名里有 .p12、证书、Profile、包名等概念。自动签名能解决大部分调试场景,但工程的包名和 Profile 模板也要对上。我们最后把签名流程写进文档,就是为了避免后面接手的人在“能构建但装不上”这里反复卡住。
第三个坑:ArkWeb 能打开页面,不代表交互都稳定
页面第一次能打开时,我们松了一口气。很快又遇到崩溃。
最典型的问题是拖拽。Windows 浏览器里很自然的 HTML5 drag/drop,在 RV2 的 ArkWeb 上并不稳定。鼠标一拖就可能触发 cpp crash。换成触屏后,大积木能拖,但小积木吸附和页面滚动又会互相影响。
我们尝试过恢复完整拖拽动画,在新的 1080p 屏幕上重新测试,结果仍然闪退。最后的处理比较克制:
- OpenHarmony 运行时禁用原生
draggable和dataTransfer路径; - 保留自定义触摸/鼠标拖拽;
- 让小积木支持先拖到画布空白区,再二次拖到槽位;
- 保留点击选择、点击槽位填入的兜底操作;
- Windows 版继续保留完整拖拽体验,不因为 OpenHarmony 降级。
这个决定有点遗憾,因为积木软件当然应该能拖。但做设备端软件时,稳定性比动画完整更重要。课堂演示中,点击填槽至少能保证教学流程不断。
第四个坑:UI 不是简单放大到 1920×1080
最早用 7 寸 1024×600 屏时,左侧积木栏太窄,右侧机器状态挤在一起,底部日志还会挡住内容。后来换到 1920×1080 屏幕,问题并没有自动消失,只是换了形态:顶部工具栏太长,日志和反馈常驻占空间,右侧辅助栏滚不到底,底部还出现过一条白色区域。
我们后来做了几轮调整:
- 顶部只保留高频控制,执行相关按钮改回简洁图标;
- 指令积木栏和编辑区真正左右相邻,不再让素材栏盖住画布;
- 编辑区标题栏独立占位,网格从标题栏下沿开始;
- 执行日志和教学反馈改成底部抽屉;
- 右侧辅助栏支持宽度和高度调整;
- 辅助栏内部单独滚动,避免存储器区域被底部挡住;
- 画布增加缩放按钮,便于程序变长后观察整体结构。
其中有一次修底部白条时还出现了主体白屏。最后发现原因是高度链断了:外层用了 100vh,但中间的 main 没有作为 flex 容器继续把剩余高度传下去。修复后,工作区才真正占满剩余空间。
这类问题很难靠想象解决。必须在目标屏幕上看,拖一下,滚一下,跑一遍自动执行,才能知道哪里不舒服。
第五个坑:OpenHarmony 展示和执行动画会抢位置
项目里有一个 OpenHarmony 展示功能,用来说明软件积木、香橙派主控、软总线和后续实体积木之间的关系。后来我们又加了数据动画,用卡片显示寄存器、存储器和 PC 的变化。
一开始两套动画会互相抢右侧辅助栏。打开 OpenHarmony 展示以后,自动执行的数据动画会把展示卡片顶掉,或者展示模式干脆禁用自动执行。
这不符合课堂使用。老师可能一边讲 OpenHarmony 展示,一边执行 RISC-V 指令。于是我们把两者解耦:
- OpenHarmony 展示只是辅助信息,不接管执行按钮;
- 单步、自动、暂停、重置仍然控制 CPU 教学模拟;
- 打开展示时,OpenHarmony 动画保留在辅助栏;
- 数据执行动画出现时,和 OpenHarmony 展示上下共存;
- 关闭 OpenHarmony 展示后,对应卡片自动收起。
后来又补了动画暂停。现在数据卡片出现时可以停住看清楚,速度档也从旧的 0.5x 改成新的 1x / 1.5x / 2x。新的 1x 实际上是课堂观察用慢速。
术语也会影响理解
有些修改看起来很小,但对教学很重要。
例如右侧机器状态里,早期写的是“内存”。后来我们改成“存储器”,因为课堂上讲 RISC-V 指令执行时,寄存器和存储器应该分清。数据动画卡片也不再只显示:
0 -> 5
而是显示成:
寄存器 x1: 0 -> 5
PC: 0 -> 1
当一条指令同时改变寄存器和 PC 时,两张卡片左右并排出现。这样学生暂停后能直接看懂:数据写到哪里,PC 又走到了哪里。
机器状态初始化区也做过细调。寄存器/存储器、目标编号、数值、写入、清除这五个控件要放在一行,并且宽度要和上一排进制按钮对齐。这个问题最后定位到 OpenHarmony 专用 CSS 后加载,覆盖了主样式里的五列 grid。主线已经改了,但真机还不变,就要查 openharmony-port.css。
更多推荐


所有评论(0)