什么是弱函数,它们的用途是什么?我正在使用 stm32f429 微控制器
Posted
技术标签:
【中文标题】什么是弱函数,它们的用途是什么?我正在使用 stm32f429 微控制器【英文标题】:What are weak functions and what are their uses? I am using a stm32f429 micro controller 【发布时间】:2016-06-01 03:39:42 【问题描述】:***说:
弱符号表示链接过程中的特殊注释符号 可执行和可链接格式 (ELF) 对象文件。默认情况下,没有 任何注释,目标文件中的符号都是强的。在链接过程中, 强符号可以覆盖同名的弱符号。在 相反,共享名称的两个强符号会产生链接错误 在链接时间。链接二进制可执行文件时,弱声明 符号不需要定义。相比之下,(默认情况下)a 没有定义的声明强符号触发未定义 符号链接错误。 C 或 C++ 语言未提及弱符号 标准;因此,将它们插入代码不是很便携。 即使两个平台支持相同或相似的标记语法 符号很弱,语义可能在细微之处有所不同,例如 运行时动态链接期间的弱符号是否丢失 语义与否。
。库中有一些弱函数。但我不明白,它们和它们的用途!
我在谷歌上搜索过,但没有得到满意的答案。
【问题讨论】:
【参考方案1】:当一个函数前面带有 __weak 描述符时,它基本上意味着如果你(编码器)不定义它,它就在这里定义。
让我们看看我的宿敌“HAL_UART_RxCpltCallback()”。
此函数存在于您可以从 ST-Micro 下载的 STM32F4-HAL 代码库的 HAL 中。
在文件stm32f4xx_hal_uart.c文件中你会发现这个函数定义为:
__weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
/* NOTE: This function Should not be modified, when the callback is needed,
the HAL_UART_RxCpltCallback could be implemented in the user file
*/
因此,正如此处代码中的注释所说,将此函数放在您自己的用户文件中。但是,当您这样做时,请不要输入 __weak
术语。这意味着链接器将采用您对 HAL_UART_RxCpltCallback() 函数的定义,而不是在 stm32f4xx_hal_uart.c 文件中定义的函数。
这使通用代码库能够始终编译。您不必编写一大堆您不感兴趣的函数,但它会编译。在编写自己的代码时,您只需不要将自己的代码定义为 __weak
并编写它。
简单吗?有用吗?
干杯!!
【讨论】:
【参考方案2】:__weak 函数是可以被同名用户函数覆盖的方法,用于定义向量表和默认处理程序
普通函数编写(声明和定义)被认为是强函数名,不能重新声明函数名,你会得到编译器/链接器错误
将函数声明为可以被用户代码覆盖的星期
void USART1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
uint32_t vectors[75] __attribute__((section(".isr_vector")));
vectors[0] = STACK_START;
vectors[52] = USART1_IRQHandler;
void Default_Handler(void)
while(1);
uart1.c (user code)
void USART1_IRQHandler()
...
在上面的示例代码中,USART1_IRQHandler 被定义为弱函数并别名为 Default_handler
如果用户在 uart1.c 中定义 USART1_IRQHandler,则用户可以使用相同的名称覆盖此函数而不会出现任何编译器/链接器错误,将使用此新函数定义
【讨论】:
【参考方案3】:除了“这使通用代码库能够始终编译”。 __weak 允许您重新生成(在 CubeMX 中)您的代码,而无需触及您的 __weak +less 回调函数代码。 如果您在此编写代码:
__weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
/* NOTE: This function Should not be modified, when the callback is needed,
the HAL_UART_RxCpltCallback could be implemented in the user file
*/
并出于某种原因在 cubemx 中重新生成。你的代码会爆炸!
【讨论】:
【参考方案4】:假设我们有一个通用(库)协议接口protocol.c
,并且在接收到数据后,我们希望在我们的通信接口com.c
中执行特定于应用程序的逻辑。这可以通过弱函数来解决。
/// protocol.h
void protocol_recCallback(protocol_t *prt);
/// protocol.c
__weak void protocol_recCallback(protocol_t *prt)
void protocol_rx(protocol_t *prt)
// Common protocol interface
protocol_recCallback(prt); // This will call application specific function in com.c
/// com.c
#include "protocol.h"
void protocol_recCallback(protocol_t *prt)
// Application specific code is executed here
优势:
如果protocol_recCallback()
未在com.c
中定义。链接器不会输出未定义的引用,__weak
函数将被调用。
【讨论】:
以上是关于什么是弱函数,它们的用途是什么?我正在使用 stm32f429 微控制器的主要内容,如果未能解决你的问题,请参考以下文章