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