The app-size ladder: the launcher jumps before the app is fully copied

Measured with the 2 ms PC probe: Spin (16 B) loops in the overlay forever; Delay (248 B) is still running 13 s later, 54 of the last 60 samples at 0x20000348; Phases (372 B) survives bar, blit and led; Ladder (544 B) dies before drawing; Minesweeper (2408 B, and 2428 B with an opening spin) is dead within about 4 ms either way. An opening spin does not save the big apps, so the difference is how much of the app has been copied rather than when the first call is made -- and that also explains why Tetris's full 3300 bytes were present in the overlay when checked afterwards: the copy finishes after the app has been entered.

Same family as the four flash bugs already recorded here: the loader is told the transfer is over while the guest is still feeding it. Next: watch the SPI/DMA busy and complete flags during a large read instead of reasoning about them.
This commit is contained in:
mckero committed 2026-10-02 10:19:15 +08:00
1 parent f3a369d38f
commit 36c8c66006
2 files changed
+43

No files matched your search

+23
View File
@@ -808,6 +808,29 @@ nothing. So the launcher (or the fault path it takes) is wedged, not merely wait
That is where the next round starts: the app dies within about 2 ms, the firmware never reads the flash after That is where the next round starts: the app dies within about 2 ms, the firmware never reads the flash after
loading it, and what is left running is a tight loop in the firmware with no display or key activity. loading it, and what is left running is a tight loop in the firmware with no display or key activity.
**The app-size ladder points the finger at an unfinished copy: the launcher jumps before the code is all there.**
Sizes and outcomes, all measured on the page's own emulator with a 2 ms PC probe (UVK5_PC_PROBE_MS):
| app | code | result |
| --- | --- | --- |
| Spin | 16 B | loops in the overlay forever |
| Delay | 248 B | **still running 13 s later** (54 of the last 60 samples inside the overlay, at 0x20000348) |
| Phases | 372 B | survives a bar plus blit plus led |
| Ladder | 544 B | dies before it can draw anything |
| Minesweeper | 2408 B, then 2428 B with an opening spin | dead within about 4 ms either way |
An opening spin does not save the big apps, so this is not about how soon the first call is made. It is about
**how much of the app has been copied**: the first few hundred bytes are executable and everything past them is
not there yet when the app runs. That also explains the earlier surprise that Tetris's full 3300 bytes were
present in the overlay when checked by hand afterwards -- the copy does finish, just after the app has been
entered. The pattern is the same family as the four flash bugs already in this file: the loader is told the
transfer is over while the guest is still feeding it, so it jumps early. The suspicion is the SPI/DMA busy and
complete flags, and the check is to watch them during a large read rather than to reason about them.
Workaround, for now and marked as one: a small app is a working app. The opening spin added to Minesweeper is
kept out of the repository until the real cause is fixed, because it does not work anyway.
## The keypad: two real bugs, both fixed ## The keypad: two real bugs, both fixed
The old note here said "keys reach the firmware but the UI does not react" and The old note here said "keys reach the firmware but the UI does not react" and
+20
View File
@@ -656,6 +656,26 @@ flash 探针是按顺序记录每一笔事务的,而那一次启动的**最后
故障路径)卡死了**,而不只是在等一次松开。 故障路径)卡死了**,而不只是在等一次松开。
下一轮就从这里开始:应用在约 2 ms 内死亡,固件在加载它之后**再也没有读过 flash**,而剩下的是一个没有显示、 下一轮就从这里开始:应用在约 2 ms 内死亡,固件在加载它之后**再也没有读过 flash**,而剩下的是一个没有显示、
**应用体积的阶梯把矛头指向「拷贝尚未完成」:启动器在代码还没全到位时就跳了进去。**
体积与结果,全部是在页面自己的模拟器上、用 2 ms 的 PC 探针(UVK5_PC_PROBE_MS)测的:
| 应用 | 代码 | 结果 |
| --- | --- | --- |
| Spin | 16 B | 在叠加区里永远循环 |
| Delay | 248 B | **13 秒后仍在运行**(最近 60 个样本里 54 个在叠加区,地址 0x20000348) |
| Phases | 372 B | 活过 bar + blit + led |
| Ladder | 544 B | 还没画出任何东西就死了 |
| Minesweeper | 2408 B,加上开场自旋后 2428 B | 两种都在约 4 ms 内死掉 |
开场自旋救不了大应用,所以问题不在「第一次调用有多早」,而在**应用到底被拷进去了多少**:头几百字节可执行,
而它们之后的部分在应用跑起来时**还没到位**。这也解释了先前那个意外:事后手工检查时,Tetris 完整的 3300 字节
**确实**在叠加区里 —— 拷贝**最终会完成**,只是**在应用已经被跳进去之后**。这与本文件里已经记着的那四个 flash
bug 是同一族:**传输还在进行时就告诉加载器「已完成」**,于是它提前跳转。嫌疑点是 SPI/DMA 的忙/完成标志;
验证方式是**在一次大读取期间去观察这些标志**,而不是坐着推理。
临时办法(且标明只是临时办法):**小应用就是能用的应用**。给扫雷加的那个开场自旋不会进仓库 —— 它本来也没起作用。
没有按键活动的紧循环。 没有按键活动的紧循环。
## 键盘:两个真 bug,都已修复 ## 键盘:两个真 bug,都已修复