Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem


Loading

FreeRTOS won't build on GCC if Linker Time Optimization is set (issue for STM32 ARM CM-7 - port.c:427: undefined reference to `vTaskSwitchContext)

Posted by daveharr on March 10, 2017

Hello, FreeRTOS won't build on GCC if Link-Time Optimization (-flto) is set. (issue for STM32 ARM CM-7) I consistently get this error in port.c:427: undefined reference to vTaskSwitchContext).

The vTaskSwitchContext() function is clearly defined in tasks.c. This problem can be fixed in tasks.h if vTaskSwitchContext is declared thus at line 2172: void vTaskSwitchContext( void ) PRIVILEGED_FUNCTION attribute((used)); For some reason the double underscores before and after the word attribute do not appear in the post.

Can you fix this so that this is include in the next release? I realize this is GCC dependent so you'd have to make it apply only for a GCC build.

Thanks.


FreeRTOS won't build on GCC if Linker Time Optimization is set (issue for STM32 ARM CM-7 - port.c:427: undefined reference to `vTaskSwitchContext)

Posted by rtel on March 10, 2017

We can't put GCC specific code in a non-GCC specific file. What happens if you add this prototype to the port.c file specific to the Cortex-M port you are using? Then there will be two prototypes for the same function visible to the file, so it might puke.


FreeRTOS won't build on GCC if Linker Time Optimization is set (issue for STM32 ARM CM-7 - port.c:427: undefined reference to `vTaskSwitchContext)

Posted by daveharr on March 10, 2017

I tried that - i.e. putting the prototype

void vTaskSwitchContext( void ) PRIVILEGED_FUNCTION attribute((used));

in port.c. The GCC compiler doesn't object but it doesn't get rid of the undefined reference to vTaskSwitchContext either. That is because the link time optimizer is optimizing away the actual vTaskSwitchContext function defined in tasks.c because it doesn't see it referenced anywhere. It is the tasks.c source code file that needs to have that prototype, or the equivalent of it somewhere.


FreeRTOS won't build on GCC if Linker Time Optimization is set (issue for STM32 ARM CM-7 - port.c:427: undefined reference to `vTaskSwitchContext)

Posted by xz8987f on March 10, 2017

This is what I have done in all my FreeRTOS ports: Using this in task.h: ~~~

ifdef GNUC /* << EST: 'used' attribute need for LTO (Link Time Optimization) */

void vTaskSwitchContext( void ) PRIVILEGED_FUNCTION attribute((used));

else

void vTaskSwitchContext( void ) PRIVILEGED_FUNCTION;

endif

~~~

Using this in task.c: ~~~

ifdef GNUC /* << EST */

attribute((used)) /* using C++ compiler, vTaskSwitchContext() might be removed even with -O0? */

endif

void vTaskSwitchContext( void ) ~~~

I have seen that problem both with -Lto and compiling the RTOS in C++ mode. I agree that using compiler specifc things like above is not ideal, but worked for me. Another option would be to use some defines in the GCC portmacro.h

Erich


FreeRTOS won't build on GCC if Linker Time Optimization is set (issue for STM32 ARM CM-7 - port.c:427: undefined reference to `vTaskSwitchContext)

Posted by rtel on March 10, 2017

Is that an acceptable solution for you?

Yes, I think so, it is a GCC specific fix (?) in a GCC specific code. I will add it into the main line too.


FreeRTOS won't build on GCC if Linker Time Optimization is set (issue for STM32 ARM CM-7 - port.c:427: undefined reference to `vTaskSwitchContext)

Posted by daveharr on March 10, 2017

Unfortunately I replied that it fixed the problem too soon. I subsequently edited my post above to indicate that inserting the prototype void vTaskSwitchContext( void ) PRIVILEGED_FUNCTION attribute((used)); in the port.c file does NOT work. It is the tasks.h or tasks.c file that must contain it. I am in the fortunate position that I know I will only ever use GNU CC so I can put it directly into task.h in my own project. I realize that you can't do that so you may want to find another solution.


FreeRTOS won't build on GCC if Linker Time Optimization is set (issue for STM32 ARM CM-7 - port.c:427: undefined reference to `vTaskSwitchContext)

Posted by rtel on March 11, 2017

Ok - I had already made that change, but not checked it in, so its easy to undo. Another solution is required.

Presumable if vTaskSwitchContext() was called by C code, rather than just asm code, then the compiler/linker would know to keep the function. Can you try calling the function, or at least referencing the function, after the scheduler has been started? The compiler will not know that in the GCC port prvPortStartFirstTask() will not return, so you can call vTaskSwitchContext() after prvPortStartFirstTask() within the xPortStartScheduler() function, which is itself in the FreeRTOS/Source/portable/GCC/ARM_CMx/port.c file. You will notice that prvTaskExitError() is already called there for a simliar (but not identical) reason.


FreeRTOS won't build on GCC if Linker Time Optimization is set (issue for STM32 ARM CM-7 - port.c:427: undefined reference to `vTaskSwitchContext)

Posted by richard_damon on March 12, 2017

I will add that I hope the issue has also been forwarded to the GCC team (unless this falls under a documentent Known Issue), as it sounds like a serious bug in the Link Time Optimization routine. Optimizations must not break valid code.


FreeRTOS won't build on GCC if Linker Time Optimization is set (issue for STM32 ARM CM-7 - port.c:427: undefined reference to `vTaskSwitchContext)

Posted by rtel on March 12, 2017

I think in this case the offending function is only called from asm code, so the compiler cannot see it, but as we are discussing link time optimisation the LINKER should be able to see it.


FreeRTOS won't build on GCC if Linker Time Optimization is set (issue for STM32 ARM CM-7 - port.c:427: undefined reference to `vTaskSwitchContext)

Posted by hs2sf on March 12, 2017

I've added this to compiler/platform specific portmacro.h: ~~~

ifndef portFORCE_USED
#define portFORCE_USED  __attribute__(( used ))
endif

~~~ and appended portFORCE_USED to vTaskSwitchContext decl. in task.h:

void vTaskSwitchContext( void ) PRIVILEGED_FUNCTION portFORCE_USED;

This should solve the GCC specfic issue in a generic way. (see feature req. ticket #90 LTO Support in FreeRTOS)

Just my 2ct, HS2


FreeRTOS won't build on GCC if Linker Time Optimization is set (issue for STM32 ARM CM-7 - port.c:427: undefined reference to `vTaskSwitchContext)

Posted by richard_damon on March 12, 2017

My guess, is that LTO is looking at the call context of the function to see if it can be profitably inlined, or perhaps some optimiazations for the code are possible, and not seeing any context is omitting the function, but the ASM reference SHOULD raise a flag that there is a (possible) call that is from an unknown context, so the compiler needs to be conservative in optimization. Perhaps the ((used)) attribute is a way of signalling it, but to me it really shouldn't be needed.

As Real Time Engineers commented, a simpler fix might just be to put a call to it in C code so it knows it will be needed.


[ Back to the top ]    [ About FreeRTOS ]    [ Privacy ]    [ Sitemap ]    [ ]


Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

NXP tweet showing LPC5500 (ARMv8-M Cortex-M33) running FreeRTOS.

Meet Richard Barry and learn about running FreeRTOS on RISC-V at FOSDEM 2019

Version 10.1.1 of the FreeRTOS kernel is available for immediate download. MIT licensed.

View a recording of the "OTA Update Security and Reliability" webinar, presented by TI and AWS.


Careers

FreeRTOS and other embedded software careers at AWS.



FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Espressif ESP32

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Renesas

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS

Xilinx Microblaze and Zynq partner