
把 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.71API 版本为 12releaseType 是 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 launchedOpenHarmony 工程签名里有.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。