diff --git a/AGENTS.md b/AGENTS.md index dc69f45..b6d1bbb 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -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 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 old note here said "keys reach the firmware but the UI does not react" and diff --git a/AGENTS.zh-CN.md b/AGENTS.zh-CN.md index 2060bfa..312b576 100644 --- a/AGENTS.zh-CN.md +++ b/AGENTS.zh-CN.md @@ -656,6 +656,26 @@ 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,都已修复