feature: tamcpp examples runnable - #13
Merged
Merged
Conversation
A1 spike(加载 TAMCPP 1_led_control 的 C++ elf 看 PC13 toggle)暴露两个被 现有 busy-loop delay_ms 样例掩盖的 bug: 1. elf_loader .data 段按 p_vaddr 加载,漏了 flash LMA 副本。裸机 startup 的 CopyDataInit 从 _sidata(=p_paddr)复制 .data 到 SRAM,但 LMA 未加载→ 读 0→SystemCoreClock 被清零→HAL_InitTick 的 SYSTICK_Config(0) 走 ERROR 不配 SysTick→HAL_Delay 死循环。改按 p_paddr 加载(p_paddr!=0 且 !=p_vaddr 时),初值落 flash LMA 让 CopyDataInit 复制,与真实烧录器行为一致;.text 段 p_vaddr==p_paddr 无变化。补 test_elf_loader: DataSegmentLoadedToFlashLmaWhenVaddrDiffers。 2. cortex_m3 线程模式 active_preempt=preempt_priority(0xFF),4 位截断成 0xF, 与最低优先级 exception(SysTick 默认 0xF0→0xF)相等,严格 < 不成立→ SysTick 不抢占线程→HAL_IncTick 不调→uwTick 不涨。改线程模式用 0xFF(不 截断),任何 exception preempt(0..0xF)均 < 0xFF 可抢占;handler 模式 nesting 不变,NVIC E2E 不破坏。 新增 examples/tamcpp_blink/ runner(spike 验证工具,elf 由外部脚本编出暂不 进 ctest;A2 串口打通时再正规化 firmware build)。 ctest 368/368 绿(含新 LMA 测试 + NVIC E2E 不破坏);spike 实测 PC13 toggle=1>0,C++ HAL 样例首次在模拟器跑通。
HAL_NVIC_SetPriority 用 strb 写 IP[IRQn],原 write 只支持 Word 返回 Unaligned → DataAccessFault。IPR 分支提前 + 按 width 更新对应字节, ISER/ICER/ISPR/ICPR 仍 Word。TAMCPP 3_uart_logger enable_interrupt 因此通。
build_sample.sh 参数化编 TAMCPP 1/2/3 C++ elf(借 STM32CubeF1,不改 TAMCPP)。
TAMCPP_ROOT cache 变量不进 git。led spike 通(PC13 toggle=1),uart TX 通
('UART Logger Ready!'),uart RX 收命令(回 ERR,链路通),button spike
诊断中(poll_events 去抖状态机卡)。加 -std=c++23(uart_driver std::expected)。
记录 elf_loader .data LMA + SysTick 优先级 + nvic IPR 字节写三 bug; led/uart TX/收命令 通;button poll_events 去抖卡(诊断中);firmware CMake 正规化。runner 加 last_fault/mmio_trace 诊断。
IT 指令(0xBF1x) mask 解码 1u<<(3-slot) 取 mask[3-slot],但 ARM 编码 slot i 的 THEN/ELSE 位是 mask[4-i](slot1→mask[3])。itt ne(mask=0xC) 和 ite ne(mask=0x4) 的 mask[2] 都是 1,旧代码无法区分,导致 ite 的 ELSE 槽用 THEN 条件执行。 实际影响:HAL_GPIO_ReadPin 的 `ite ne; movne r0,#1; moveq r0,#0` 两个 mov 都执行,r0 被 moveq 覆盖=0,ReadPin 永远返回 0(无论 IDR=0/1)。 TAMCPP 2_button_control 因此一直认为按下。 修复:3-slot → 4-slot。编码验证: itt ne=0xBF1C → slot1 mask[3]=1==1 THEN → [ne,ne] ite ne=0xBF14 → slot1 mask[3]=0≠1 ELSE → [ne,eq] itee ne=0xBF12 → [ne,eq,eq] ctest 368/368 绿。button on() 修复后在 press 段触发(ReadPin=0 正确)。
IT 块条件存在独立的 it_conditions_,SysTick 打断 HAL_GPIO_ReadPin 的 ITE 块时 handler 消费线程条件、异常返回也不恢复——IDR 恒 1 但 ReadPin 偶发返回 0,每次假按下重置 release 去抖,2_button_control 的 off() 永不触发。 异常 entry 按嵌套层级把 (it_conditions_, it_condition_pos_) 压入 suspended_it_states_ 并清空(handler 起点在 IT 块之外),return 弹出 恢复到被打断的槽位。新增 ExceptionPreservesInterruptedItBlock 回归 测试。runner_button 验证 on=1 off=1 [PASS]。ctest 369 绿。
POP {pc} 弹出 EXC_RETURN 时,write_pc 触发 interrupt_return(从 SP
弹 8 字异常帧并恢复 SP);但 t16_pop 随后用局部 sp(尚未 +4)writeback,
覆盖了 interrupt_return 刚恢复的 SP → 每次 exception 净漏 0x20。
3_uart_logger 的 USART1 RXNE 中断每收一字节 sp 偏 0x20 → line_buf
(@sp+16)地址漂移 → strb 写错位置 → handle_command 的 cmd=="LED ON"
比较恒失败 → 回 ERR: unknown command。SysTick handler 走 bx lr 不经
pop {pc},故此前一直平衡、未暴露本题。
修:pop {pc} 先 writeback sp+4、再 write_pc,让 interrupt_return 从
正确位置弹帧。runner_uart 验证 TX banner=1 RX cmd=1。notes 044 记第
6 个模拟器 bug + led/button/uart 三样例全通。
仿 hal_uart E2E 模式(E2E_TAMCPP_*_ELF 宏 + #ifdef TEST):
- TamcppLed:1_led_control PC13 toggle(while 里 HAL_Delay(500) 间 on/off,
run 80M cycles 观察首次 on)。
- TamcppButton:2_button_control 注入 PA0 idle→press→release,验 PC13 BSRR
reset/set 各触发一次(覆盖 IT block mask + ITSTATE 异常保存)。
- TamcppUart:3_uart_logger 注入 RX "LED ON\r\n",验 TX banner + RX 回
"OK: LED ON"(覆盖 pop{pc} SP 正确恢复)。
需 TAMCPP_ROOT + STM32CubeF1 双门禁(tamcpp_*_firmware target 存在)。
ctest 372 绿(+3)。
3 样例全通 + 6 bug 修完 + E2E.Tamcpp{Led,Button,Uart} 进 ctest(372 绿)。
MainWindow: - setAcceptDrops + dragEnterEvent/dropEvent:拖 .elf/.bin 到窗口即加载 - File 菜单 Open(Ctrl+O,QFileDialog):拖拽之外的另一入口 - loadFirmware 复用 reset 的 stop-timer + rebuild 路径 GpioPanel:加回 PA0 push-button(checkable,active-low:hold=press 低, release=idle 高)→ injectGpio 信号 → session.simulate_gpio_input。原 A2 按钮被移除是因 demo 固件不读 IDR,但 TAMCPP 2_button_control 的 HAL_GPIO_ReadPin 读 IDR,对它有效。 配合线 B 的 serial_panel RX 输入框 + 板视图 PC13 QuarkBulb,TAMCPP 三 样例可加载进 GUI:LED(PC13)/ button(PA0 按/放)/ uart(TX banner + RX 输入 "LED ON" 回 "OK: LED ON")。offscreen smoke 验证不崩。
原 inputSubmitted 只注入用户打的字节("LED ON"),固件 handle_command
要等 \r/\n 才触发,所以 GUI 输入命令没回复。且连续 inject_rx 多字节,
USART 的 DR 是单字节缓冲,没中间 run 会覆盖丢字节。
改:每字节 inject 后 session_.run(50000) 让 RXNE IRQ 消费该字节,结尾
追加 \r\n 触发固件行解析。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
欸超了,发现没JIT被做局了,LED 例子搞不通,上大的!