四个 Fault 全部采集现场:MemManage/BusFault/UsageFault 由空死循环升级
原状:HardFault 已有崩溃采集,但 MemManage / BusFault / UsageFault 仍是空
while(1) —— 这三类故障发生时日志完全静默,且因 SHCSR 默认未使能,实际会
被升级成 HardFault,报告出笼统的 "HARDFAULT"、看不出根因。
改动:
- Src/stm32f4xx_it.c:三个 Handler 升级为手工 __asm 版(取 MSP/PSP 帧指针)
-> B 到 per-fault C 入口 fault_entry_{mem,bus,usage} -> hard_fault_report()。
hard_fault_report 增加 tag 参数,日志统一为
"[ERR] <TAG> PC=.. LR=.. xPSR=.. R0-R3=.. CFSR=.. HFSR=..[/BFAR][/MMFAR]"。
生成实体经 #define X X_Gen 改名保留,链接器各移除 2 字节(.map 已验)。
三个各带独立锚点 MEMFAULT/BUSFAULT/USAGEFAULT-ANCHOR。
- 新增 fault_handler_enable()(USER CODE BEGIN 1 区):使能 SHCSR 的
MEMFAULTENA/BUSFAULTENA/USGFAULTENA。声明入 Inc/stm32f4xx_it.h,调用在
app_main_init() 第一行(纯寄存器写,不依赖日志/时钟)。
- 刻意不启用 CCR.UNALIGN_TRP / CCR.DIV_0_TRP:会把普通 bug 升级成死机,
对本项目弊大于利(说明写进函数注释)。
实现约束(本轮踩坑):ARMCC 的 __asm 块取不到 C 的数据符号(ADR r1, xxx_tag
报 A1516E: Bad symbol,去 static 也无效),也无法给 C 函数传字符串参数,
故故障名必须由 C 侧 per-fault 入口带上。
配套:
- check_cubemx_survival.py:新增 fault-handlers-3 / fault-handler-enable 两项,
UNPROTECTED_LEGACY 清掉三个 Fault(WARN 2->1),清单 16 -> 18 项。
- AGENTS.md:新增"4 个 Fault 全部采集"条目;ARMCC 汇编条目补 A1516E 第 3 坑;
校验标记补 [ERR](四个 Fault 日志都以它开头 -> 一律判 FAIL,刻意)。
- 看门狗设计说明.md:§6.1 补 4 条 Fault 标记与 @test 禁项关系;
§10.2 L3 清单与四个 Fault 采集小节;§11 结论表与变更记录。
- 待处理内容.md:新增 N-03d(已完成),N-03c 补第二次重生成结论。
验证:@build 0 错误 0 警告(Flash +156 B,RAM 无变化);pre-commit 13 钩子
全通过;审计 18 通过 / 1 警告 / 0 失败。
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
#include "app_cfg.h"
|
||||
|
||||
#include "main.h" /* ST_DIR4_GPIO_Port / ST_DIR4_Pin 等 CubeMX 宏 */
|
||||
#include "stm32f4xx_it.h" /* fault_handler_enable() */
|
||||
#include "usart.h" /* huart5 */
|
||||
#include "rs485.h"
|
||||
#include "sd2506.h"
|
||||
@@ -90,6 +91,13 @@ static void reset_cause_str(uint32_t csr, char *buf, unsigned int len) {
|
||||
* 6) 触发首次 ADC 转换
|
||||
*/
|
||||
int app_main_init(void) {
|
||||
/* 0) 使能 MemManage / BusFault / UsageFault(复位后默认只有 HardFault 使能)。
|
||||
* 必须尽早——放在所有业务初始化**之前**,这样从第一行业务代码起,
|
||||
* 任何内存/总线/非法指令类故障都会被独立捕获并打出故障名,
|
||||
* 而不是被升级成 HardFault 后只看到笼统的 "HARDFAULT"。
|
||||
* 纯寄存器写(SCB->SHCSR),不依赖日志/时钟,故放在最前无副作用。 */
|
||||
fault_handler_enable();
|
||||
|
||||
/* 日志引擎初始化(创建待发队列;须先于任何 syslog_post) */
|
||||
(void)syslog_mcu_init();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user