什么是弱功能,它们的用途是什么?我正在使用stm32f429微控制器

时间:2016-02-19 14:17:38

标签: c stm32f4discovery stm32f4 stm32ldiscovery

维基百科说:

  

弱符号表示链接期间特别注释的符号   可执行和可链接格式(ELF)对象文件。默认情况下,没有   任何注释,目标文件中的符号都很强。在链接期间   强符号可以覆盖同名的弱符号。在   相反,共享名称的两个强符号会产生链接错误   在链接时。链接二进制可执行文件时,弱声明   符号不需要定义。相比之下,(默认情况下)a   声明没有定义的强符号触发未定义   符号链接错误。 C或C ++语言未提及弱符号   标准;因此,将它们插入代码中并不是非常便携。   即使两个平台支持相同或类似的标记语法   作为弱的符号,语义可能在细微的点上有所不同,例如   在运行时动态链接期间的弱符号是否会丢失   语义与否。

弱功能有哪些?它们的用途是什么?我使用的是stm32f429微控制器。库中有一些弱函数。但是我无法理解他们和他们的用途!

我在谷歌上搜索过它,但没有得到满意的答案。

3 个答案:

答案 0 :(得分:0)

当一个函数前置了描述符__weak时,它基本上意味着如果你(编码器)没有定义它,它就在这里定义。

让我们来看看我的主要对手" HAL_UART_RxCpltCallback()"。

此功能存在于STM32F4-HAL代码库的HAL中,您可以从ST-Micro下载。

在文件stm32f4xx_hal_uart.c文件中,您会发现此函数定义为:

TypeError

因此,正如此处代码中的注释所示,将此函数放在您自己的用户文件中。但是,当您这样做时,请不要加入__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 */ } 术语。这意味着链接器将定义HAL_UART_RxCpltCallback()函数,而不是stm32f4xx_hal_uart.c文件中定义的函数。

这使得通用代码库能够始终进行编译。你不必编写一大堆你不感兴趣的函数,但它会编译。在编写自己的时候,你只需要将你的自己定义为__weak并写下来。

简单?有用吗?

干杯!!

答案 1 :(得分:0)

除了“这使通用代码库能够始终编译”。 __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中重新生成。你的代码会爆炸!

答案 2 :(得分:0)

__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,用户可以使用相同的名称覆盖这个函数而不会出现任何编译器/链接器错误,这个新的函数定义将被使用