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

拈花ヽ惹草 提交于 2019-11-27 06:01:23

问题


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

回答1:


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




回答2:


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




回答3:


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.




回答4:


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



来源:https://stackoverflow.com/questions/7649979/gcc-alias-to-function-outside-of-translation-unit-aka-is-this-even-the-right-t

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!