8a18e388c7
原状: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 失败。
594 lines
17 KiB
C
594 lines
17 KiB
C
/* USER CODE BEGIN Header */
|
||
/**
|
||
******************************************************************************
|
||
* @file stm32f4xx_it.c
|
||
* @brief Interrupt Service Routines.
|
||
******************************************************************************
|
||
* @attention
|
||
*
|
||
* Copyright (c) 2026 STMicroelectronics.
|
||
* All rights reserved.
|
||
*
|
||
* This software is licensed under terms that can be found in the LICENSE file
|
||
* in the root directory of this software component.
|
||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||
*
|
||
******************************************************************************
|
||
*/
|
||
/* USER CODE END Header */
|
||
|
||
/* Includes ------------------------------------------------------------------*/
|
||
#include "main.h"
|
||
#include "stm32f4xx_it.h"
|
||
/* Private includes ----------------------------------------------------------*/
|
||
/* USER CODE BEGIN Includes */
|
||
#include "usart.h"
|
||
/* USER CODE END Includes */
|
||
|
||
/* Private typedef -----------------------------------------------------------*/
|
||
/* USER CODE BEGIN TD */
|
||
|
||
/* USER CODE END TD */
|
||
|
||
/* Private define ------------------------------------------------------------*/
|
||
/* USER CODE BEGIN PD */
|
||
|
||
/* USER CODE END PD */
|
||
|
||
/* Private macro -------------------------------------------------------------*/
|
||
/* USER CODE BEGIN PM */
|
||
|
||
/* USER CODE END PM */
|
||
|
||
/* Private variables ---------------------------------------------------------*/
|
||
/* USER CODE BEGIN PV */
|
||
|
||
/* USER CODE END PV */
|
||
|
||
/* Private function prototypes -----------------------------------------------*/
|
||
/* USER CODE BEGIN PFP */
|
||
|
||
/* USER CODE END PFP */
|
||
|
||
/* Private user code ---------------------------------------------------------*/
|
||
/* USER CODE BEGIN 0 */
|
||
|
||
/* HardFault 现场报告实现(2026-09-29 迁移至此,**保护区**内):
|
||
* 原放在紧随 HardFault_Handler 之后的自造区 `HardFault_Report` 里——
|
||
* 实测 CubeMX 重生成不会保留"生成区之外的自造标记区"(它整段按新模板重写),
|
||
* 故迁入本文件本来就有的 `USER CODE BEGIN 0`(生成区内的标准保护位),
|
||
* 从此重生成不会丢失。
|
||
*
|
||
* 说明:本函数由 __asm void HardFault_Handler 用 B 直接跳入(见下方),
|
||
* 不经内核、不 printf、不遍历指针,只用 HAL_UART_Transmit 轮询 + SCB 寄存器读取,
|
||
* 因此在内核状态已不可信时仍可用。输出后 HAL_Delay(200) 排空 UART 再复位。
|
||
*/
|
||
static void hard_fault_write(const char *s, uint16_t len)
|
||
{
|
||
/* 显式长度 + 有界单次发送:上报路径自身不得再崩(2026-09-24 加固;
|
||
* 不做 '\0' 遍历,长度由调用方 sizeof 给出) */
|
||
if ((s == NULL) || (len == 0u)) {
|
||
return;
|
||
}
|
||
if (len > 64u) {
|
||
len = 64u;
|
||
}
|
||
HAL_UART_Transmit(&huart1, (const uint8_t *)s, len, 0xFFFFu);
|
||
}
|
||
|
||
/* 字面量输出宏:长度由 sizeof 定,编译期即可确定 */
|
||
#define HF_PUTS(lit) hard_fault_write((lit), (uint16_t)(sizeof(lit) - 1u))
|
||
|
||
static void hard_fault_puthex(uint32_t v)
|
||
{
|
||
static const char digits[] = "0123456789ABCDEF";
|
||
char out[9];
|
||
int i;
|
||
|
||
for (i = 0; i < 8; i++) {
|
||
out[i] = digits[(v >> (28 - i * 4)) & 0xFu];
|
||
}
|
||
out[8] = '\0';
|
||
hard_fault_write(out, 8u);
|
||
}
|
||
|
||
/* 崩溃现场报告核心(四个 Fault 共用)。
|
||
* 入口参数:tag - 故障名(ASCII 字面量,如 "HARDFAULT" / "MEMFAULT")
|
||
* frame - 异常栈帧 {R0,R1,R2,R3,R12,LR,PC,xPSR}
|
||
* 说明:CFSR 一次性打出,其子域已含 MMARVALID(bit7)/BFARVALID(bit15),
|
||
* 故 MMFAR/BFAR 的"是否有意义"由 CFSR 判定,四个 Fault 都能看全。
|
||
*
|
||
* ⚠ 本函数**不直接**被异常向量调用——异常入口是下方的 `__asm` 版 Handler,
|
||
* 它们只负责取异常帧指针,然后 `B` 到下面 4 个 per-fault 入口之一
|
||
* (每个入口自带 tag 字面量后再调本函数)。
|
||
* 这样做的原因:ARMCC 的 `__asm` 块**取不到 C 的 static 数据符号**
|
||
* (实测:`ADR r1, xxx_tag` 报 `A1516E: Bad symbol`,去掉 static 也无效),
|
||
* 而 `__asm` 里也无法给 C 函数传结构体/字符串参数。故把"带 tag"这一步
|
||
* 放在普通 C 函数里做。
|
||
*/
|
||
void hard_fault_report(const char *tag, uint32_t *frame)
|
||
{
|
||
HF_PUTS("\r\n[ERR] ");
|
||
hard_fault_write(tag, 16u);
|
||
HF_PUTS(" PC=");
|
||
hard_fault_puthex(frame[6]);
|
||
HF_PUTS(" LR=");
|
||
hard_fault_puthex(frame[5]);
|
||
HF_PUTS(" xPSR=");
|
||
hard_fault_puthex(frame[7]);
|
||
HF_PUTS(" R0=");
|
||
hard_fault_puthex(frame[0]);
|
||
HF_PUTS(" R1=");
|
||
hard_fault_puthex(frame[1]);
|
||
HF_PUTS(" R2=");
|
||
hard_fault_puthex(frame[2]);
|
||
HF_PUTS(" R3=");
|
||
hard_fault_puthex(frame[3]);
|
||
HF_PUTS(" CFSR=");
|
||
hard_fault_puthex(SCB->CFSR);
|
||
HF_PUTS(" HFSR=");
|
||
hard_fault_puthex(SCB->HFSR);
|
||
|
||
/* BFAR/MMFAR 仅在对应 valid 位为 1 时有意义 */
|
||
if ((SCB->CFSR & (1UL << 15)) != 0U) {
|
||
HF_PUTS(" BFAR=");
|
||
hard_fault_puthex(SCB->BFAR);
|
||
}
|
||
if ((SCB->CFSR & (1UL << 7)) != 0U) {
|
||
HF_PUTS(" MMFAR=");
|
||
hard_fault_puthex(SCB->MMFAR);
|
||
}
|
||
|
||
HAL_Delay(200);
|
||
NVIC_SystemReset();
|
||
}
|
||
|
||
/* 四个 per-fault 入口:__asm Handler 取到帧指针后 `B` 到这里,由 C 补上故障名。
|
||
* 名字用 `fault_entry_*` 前缀,与向量符号(`*_Handler`)区分开。 */
|
||
void fault_entry_hard(uint32_t *frame)
|
||
{
|
||
hard_fault_report("HARDFAULT", frame);
|
||
}
|
||
|
||
void fault_entry_mem(uint32_t *frame)
|
||
{
|
||
hard_fault_report("MEMFAULT", frame);
|
||
}
|
||
|
||
void fault_entry_bus(uint32_t *frame)
|
||
{
|
||
hard_fault_report("BUSFAULT", frame);
|
||
}
|
||
|
||
void fault_entry_usage(uint32_t *frame)
|
||
{
|
||
hard_fault_report("USAGEFAULT", frame);
|
||
}
|
||
|
||
/* 为生成函数改名,避免与下方手工 `__asm` 实现符号冲突。
|
||
* 生成实体改名为 <原名>_Gen(永不执行,仅为占名字不冲突,
|
||
* 保持生成区代码零删除;未被引用 → 链接器自动移除)。
|
||
*
|
||
* 覆盖的 4 个 Cortex-M4 异常:HardFault / MemManage / BusFault / UsageFault。
|
||
* 后三者须在 SHCSR 中使能对应位才会真正触发(见 fault_handler_enable)。 */
|
||
#define HardFault_Handler HardFault_Handler_Gen
|
||
#define MemManage_Handler MemManage_Handler_Gen
|
||
#define BusFault_Handler BusFault_Handler_Gen
|
||
#define UsageFault_Handler UsageFault_Handler_Gen
|
||
/* USER CODE END 0 */
|
||
|
||
/* External variables --------------------------------------------------------*/
|
||
extern DMA_HandleTypeDef hdma_spi1_rx;
|
||
extern DMA_HandleTypeDef hdma_spi1_tx;
|
||
extern DMA_HandleTypeDef hdma_spi2_rx;
|
||
extern DMA_HandleTypeDef hdma_spi2_tx;
|
||
extern SPI_HandleTypeDef hspi1;
|
||
extern SPI_HandleTypeDef hspi2;
|
||
extern DMA_HandleTypeDef hdma_usart1_tx;
|
||
extern DMA_HandleTypeDef hdma_usart1_rx;
|
||
extern UART_HandleTypeDef huart4;
|
||
extern UART_HandleTypeDef huart5;
|
||
extern UART_HandleTypeDef huart1;
|
||
extern UART_HandleTypeDef huart2;
|
||
extern UART_HandleTypeDef huart3;
|
||
extern TIM_HandleTypeDef htim7;
|
||
|
||
/* USER CODE BEGIN EV */
|
||
|
||
/* USER CODE END EV */
|
||
|
||
/******************************************************************************/
|
||
/* Cortex-M4 Processor Interruption and Exception Handlers */
|
||
/******************************************************************************/
|
||
/**
|
||
* @brief This function handles Non maskable interrupt.
|
||
*/
|
||
void NMI_Handler(void)
|
||
{
|
||
/* USER CODE BEGIN NonMaskableInt_IRQn 0 */
|
||
|
||
/* USER CODE END NonMaskableInt_IRQn 0 */
|
||
/* USER CODE BEGIN NonMaskableInt_IRQn 1 */
|
||
while (1)
|
||
{
|
||
}
|
||
/* USER CODE END NonMaskableInt_IRQn 1 */
|
||
}
|
||
|
||
/**
|
||
* @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)
|
||
{
|
||
extern fault_entry_hard
|
||
TST lr, #4
|
||
ITE EQ
|
||
MRSEQ r0, MSP
|
||
MRSNE r0, PSP
|
||
B fault_entry_hard
|
||
}
|
||
|
||
void HardFault_Handler_Gen(void)
|
||
{
|
||
while (1)
|
||
{
|
||
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
|
||
/* USER CODE END W1_HardFault_IRQn 0 */
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @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)
|
||
{
|
||
extern fault_entry_mem
|
||
TST lr, #4
|
||
ITE EQ
|
||
MRSEQ r0, MSP
|
||
MRSNE r0, PSP
|
||
B fault_entry_mem
|
||
}
|
||
|
||
void MemManage_Handler_Gen(void)
|
||
{
|
||
while (1)
|
||
{
|
||
/* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
|
||
/* USER CODE END W1_MemoryManagement_IRQn 0 */
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @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)
|
||
{
|
||
extern fault_entry_bus
|
||
TST lr, #4
|
||
ITE EQ
|
||
MRSEQ r0, MSP
|
||
MRSNE r0, PSP
|
||
B fault_entry_bus
|
||
}
|
||
|
||
void BusFault_Handler_Gen(void)
|
||
{
|
||
while (1)
|
||
{
|
||
/* USER CODE BEGIN W1_BusFault_IRQn 0 */
|
||
/* USER CODE END W1_BusFault_IRQn 0 */
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @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)
|
||
{
|
||
extern fault_entry_usage
|
||
TST lr, #4
|
||
ITE EQ
|
||
MRSEQ r0, MSP
|
||
MRSNE r0, PSP
|
||
B fault_entry_usage
|
||
}
|
||
|
||
void UsageFault_Handler_Gen(void)
|
||
{
|
||
while (1)
|
||
{
|
||
/* USER CODE BEGIN W1_UsageFault_IRQn 0 */
|
||
/* USER CODE END W1_UsageFault_IRQn 0 */
|
||
}
|
||
}
|
||
|
||
/* USER CODE BEGIN 1 */
|
||
|
||
/* 使能 MemManage / BusFault / UsageFault 三个异常。
|
||
*
|
||
* 为什么必须做:复位后 SCB->SHCSR 只开了 HardFault,后三者处于**禁用**状态——
|
||
* 它们触发时会被升级成 HardFault,`hard_fault_report` 打出来的是 "HARDFAULT"
|
||
* 且看不出根因。这里逐个置使能位,日志里才能直接看到 MEMFAULT / BUSFAULT /
|
||
* USAGEFAULT 字样。
|
||
*
|
||
* ⚠ 刻意**不**打开以下两项(都会把普通 bug 升级成死机,对本项目弊大于利):
|
||
* - CCR.UNALIGN_TRP :非对齐访问陷入。Cortex-M4 硬件本可处理非对齐访问,
|
||
* 打开后协议解析里常见的非对齐取字段会直接死机。
|
||
* - CCR.DIV_0_TRP :除零陷入。除零应由业务代码自己判,不要靠硬件兜。
|
||
* 打开它们只会让"本该只是算错个值"变成"整机复位"。
|
||
*
|
||
* 调用时机:app_main_init() 早期(日志可用前即可,越早越好)。
|
||
*/
|
||
void fault_handler_enable(void)
|
||
{
|
||
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk |
|
||
SCB_SHCSR_BUSFAULTENA_Msk |
|
||
SCB_SHCSR_USGFAULTENA_Msk;
|
||
}
|
||
|
||
/* USER CODE END 1 */
|
||
|
||
/**
|
||
* @brief This function handles Debug monitor.
|
||
*/
|
||
void DebugMon_Handler(void)
|
||
{
|
||
/* USER CODE BEGIN DebugMonitor_IRQn 0 */
|
||
|
||
/* USER CODE END DebugMonitor_IRQn 0 */
|
||
/* USER CODE BEGIN DebugMonitor_IRQn 1 */
|
||
|
||
/* USER CODE END DebugMonitor_IRQn 1 */
|
||
}
|
||
|
||
/******************************************************************************/
|
||
/* STM32F4xx Peripheral Interrupt Handlers */
|
||
/* Add here the Interrupt Handlers for the used peripherals. */
|
||
/* For the available peripheral interrupt handler names, */
|
||
/* please refer to the startup file (startup_stm32f4xx.s). */
|
||
/******************************************************************************/
|
||
|
||
/**
|
||
* @brief This function handles DMA1 stream3 global interrupt.
|
||
*/
|
||
void DMA1_Stream3_IRQHandler(void)
|
||
{
|
||
/* USER CODE BEGIN DMA1_Stream3_IRQn 0 */
|
||
|
||
/* USER CODE END DMA1_Stream3_IRQn 0 */
|
||
HAL_DMA_IRQHandler(&hdma_spi2_rx);
|
||
/* USER CODE BEGIN DMA1_Stream3_IRQn 1 */
|
||
|
||
/* USER CODE END DMA1_Stream3_IRQn 1 */
|
||
}
|
||
|
||
/**
|
||
* @brief This function handles DMA1 stream4 global interrupt.
|
||
*/
|
||
void DMA1_Stream4_IRQHandler(void)
|
||
{
|
||
/* USER CODE BEGIN DMA1_Stream4_IRQn 0 */
|
||
|
||
/* USER CODE END DMA1_Stream4_IRQn 0 */
|
||
HAL_DMA_IRQHandler(&hdma_spi2_tx);
|
||
/* USER CODE BEGIN DMA1_Stream4_IRQn 1 */
|
||
|
||
/* USER CODE END DMA1_Stream4_IRQn 1 */
|
||
}
|
||
|
||
/**
|
||
* @brief This function handles EXTI line[9:5] interrupts.
|
||
*/
|
||
void EXTI9_5_IRQHandler(void)
|
||
{
|
||
/* USER CODE BEGIN EXTI9_5_IRQn 0 */
|
||
|
||
/* USER CODE END EXTI9_5_IRQn 0 */
|
||
HAL_GPIO_EXTI_IRQHandler(TP_BUSY_Pin);
|
||
/* USER CODE BEGIN EXTI9_5_IRQn 1 */
|
||
|
||
/* USER CODE END EXTI9_5_IRQn 1 */
|
||
}
|
||
|
||
/**
|
||
* @brief This function handles SPI1 global interrupt.
|
||
*/
|
||
void SPI1_IRQHandler(void)
|
||
{
|
||
/* USER CODE BEGIN SPI1_IRQn 0 */
|
||
|
||
/* USER CODE END SPI1_IRQn 0 */
|
||
HAL_SPI_IRQHandler(&hspi1);
|
||
/* USER CODE BEGIN SPI1_IRQn 1 */
|
||
|
||
/* USER CODE END SPI1_IRQn 1 */
|
||
}
|
||
|
||
/**
|
||
* @brief This function handles SPI2 global interrupt.
|
||
*/
|
||
void SPI2_IRQHandler(void)
|
||
{
|
||
/* USER CODE BEGIN SPI2_IRQn 0 */
|
||
|
||
/* USER CODE END SPI2_IRQn 0 */
|
||
HAL_SPI_IRQHandler(&hspi2);
|
||
/* USER CODE BEGIN SPI2_IRQn 1 */
|
||
|
||
/* USER CODE END SPI2_IRQn 1 */
|
||
}
|
||
|
||
/**
|
||
* @brief This function handles USART1 global interrupt.
|
||
*/
|
||
void USART1_IRQHandler(void)
|
||
{
|
||
/* USER CODE BEGIN USART1_IRQn 0 */
|
||
|
||
/* USER CODE END USART1_IRQn 0 */
|
||
HAL_UART_IRQHandler(&huart1);
|
||
/* USER CODE BEGIN USART1_IRQn 1 */
|
||
|
||
/* USER CODE END USART1_IRQn 1 */
|
||
}
|
||
|
||
/**
|
||
* @brief This function handles USART2 global interrupt.
|
||
*/
|
||
void USART2_IRQHandler(void)
|
||
{
|
||
/* USER CODE BEGIN USART2_IRQn 0 */
|
||
|
||
/* USER CODE END USART2_IRQn 0 */
|
||
HAL_UART_IRQHandler(&huart2);
|
||
/* USER CODE BEGIN USART2_IRQn 1 */
|
||
|
||
/* USER CODE END USART2_IRQn 1 */
|
||
}
|
||
|
||
/**
|
||
* @brief This function handles USART3 global interrupt.
|
||
*/
|
||
void USART3_IRQHandler(void)
|
||
{
|
||
/* USER CODE BEGIN USART3_IRQn 0 */
|
||
|
||
/* USER CODE END USART3_IRQn 0 */
|
||
HAL_UART_IRQHandler(&huart3);
|
||
/* USER CODE BEGIN USART3_IRQn 1 */
|
||
|
||
/* USER CODE END USART3_IRQn 1 */
|
||
}
|
||
|
||
/**
|
||
* @brief This function handles UART4 global interrupt.
|
||
*/
|
||
void UART4_IRQHandler(void)
|
||
{
|
||
/* USER CODE BEGIN UART4_IRQn 0 */
|
||
|
||
/* USER CODE END UART4_IRQn 0 */
|
||
HAL_UART_IRQHandler(&huart4);
|
||
/* USER CODE BEGIN UART4_IRQn 1 */
|
||
|
||
/* USER CODE END UART4_IRQn 1 */
|
||
}
|
||
|
||
/**
|
||
* @brief This function handles UART5 global interrupt.
|
||
*/
|
||
void UART5_IRQHandler(void)
|
||
{
|
||
/* USER CODE BEGIN UART5_IRQn 0 */
|
||
|
||
/* USER CODE END UART5_IRQn 0 */
|
||
HAL_UART_IRQHandler(&huart5);
|
||
/* USER CODE BEGIN UART5_IRQn 1 */
|
||
|
||
/* USER CODE END UART5_IRQn 1 */
|
||
}
|
||
|
||
/**
|
||
* @brief This function handles TIM7 global interrupt.
|
||
*/
|
||
void TIM7_IRQHandler(void)
|
||
{
|
||
/* USER CODE BEGIN TIM7_IRQn 0 */
|
||
|
||
/* USER CODE END TIM7_IRQn 0 */
|
||
HAL_TIM_IRQHandler(&htim7);
|
||
/* USER CODE BEGIN TIM7_IRQn 1 */
|
||
|
||
/* USER CODE END TIM7_IRQn 1 */
|
||
}
|
||
|
||
/**
|
||
* @brief This function handles DMA2 stream0 global interrupt.
|
||
*/
|
||
void DMA2_Stream0_IRQHandler(void)
|
||
{
|
||
/* USER CODE BEGIN DMA2_Stream0_IRQn 0 */
|
||
|
||
/* USER CODE END DMA2_Stream0_IRQn 0 */
|
||
HAL_DMA_IRQHandler(&hdma_spi1_rx);
|
||
/* USER CODE BEGIN DMA2_Stream0_IRQn 1 */
|
||
|
||
/* USER CODE END DMA2_Stream0_IRQn 1 */
|
||
}
|
||
|
||
/**
|
||
* @brief This function handles DMA2 stream2 global interrupt.
|
||
*/
|
||
void DMA2_Stream2_IRQHandler(void)
|
||
{
|
||
/* USER CODE BEGIN DMA2_Stream2_IRQn 0 */
|
||
|
||
/* USER CODE END DMA2_Stream2_IRQn 0 */
|
||
HAL_DMA_IRQHandler(&hdma_usart1_rx);
|
||
/* USER CODE BEGIN DMA2_Stream2_IRQn 1 */
|
||
|
||
/* USER CODE END DMA2_Stream2_IRQn 1 */
|
||
}
|
||
|
||
/**
|
||
* @brief This function handles DMA2 stream3 global interrupt.
|
||
*/
|
||
void DMA2_Stream3_IRQHandler(void)
|
||
{
|
||
/* USER CODE BEGIN DMA2_Stream3_IRQn 0 */
|
||
|
||
/* USER CODE END DMA2_Stream3_IRQn 0 */
|
||
HAL_DMA_IRQHandler(&hdma_spi1_tx);
|
||
/* USER CODE BEGIN DMA2_Stream3_IRQn 1 */
|
||
|
||
/* USER CODE END DMA2_Stream3_IRQn 1 */
|
||
}
|
||
|
||
/**
|
||
* @brief This function handles DMA2 stream7 global interrupt.
|
||
*/
|
||
void DMA2_Stream7_IRQHandler(void)
|
||
{
|
||
/* USER CODE BEGIN DMA2_Stream7_IRQn 0 */
|
||
|
||
/* USER CODE END DMA2_Stream7_IRQn 0 */
|
||
HAL_DMA_IRQHandler(&hdma_usart1_tx);
|
||
/* USER CODE BEGIN DMA2_Stream7_IRQn 1 */
|
||
|
||
/* USER CODE END DMA2_Stream7_IRQn 1 */
|
||
}
|
||
|
||
/* USER CODE BEGIN 1 */
|
||
|
||
/* USER CODE END 1 */
|