STM32 中__weak 弱定义函数核心总结
一、__weak 函数的本质
__weak是 ARM 编译器(如 MDK/Keil)提供的弱定义关键字,核心作用是为函数/变量提供'可被覆盖的默认实现':
- 带
__weak修饰的函数为「弱定义」,优先级低; - 用户自定义的同名无
__weak函数为「强定义」,优先级高; - 编译器会优先选择'强定义'版本,弱定义版本会被自动忽略(若存在同名强定义)。
二、STM32 中断场景下的核心应用(以串口为例)
用户自定义的强定义中断函数
开发者只需在代码中写同名无__weak的函数,即可'覆盖'默认实现:
// 用户自定义的强定义版本(中断触发时实际执行的逻辑)
void USART1_IRQHandler(void)
{
if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
uint8_t data = USART_ReceiveData(USART1); // 处理接收数据
USART_ClearITPendingBit(USART1, USART_IT_RXNE); // 清中断标志
}
}
本质:中断向量表会将该中断号(如USART1_IRQn)的函数地址,从默认弱函数替换为用户自定义函数。
系统默认的弱定义中断函数
STM32 标准库/HAL 库中,所有外设中断服务函数(如USART1_IRQHandler)都被声明为__weak,仅作为'占位符':
// 库中默认的弱定义串口 1 中断函数(空实现)
__weak void USART1_IRQHandler(void)
{
// 空逻辑/死循环,防止中断触发后找不到函数地址
}
作用:避免中断触发时因'无对应函数'导致程序崩溃,仅做兜底。
三、关键特性(新手必记)
- 非'重写':不同于 C++ 的类继承重写(Override),
__weak是 C 语言层面的'符号覆盖',无继承关系; - 可选实现:若用户不写同名强定义函数,程序会执行弱定义版本(如空中断函数);
- 核心价值:为 STM32 中断、回调函数(如 HAL 库的
HAL_UART_RxCpltCallback)提供'默认兜底 + 用户自定义'的灵活机制,降低开发门槛。
四、典型使用场景
| 场景 | 作用 |
|---|---|
| 中断服务函数 | 系统提供空的弱定义中断函数,用户按需实现具体逻辑 |
| HAL 库回调函数 | 如HAL_UART_TxCpltCallback,默认空实现,用户自定义数据发送完成后的逻辑 |

