GCC alias to function outside of translation unit -AKA- is this even the right tool for the job?
Asked Answered
P

4

14

I'm working with FreeRTOS on an STM32 (Cortex-M3), and using the CMSIS library from ST to bootstrap everything.

The CMSIS library defines the weak symbol SVC_Handler in the startup ".s" file. It must be overridden somewhere in order to get your ISR in the interrupt vector table. FreeRTOS defines vPortSVCHandler, which is the ISR I want to have handle the SVC interrupt.

I would like to "glue" the two together using my application code (i.e. w/o modifyng FreeRTOS or the CMSIS source code). I thought an alias would be the right tool for the job, so I tried this (in a separate source file, main.c):

void SVC_Handler(void) __attribute__ ((alias ("vPortSVCHandler")));

That results in: error: 'SVC_Handler' aliased to undefined symbol 'vPortSVCHandler'

Turns out, according to GCC documentation here http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html, in order to use the alias attribute, you cannot alias a symbol outside of the translation unit. So I thought I'd try to extern the symbol into main.c like so:

extern void vPortSVCHandler( void ) __attribute__ (( naked ));
void SVC_Handler(void) __attribute__ ((alias ("vPortSVCHandler")));

This generates the same error. Any suggestions???

I would really like to avoid modifying either of the libraries. I know I could write a function SVC_Handler that simply calls vPortSVCHandler, but that could add unnecessary overhead to the ISR (possibly depending on optimization settings). Note: The FreeRTOS examples accomplish this via a custom startup file. I'm looking for a way to do this from C or my linker script.

  • Compiler Version: gcc version 4.5.2 (Sourcery G++ Lite 2011.03-42)
  • Target: arm-none-eabi
Pretentious answered 4/10, 2011 at 15:4 Comment(0)
B
10

You should be able to do this either with a linker script, or by passing the appropriate option to the linker, eg. for ld, --defsym=SVC_Handler=vPortSVCHandler

See the binutils documentation for more information on the ld --defsym option, and assignments in linker scripts

Bristol answered 4/10, 2011 at 15:23 Comment(3)
Simply adding SVC_Handler = vPortSVCHandler; to the top of the linker script gets the job done. Still seems messy, but it works.Pretentious
Note that this solution does not appear to work with LTO at all. It seems the symbol is always emitted pointing to 0x0 leading to "CALL 0" in the generated instructions.Subirrigate
One nice thing is that this also works for variables that are visible as extern only in some CUs where the alias solution does not work either.Monophyletic
R
4

I think the problem with alias is, that it expects a declared and defined function, since it is just an alias. You want to use it as a forward-declaration of another function. I got a similar thing to work like that:

void SVC_Handler(void) asm("vPortSVCHandler");

This renames the entry point of the SVC_Handler, and if you then do not define it, it should find vPortSVCHandler.

See: https://gcc.gnu.org/onlinedocs/gcc/Asm-Labels.html

Ravelment answered 18/2, 2016 at 10:39 Comment(0)
P
1

Another solution that I gleaned from one of the FreeRTOS examples is to add the following to your FreeRTOSConfig.h ...

/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
standard names - or at least those used in the unmodified vector table. */
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler

The original file is from FreeRTOS/Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Source/FreeRTOSConfig.h which also integrates the CMSIS system clock into the config. A very nice starting point for a CMSIS/FreeRTOS project.

Puttee answered 8/4, 2013 at 15:8 Comment(0)
L
0

I'm pretty sure SVC handler is only used by FreeRTOS at initial startup, so adding an indirection exception handler isn't going to hurt performance (but its ugly). Best ask this on the FreeRTOS forum, response there is usually great.

Hope this helps, Best Regards, Dave

Loony answered 4/10, 2011 at 15:10 Comment(1)
I should add that I need to do this w/ the SysTick and PendSV handler as well. I might ask on FreeRTOS forums too, but it's really more a question about the GCC toolchain than about FreeRTOS.Pretentious

© 2022 - 2024 — McMap. All rights reserved.