本文使用已登记到 local/apps.toml 的 hello 示例。所有命令在 PXA 工作区根目录执行;真实设备需要事先运行 PXA 固件。
1. 桌面一次运行或持续开发
# 构建、安装并运行;终端保持运行直到应用结束或按 Ctrl-C
tools/dev.sh sim hello
# 保存源码后,重新打包、安装和启动
tools/dev.sh sim hello --watch
开发工具依次启动模拟器服务、构建 simulator 目标、用 PXADB 覆盖安装,再启动 product runner。日志中应出现 [dev] running pxa-hello。首次运行可能需要构建工具链或模拟器,之后才进入增量循环。
每次更新都会重新启动 App,运行中的内存状态会丢失。安装后的持久数据由安装器和应用存储策略管理,不能把这种工作流当作保持全部运行状态的热重载。
2. watch 观察哪些文件
工具递归观察当前应用目录中的文件变化,例如 main.c、package.json 和 i18n/。它跳过 .git、__pycache__、build、dist、node_modules、out 等目录。
应用目录之外的共享 SDK、其他仓库,以及 local/apps.toml 和模拟器 Profile,不属于这次 App watch 的观察范围。修改这些配置后停止并重新执行命令;不要一直等它自动发现。
tools/dev.sh sim hello --watch --interval 0.5 --debounce 0.8
--interval 是检查间隔,默认 0.35 秒;--debounce 是文件停止变化后再触发构建的等待时间,默认 0.30 秒。一次保存会改多个文件时,适当增加 debounce 可以减少重复构建。
首次部署失败时先修复问题并重新执行。进入 watch 后的后续构建失败会记录 update failed,观察循环继续等待下一次修改;应用可能已被停止,不能认为旧画面还在运行。
3. 区分 board、profile 与 target
| 参数 | 控制内容 | 例子 |
|---|---|---|
--board |
工作区板级选择、相关打包配置和默认输出目录 | pai-touch |
--profile |
桌面尺寸、屏幕形状、语言等模拟参数 | sensecap-watcher |
--target |
tools/app.sh 生成的制品架构 |
simulator、esp32s3、esp32s31 |
tools/dev.sh sim 始终构建桌面目标;改变 Profile 不会把应用变成 ESP 固件。dev.sh 未给 Profile 时默认使用与 --board 同名的 Profile,而直接使用 simulator.sh 时默认 Profile 是 generic。
# 输出仍放在 pai-touch 下,但以 Watcher 圆屏运行
tools/dev.sh sim hello --board pai-touch --profile sensecap-watcher --watch
# 板级与默认模拟屏幕一起选为 ESP32-S31 Korvo
tools/dev.sh sim hello --board esp32s31-korvo-1 --watch
新建了 watch-240.toml 时,用 --profile watch-240;不要仅因为它是显示 Profile,就把不存在的板级目录传给 --board。dev.sh 当前没有 --target 参数,需自选架构时使用分步打包命令。
4. 切换到真机
关闭占用端口的 IDF monitor、GUI 或其他 PXADB 进程,然后执行:
tools/dev.sh device hello --board pai-touch --port /dev/ttyACM0 --watch
设备模式独立打包应用并覆盖安装,不重新编译和烧录固件。默认部署后订阅 logcat,下次部署前会先停止这个由它启动的日志进程以释放串口。
使用 USB 桥 UART 的设备时,应按板子的真实传输配置设置波特率,例如:
tools/dev.sh device hello --board esp32s31-korvo-1 \
--port /dev/ttyUSB0 --baud 2000000 --watch
当前开发工具在设备模式中对 esp32s31-korvo-1 选择 esp32s31,其他 board 选择 esp32s3。适配其他芯片时不能假设它会自动判断 CPU,应先用 tools/app.sh --target 的受支持目标分步验证。
5. 一次部署后交给 GUI
需要 GUI 长时间占用串口时,先做一次不订阅日志的部署:
tools/dev.sh device hello --port /dev/ttyACM0 --no-logcat
tools/pxadb-gui.sh --port /dev/ttyACM0
不要同时开 device watch 和 GUI。--no-logcat 只关闭开发工具自己的日志订阅,不会解决两个工具同时安装或访问串口的冲突。
6. 保存独立日志
默认日志追加写入 local/dev-logs/<mode>/<源码目录名>.log,合并构建、安装、运行器与 Guest 输出。不同 Profile 调试同一个应用时,建议显式分文件:
tools/dev.sh sim hello --profile pai-touch --watch \
--log-file local/dev-logs/hello-pai-touch.log
下一次换屏幕时使用另一个文件名。并行运行多个 dev watch 会共享默认打包输出,容易互相覆盖;正式多实例比较请按Profile 教程先构建一个稳定包,再装入隔离实例。
7. 正确结束与分步定位
Ctrl-C 会停止开发工具管理的 App runner 和日志订阅。模拟器服务通过显式 service start 启动,可能继续常驻;用下列命令检查并按需停止:
tools/simulator.sh service status --profile pai-touch
tools/simulator.sh service stop --profile pai-touch
只停止自己使用的 Profile;其他窗口可能仍在依赖该服务。分步排查可以按顺序执行:
tools/app.sh build hello --target simulator
tools/simulator.sh service start --profile pai-touch
pxadb package install local/app-output/pai-touch/pxa-hello.pxa --simulator pai-touch
pxadb package list --simulator pai-touch
pxadb package run pxa-hello --simulator pai-touch
构建失败检查源码与工具链;安装失败检查签名和包;启动失败检查身份、ABI、服务和资源。把这三个阶段分开,通常比反复运行一条长命令更容易定位。
8. 自签名应用的模拟器调试
PXA_SIGNING_KEY 控制打包私钥。模拟器默认信任开发夹具公钥;自己的包应显式指定匹配的 DER 公钥:
export PXA_SIGNING_KEY="$PWD/local/keys/publisher-private.pem"
export PXA_SIMULATOR_PUBLISHER_KEY="$PWD/local/keys/publisher-public.der"
tools/dev.sh sim hello --watch
已有服务不会因新终端改变环境变量就自动更换验签公钥。确认其他窗口不依赖该服务后,先停止对应 Profile 的服务,再用新配置启动。密钥生成与更新身份见打包、签名与版本。