Hello, I am having issues implementing the ISR routine on the CORTEX-M3, this exact setup works when I use it with RTX but not as standalone code. When I compile it says cancpp.axf: Error: L6218E: Undefined symbol GPI_ISR (referred from startup.o). But no issues when I build with RTX OS selected.
This is a snip-it of code: GPI_ISR should be the function it branches to.
****************************************************************************** ; ; The vector table. ; ;****************************************************************************** EXPORT __Vectors IMPORT GPI_ISR ;[WEAK] __Vectors DCD StackMem + Stack ; Top of Stack DCD Reset_Handler ; Reset Handler DCD NmiSR ; NMI Handler DCD FaultISR ; Hard Fault Handler DCD IntDefaultHandler ; MPU Fault Handler DCD IntDefaultHandler ; Bus Fault Handler DCD IntDefaultHandler ; Usage Fault Handler DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD IntDefaultHandler ; SVCall handler DCD IntDefaultHandler ; Debug monitor handler DCD 0 ; Reserved DCD IntDefaultHandler ; PendSV Handler DCD IntDefaultHandler ; SysTick Handler DCD GPI_ISR ; GPIO Port A
.
in the main.c I have
void GPI_ISR (void) { }
Check your map file to see if GPI_ISR shows up at all. Your executable is cancpp.axf - are you compiling as C++ code? In that case the GPI_ISR function name maybe mangled and would show up as something other than GPI_ISR in the linker output.
Andrew
I am using C++.
Using the
IMPORT GPI_ISR [WEAK]
syntax it will build but wont go to the function. If I remove the [WEAK] syntax, it wont build and says:
cancpp.axf: Error: L6218E: Undefined symbol GPI_ISR (referred from startup.o).
This is what I copied from the MAP file, it shows GPI_ISR as an undefined Weak Reference:
BuildAttributes$$THM_ISAv4$P$D$K$B$S$PE$A:L22UL41UL21$X:L11$S22US41US21$IEEE1$IW$USESV6$~STKCKD$USESV7$~SHL$OTIME$ROPI$IEEEJ$EBA8$UX$STANDARDLIB$REQ8$PRES8$EABIv2 0x00000000 Number 0 anon$$obj.o ABSOLUTE __ARM_use_no_argv 0x00000000 Number 0 main.o ABSOLUTE __Vectors 0x00000000 Data 0 startup.o(RESET) __dso_handle 0x00000000 Number 0 startup.o(RESET) _printf_flags 0x00000000 Number 0 printf_stubs.o ABSOLUTE _printf_return_value 0x00000000 Number 0 printf_stubs.o ABSOLUTE _printf_sizespec 0x00000000 Number 0 printf_stubs.o ABSOLUTE _printf_widthprec 0x00000000 Number 0 printf_stubs.o ABSOLUTE GPI_ISR - Undefined Weak Reference SHT$$ARM_EXIDX$$Base - Undefined Reference SHT$$ARM_EXIDX$$Limit - Undefined Reference
Thanks for the help.
And have you tried to tell your nice C++ compiler that you want it to create your function using the standard C naming convention?
No I have not, I am new to Keil. How would I go about doing this? Pleas send me a link or some info.
Thank you.
Doesn't matter if you are new to Keil.
It's a question about what you know about C++, the programming language.
How do you think C++, with name mangling of all external references, can link with C functions like printf(), atoi() etc that do not have their names name mangled?
Enlighten me.
try declaring your GPI_ISR as
extern "C" GPI_ISR();
This should generate a standard C naming convention symbol which then is linked to the startup file.
This is my first C++ project on a non windows machine so I am still kind of lost.
Thanks for that Andrew .
It's the same with Keil as with Windows as with OS/2 as with Linux.
Whenever a C++ program needs to access a C function, it has to know that the C function that gets linked in is "C"
And to let a C program reach a C++ function, the C++ function must specify that it should use "C" naming and calling conventions.
The reason for the name mangling in C++ is to allow polymorphic functions, where the same function name can be used multiple times but with different sets of argument types. And to get type-safe linking - the linker will only be able to match the symbol names when caller and implementation expects the same set of data types.
Since C does not have name mangling, C++ is required to have a standard method to declare when name mangling can not be used. So a good C++ book will cover this, and lots of other useful details.
Thanks Westermark. Although I have read many C++ books ( I honestly don't recall seeing that in them), I have never had the need to mix C++ and C functions directly, until now. The libraries always had the extern "C" in them, and I never paid attention to it much. But thanks for taking the time to explain.