FreeRTOS Support Archive
The FreeRTOS support forum is used to obtain active support directly from Real
Time Engineers Ltd. In return for using our top quality software and services for
free, we request you play fair and do your bit to help others too! Sign up
to receive notifications of new support topics then help where you can.
This is a read only archive of threads posted to the FreeRTOS support forum.
The archive is updated every week, so will not always contain the very latest posts.
Use these archive pages to search previous posts. Use the Live FreeRTOS Forum
link to reply to a post, or start a new support thread.
[FreeRTOS Home] [Live FreeRTOS Forum] [FAQ] [Archive Top] [March 2017 Threads] 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.
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.
|