mirror of
https://github.com/MCKero6423/uv-k5-v3-emulator.git
synced 2026-10-02 03:15:36 +00:00
Make the PC probe interval configurable, and trace the app's life as one tick
uvk5_pc_probe_interval_ms() reads UVK5_PC_PROBE_MS and falls back to 100, so existing probe runs are unchanged. At 2 ms a launch gives 468 samples in about 0.94 s and exactly one of them is inside the 4 KiB overlay: the app lives for roughly 2 ms, not 100. The trace settles two things and adds one. The loader copies and jumps (the single overlay sample; a 16-byte app that calls nothing stays there forever). The sector-cache overwrite is dead: the flash log's last transaction for the run is the app's own code load (addr=103000 len=2408) and nothing follows it, no font read included. New: after the app dies the firmware loops inside its own flash (PCs near 0x08005118/0x08005122/0x08005248) with zero flash reads and no key response at all -- F then 7 no longer opens the menu and an explicit MENU down/up changes nothing -- so the launcher or its fault path is wedged.
This commit is contained in:
1 parent
394f473df0
commit
f3a369d38f
3 files changed
+49
-2
No files matched your search
@@ -790,6 +790,24 @@ Next instrument, and it needs a one-line model change rather than more guessing:
|
|||||||
100 ms, which is the same order as the app's whole life. Dropping that interval to a couple of milliseconds
|
100 ms, which is the same order as the app's whole life. Dropping that interval to a couple of milliseconds
|
||||||
turns it into a real trace and would show where in the overlay the app stops.
|
turns it into a real trace and would show where in the overlay the app stops.
|
||||||
|
|
||||||
|
**The PC probe's interval is now a knob (UVK5_PC_PROBE_MS), and at 2 ms the overlay app's whole life is one tick.**
|
||||||
|
|
||||||
|
100 ms was the same order as the thing being measured: an app that the launcher starts and that is gone again
|
||||||
|
before the next sample. uvk5_pc_probe_interval_ms() reads UVK5_PC_PROBE_MS and falls back to 100, so every
|
||||||
|
existing probe run is unchanged. At 2 ms, a launch gives 468 samples in about 0.94 s and **exactly one of them
|
||||||
|
is inside the 4 KiB overlay** -- the app runs for roughly 2 ms, not 100.
|
||||||
|
|
||||||
|
With a real trace in hand, two things are now settled and one is new. Settled: the loader copies and jumps (the
|
||||||
|
single overlay sample), and a 16-byte app that calls nothing stays there forever. Settled the other way: the
|
||||||
|
sector-cache overwrite is dead -- the flash log's **last** transaction for the run is the app's own code load
|
||||||
|
(addr=103000 len=2408) and **nothing follows it**, no font read included. New: after the app dies the firmware
|
||||||
|
sits in a loop inside its own flash (PCs around 0x08005118/0x08005122/0x08005248) with **zero flash reads and
|
||||||
|
no key response at all** -- even F then 7 no longer opens the menu, and an explicit MENU down/up changes
|
||||||
|
nothing. So the launcher (or the fault path it takes) is wedged, not merely waiting for a release.
|
||||||
|
|
||||||
|
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 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
|
||||||
|
|||||||
@@ -642,6 +642,22 @@ flash 探针是按顺序记录每一笔事务的,而那一次启动的**最后
|
|||||||
下一个仪器,只需要改模型一行而不是继续猜:PC 探针每 100 ms 采样一次,而应用整个生命期就是这个量级。把这个
|
下一个仪器,只需要改模型一行而不是继续猜:PC 探针每 100 ms 采样一次,而应用整个生命期就是这个量级。把这个
|
||||||
间隔降到几毫秒,它就变成真正的 trace,能看出应用**停在叠加区的哪个位置**。
|
间隔降到几毫秒,它就变成真正的 trace,能看出应用**停在叠加区的哪个位置**。
|
||||||
|
|
||||||
|
**PC 探针的间隔现在是可配置的(UVK5_PC_PROBE_MS);调到 2 ms 之后,叠加应用整个生命期只有一个采样点。**
|
||||||
|
|
||||||
|
100 ms 与被测对象同量级:启动器刚把应用带起来,下一个采样到来之前它就已经没了。uvk5_pc_probe_interval_ms()
|
||||||
|
读 UVK5_PC_PROBE_MS、缺省仍是 100,所以以往任何一次探针运行都保持原样。调到 2 ms 后,一次启动在约 0.94 秒里
|
||||||
|
得到 468 个样本,其中**恰好一个**落在那 4 KiB 叠加区内 —— 应用只活了约 **2 毫秒**,不是 100。
|
||||||
|
|
||||||
|
有了真正的 trace,两件事就此确定,另有一件是新发现。确定的:加载器会拷贝并跳转(那一个叠加区样本),而且
|
||||||
|
那个 16 字节、什么都不调用的应用能一直待在里面。反过来确定的:**扇区缓存覆盖说已经死了** —— 那次运行的 flash
|
||||||
|
日志里**最后一条**就是应用自己的代码加载(addr=103000 len=2408),**其后什么都没有**,包括字体读取。新发现:
|
||||||
|
应用死掉之后,固件**停在自身 flash 内的一个循环里**(PC 在 0x08005118/0x08005122/0x08005248 一带),**零次 flash
|
||||||
|
读取、按键完全无响应** —— 连 F 再 7 都打不开菜单了,显式地 MENU down/up 也毫无变化。也就是说**启动器(或它走的
|
||||||
|
故障路径)卡死了**,而不只是在等一次松开。
|
||||||
|
|
||||||
|
下一轮就从这里开始:应用在约 2 ms 内死亡,固件在加载它之后**再也没有读过 flash**,而剩下的是一个没有显示、
|
||||||
|
没有按键活动的紧循环。
|
||||||
|
|
||||||
## 键盘:两个真 bug,都已修复
|
## 键盘:两个真 bug,都已修复
|
||||||
|
|
||||||
这里原来的笔记写的是"按键到达了固件但界面不反应",并且归咎于机器模型。结果发现有**两个
|
这里原来的笔记写的是"按键到达了固件但界面不反应",并且归咎于机器模型。结果发现有**两个
|
||||||
|
|||||||
+15
-2
@@ -3609,6 +3609,19 @@ static uint32_t uvk5_sniff_app_offset(const char *path)
|
|||||||
* can be located without a debugger (a gdb attach stops the guest, which is the
|
* can be located without a debugger (a gdb attach stops the guest, which is the
|
||||||
* one thing that must not happen while working out where it stopped).
|
* one thing that must not happen while working out where it stopped).
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
|
* How often the PC probe samples. 100 ms is fine for finding a hang, but an overlay
|
||||||
|
* app's whole life can be shorter than that -- the launcher takes the screen and the app
|
||||||
|
* is gone again before the next tick -- so UVK5_PC_PROBE_MS lets a run ask for a real
|
||||||
|
* trace instead of a few points. The default keeps every existing probe run identical.
|
||||||
|
*/
|
||||||
|
static int uvk5_pc_probe_interval_ms(void)
|
||||||
|
{
|
||||||
|
const char *v = g_getenv("UVK5_PC_PROBE_MS");
|
||||||
|
int ms = v ? atoi(v) : 0;
|
||||||
|
return ms > 0 ? ms : 100;
|
||||||
|
}
|
||||||
|
|
||||||
static void uvk5_pc_probe_tick(void *opaque)
|
static void uvk5_pc_probe_tick(void *opaque)
|
||||||
{
|
{
|
||||||
UVK5MachineState *s = opaque;
|
UVK5MachineState *s = opaque;
|
||||||
@@ -3620,7 +3633,7 @@ static void uvk5_pc_probe_tick(void *opaque)
|
|||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
timer_mod(s->pc_probe_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 100);
|
timer_mod(s->pc_probe_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + uvk5_pc_probe_interval_ms());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void uvk5_boot_key_release(void *opaque)
|
static void uvk5_boot_key_release(void *opaque)
|
||||||
@@ -3800,7 +3813,7 @@ static void uvk5_machine_init(MachineState *machine)
|
|||||||
uvk5_arm_boot_key(s);
|
uvk5_arm_boot_key(s);
|
||||||
if (g_getenv("UVK5_PC_PROBE")) {
|
if (g_getenv("UVK5_PC_PROBE")) {
|
||||||
s->pc_probe_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, uvk5_pc_probe_tick, s);
|
s->pc_probe_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, uvk5_pc_probe_tick, s);
|
||||||
timer_mod(s->pc_probe_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 100);
|
timer_mod(s->pc_probe_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + uvk5_pc_probe_interval_ms());
|
||||||
}
|
}
|
||||||
qdev_connect_gpio_out_named(DEVICE(&s->soc.gpio[0]), "pin-out", 3,
|
qdev_connect_gpio_out_named(DEVICE(&s->soc.gpio[0]), "pin-out", 3,
|
||||||
qdev_get_gpio_in_named(DEVICE(&s->flash),
|
qdev_get_gpio_in_named(DEVICE(&s->flash),
|
||||||
|
|||||||
Reference in new issue
Block a user