4 个 Fault Handler 迁入 USER CODE BEGIN 0(L3→L2):生成区恢复 CubeMX 原样,重生成零 diff
This commit is contained in:
+81
-78
@@ -165,7 +165,67 @@ void fault_entry_usage(uint32_t *frame)
|
||||
hard_fault_report("USAGEFAULT", frame);
|
||||
}
|
||||
|
||||
/* 为生成函数改名,避免与下方手工 `__asm` 实现符号冲突。
|
||||
/* ==== 4 个异常入口:__asm 版 Handler(符号与向量表一致)====
|
||||
* ⚠ **必须写在下面 4 个 `#define X X_Gen` 之前**——写在之后会被自己的宏改名。
|
||||
* 2026-10-09 从生成区迁入本保护区:此前放在生成区内(L3),每次 CubeMX 重生成
|
||||
* 都被抹掉、需 `git checkout HEAD -- Src/stm32f4xx_it.c` 复原;现在生成区保持
|
||||
* CubeMX 原样,重生成零改动。
|
||||
*
|
||||
* 原理:EXC_RETURN bit2(`TST lr, #4`)判断异常帧在 MSP 还是 PSP,取帧指针后
|
||||
* `B` 到上面的 per-fault C 入口。CubeMX 默认的空 `while(1)` 版会让死机在日志上
|
||||
* **完全静默**(2026-09-20 实证)。
|
||||
* ⚠ ARMCC 语法:内联汇编**只能**用整函数 `__asm void f(void) {...}` 形态。
|
||||
* `__asm volatile("MRS %0, lr" : "=r"(x))`(GCC 语法)报 #18;
|
||||
* `__asm { MRS x, lr }` 块内联会把寄存器名当 C 标识符报 #20(2026-09-29 实测)。
|
||||
*/
|
||||
__asm void HardFault_Handler(void)
|
||||
{
|
||||
extern fault_entry_hard
|
||||
TST lr, #4
|
||||
ITE EQ
|
||||
MRSEQ r0, MSP
|
||||
MRSNE r0, PSP
|
||||
B fault_entry_hard
|
||||
}
|
||||
|
||||
/* MEMFAULT:访问 MPU 禁止区 / 非法特权级访问。须 SHCSR 的 MEMFAULTENA(bit16) 使能。
|
||||
* 命中时 CFSR 的 MMARVALID(bit7) 置 1,MMFAR 记录出错地址(报告函数按此判定)。 */
|
||||
__asm void MemManage_Handler(void)
|
||||
{
|
||||
extern fault_entry_mem
|
||||
TST lr, #4
|
||||
ITE EQ
|
||||
MRSEQ r0, MSP
|
||||
MRSNE r0, PSP
|
||||
B fault_entry_mem
|
||||
}
|
||||
|
||||
/* BUSFAULT:非法总线访问 / 取指(外设时钟未开、错误指针、DMA 越界等)。
|
||||
* 须 SHCSR 的 BUSFAULTENA(bit17) 使能。命中时 CFSR 的 BFARVALID(bit15) 置 1。 */
|
||||
__asm void BusFault_Handler(void)
|
||||
{
|
||||
extern fault_entry_bus
|
||||
TST lr, #4
|
||||
ITE EQ
|
||||
MRSEQ r0, MSP
|
||||
MRSNE r0, PSP
|
||||
B fault_entry_bus
|
||||
}
|
||||
|
||||
/* USAGEFAULT:未定义指令 / 非对齐访问 / 除零(须 DIV_0_TRP)/ 非法状态。
|
||||
* 须 SHCSR 的 USGFAULTENA(bit18) 使能。
|
||||
* ⚠ 本项目**刻意不使用硬件除零陷入**(C 代码里除零应自己判,避免把普通 bug 升级为死机)。 */
|
||||
__asm void UsageFault_Handler(void)
|
||||
{
|
||||
extern fault_entry_usage
|
||||
TST lr, #4
|
||||
ITE EQ
|
||||
MRSEQ r0, MSP
|
||||
MRSNE r0, PSP
|
||||
B fault_entry_usage
|
||||
}
|
||||
|
||||
/* 为生成函数改名,避免与上面手工 `__asm` 实现符号冲突。
|
||||
* 生成实体改名为 <原名>_Gen(永不执行,仅为占名字不冲突,
|
||||
* 保持生成区代码零删除;未被引用 → 链接器自动移除)。
|
||||
*
|
||||
@@ -216,36 +276,13 @@ void NMI_Handler(void)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Hard fault interrupt.
|
||||
*/
|
||||
/* HARD-FAULT-ANCHOR — 本锚点与下方改动一体,重生成会一并消失,
|
||||
* 供 scripts/check_cubemx_survival.py 检出(勿删):
|
||||
*
|
||||
* 崩溃现场采集(手工改写)。EXC_RETURN bit2 判断异常帧在 MSP 还是 PSP,
|
||||
* 取帧指针交给 C 报告函数 hard_fault_report()(实现在文件头 USER CODE BEGIN 0
|
||||
* 保护区内)。空 while(1) 版会让死机在日志上完全静默(2026-09-20 实证)。
|
||||
*
|
||||
* 命名:`#undef HardFault_Handler` 后重定义为 __asm 版本,与向量表符号一致;
|
||||
* 为避免与下方生成实体"重复定义"(ARMCC 报 #247,其"已定义"检查
|
||||
* 早于 C 作用域),已在文件头用 `#define HardFault_Handler
|
||||
* HardFault_Handler_Gen` 把生成实体改名为不冲突的符号。
|
||||
*
|
||||
* ⚠ ARMCC 语法:内联汇编**只能**用整函数 `__asm void f(void) {...}` 形态。
|
||||
* `__asm volatile("MRS %0, lr" : "=r"(x))`(GCC 语法)报 #18;
|
||||
* `__asm { MRS x, lr }` 块内联会把寄存器名当 C 标识符报 #20(2026-09-29 实测)。 */
|
||||
#undef HardFault_Handler
|
||||
__asm void HardFault_Handler(void)
|
||||
* @brief This function handles Hard fault interrupt.
|
||||
*/
|
||||
void HardFault_Handler(void)
|
||||
{
|
||||
extern fault_entry_hard
|
||||
TST lr, #4
|
||||
ITE EQ
|
||||
MRSEQ r0, MSP
|
||||
MRSNE r0, PSP
|
||||
B fault_entry_hard
|
||||
}
|
||||
/* USER CODE BEGIN HardFault_IRQn 0 */
|
||||
|
||||
void HardFault_Handler_Gen(void)
|
||||
{
|
||||
/* USER CODE END HardFault_IRQn 0 */
|
||||
while (1)
|
||||
{
|
||||
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
|
||||
@@ -254,24 +291,13 @@ void HardFault_Handler_Gen(void)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Memory management fault.
|
||||
*/
|
||||
/* MEMFAULT-ANCHOR — 见 HARD-FAULT-ANCHOR(同一套采集方案,勿删本锚点)
|
||||
* 触发条件:访问 MPU 禁止区 / 非法特权级访问。须 SHCSR 的 MEMFAULTENA(bit16) 使能。
|
||||
* 命中时 CFSR 的 MMARVALID(bit7) 置 1,MMFAR 记录出错地址(报告函数按此判定)。 */
|
||||
#undef MemManage_Handler
|
||||
__asm void MemManage_Handler(void)
|
||||
* @brief This function handles Memory management fault.
|
||||
*/
|
||||
void MemManage_Handler(void)
|
||||
{
|
||||
extern fault_entry_mem
|
||||
TST lr, #4
|
||||
ITE EQ
|
||||
MRSEQ r0, MSP
|
||||
MRSNE r0, PSP
|
||||
B fault_entry_mem
|
||||
}
|
||||
/* USER CODE BEGIN MemoryManagement_IRQn 0 */
|
||||
|
||||
void MemManage_Handler_Gen(void)
|
||||
{
|
||||
/* USER CODE END MemoryManagement_IRQn 0 */
|
||||
while (1)
|
||||
{
|
||||
/* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
|
||||
@@ -280,24 +306,13 @@ void MemManage_Handler_Gen(void)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Pre-fetch fault, memory access fault.
|
||||
*/
|
||||
/* BUSFAULT-ANCHOR — 见 HARD-FAULT-ANCHOR(同一套采集方案,勿删本锚点)
|
||||
* 触发条件:非法总线访问 / 取指(外设时钟未开、错误指针、DMA 越界等)。
|
||||
* 须 SHCSR 的 BUSFAULTENA(bit17) 使能。命中时 CFSR 的 BFARVALID(bit15) 置 1。 */
|
||||
#undef BusFault_Handler
|
||||
__asm void BusFault_Handler(void)
|
||||
* @brief This function handles Pre-fetch fault, memory access fault.
|
||||
*/
|
||||
void BusFault_Handler(void)
|
||||
{
|
||||
extern fault_entry_bus
|
||||
TST lr, #4
|
||||
ITE EQ
|
||||
MRSEQ r0, MSP
|
||||
MRSNE r0, PSP
|
||||
B fault_entry_bus
|
||||
}
|
||||
/* USER CODE BEGIN BusFault_IRQn 0 */
|
||||
|
||||
void BusFault_Handler_Gen(void)
|
||||
{
|
||||
/* USER CODE END BusFault_IRQn 0 */
|
||||
while (1)
|
||||
{
|
||||
/* USER CODE BEGIN W1_BusFault_IRQn 0 */
|
||||
@@ -306,25 +321,13 @@ void BusFault_Handler_Gen(void)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Undefined instruction or illegal state.
|
||||
*/
|
||||
/* USAGEFAULT-ANCHOR — 见 HARD-FAULT-ANCHOR(同一套采集方案,勿删本锚点)
|
||||
* 触发条件:未定义指令 / 非对齐访问 / 除零(须 DIV_0_TRP)/ 非法状态。
|
||||
* 须 SHCSR 的 USGFAULTENA(bit18) 使能。
|
||||
* ⚠ 本项目**刻意不使用硬件除零陷入**(C 代码里除零应自己判,避免把普通 bug 升级为死机)。 */
|
||||
#undef UsageFault_Handler
|
||||
__asm void UsageFault_Handler(void)
|
||||
* @brief This function handles Undefined instruction or illegal state.
|
||||
*/
|
||||
void UsageFault_Handler(void)
|
||||
{
|
||||
extern fault_entry_usage
|
||||
TST lr, #4
|
||||
ITE EQ
|
||||
MRSEQ r0, MSP
|
||||
MRSNE r0, PSP
|
||||
B fault_entry_usage
|
||||
}
|
||||
/* USER CODE BEGIN UsageFault_IRQn 0 */
|
||||
|
||||
void UsageFault_Handler_Gen(void)
|
||||
{
|
||||
/* USER CODE END UsageFault_IRQn 0 */
|
||||
while (1)
|
||||
{
|
||||
/* USER CODE BEGIN W1_UsageFault_IRQn 0 */
|
||||
|
||||
Reference in New Issue
Block a user