What are weak functions and what are their uses? I am using a stm32f429 micro controller
Asked Answered
M

4

33

Wikipedia says:

A weak symbol denotes a specially annotated symbol during linking of Executable and Linkable Format (ELF) object files. By default, without any annotation, a symbol in an object file is strong. During linking, a strong symbol can override a weak symbol of the same name. In contrast, two strong symbols that share a name yield a link error during link-time. When linking a binary executable, a weakly declared symbol does not need a definition. In comparison, (by default) a declared strong symbol without a definition triggers an undefined symbol link error. Weak symbols are not mentioned by C or C++ language standards; as such, inserting them into code is not very portable. Even if two platforms support the same or similar syntax for marking symbols as weak, the semantics may differ in subtle points, e.g. whether weak symbols during dynamic linking at runtime lose their semantics or not.

What are the weak functions and what are their uses? I am using an stm32f429 micro controller. There are some weak functions in the library. But I can't understand, what they and their use!

I searched about it on google but did't get a satisfactory answer.

Melodymeloid answered 19/2, 2016 at 14:17 Comment(0)
T
65

When a function is prepended with the descriptor __weak it basically means that if you (the coder) do not define it, it is defined here.

Let us take a look at my arch-nemesis "HAL_UART_RxCpltCallback()".

This function exists within the HAL of the STM32F4-HAL code base that you can download from ST-Micro.

Within the file stm32f4xx_hal_uart.c file you will find this function defined as:

__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
  */
}

So, as the note within the code here says, place this function inside your own user files. However when you do that, do not put in the __weak term. This means that the linker will take your definition of the HAL_UART_RxCpltCallback() function and not the one defined within the stm32f4xx_hal_uart.c file.

This gives the generic code base the ability to always compile. You don't have to write a whole bunch of functions that you are not interested in but it will compile. When it comes time to writing your own, you just have to NOT define yours as __weak and write it.

Simple? Helpful?

Cheers!!

Thorrlow answered 21/2, 2016 at 21:30 Comment(0)
L
7

Let's say we have a common (library) protocol interface protocol.c, and upon receiving data we wish to execute application specific logic in our communication interface com.c. This can be solved with a weak function.

/// 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
}

Advantage: If protocol_recCallback() is not defined in com.c. The linker will not output an undefined reference and the __weak function will be called.

Laryngeal answered 24/11, 2021 at 9:5 Comment(0)
I
4

__weak function are methods that can be overwritten by user function with same name, used to define vector tables, and default handlers

Normal function writing (declaration and definition) are considered strong meaning that the function name cannot be re declared, you will get compiler/linker error

Declaring the function as week it can be overwritten by user code

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(){
    ...
}

in the above sample code the USART1_IRQHandler is defined as weak function and aliased to Default_handler

User can override this function using the same name without any compiler/linker error if user define the USART1_IRQHandler in uart1.c this new function definition will be used

Idola answered 26/3, 2021 at 14:44 Comment(0)
A
2

In addition to "This gives the generic code base the ability to always compile." __weak allows you to regenerating(in CubeMX) your code without touching your __weak +less callback function code. if you write your code in this:

__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
  */
}

and regenarate in cubemx for some reason. Your code will blow up!

Antic answered 22/3, 2021 at 14:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.