The example code for AT91SAM7S64 contains #include <lib_AT91SAM7S64.h> and it works fine. When I include this in two or more .c files, I get lots of linker errors like *** ERROR L104: MULTIPLE PUBLIC DEFINITIONS SYMBOL: AT91F_AIC_ConfigureIt?T Now if there was a non-extern variable declaration, or a normal routine in there I'd understand it, but in lib_AT91SAM7S64.h, AT91F_AIC_ConfigureIt is defined as __inline. ... and if it's inline, then why is the compiler generating any public definitions for it at all? Why does the linker even need to see an inline function? I've tried changing "__inline" to "inline", to agree more closely with the compiler docs, but that didn't help. Any ideas?
This works fine here. Are you using the current Keil Development Suite for ARM Version 1.5?
have you tried looking at the preprocessor listing to see what the compiler's actually getting...?
I think so. I installed from the CD (Release 10.2004), then patched it with karm15.exe from your website. Prior to patching, there were no AT91SAM7 examples. After patching I found Blinky for AT91SAM7 (which uses lib_AT91SAM7S64.h just once), but I didn't find any examples with it included by two or more .c files. Do you have any examples which use it twice? Could I try the one you tried?
I hadn't, but I have now. According to the .i file for each of the .c files that includes lib_AT91SAM7S64.h, the function definition begins with __inline unsigned int AT91F_AIC_ConfigureIt ( I don't think I've got NOEXTEND turned on, and I get no compiler errors in any case, just linker errors. I'd read up on the inline keyword, but there's a broken link in the online manual.
I went back to the blinky example (which works) and had a look at the disassembly listing, and I think it might be ignoring the inline directive and generating function calls as normal. The main function starts: int main (void) { int i; // Enable the Clock of the PIO AT91F_PMC_EnablePeriphClock(AT91C_BASE_PMC, 1 << AT91C_ID_PIOA); The lib file has: __inline void AT91F_PMC_EnablePeriphClock ( AT91PS_PMC pPMC, // \arg pointer to PMC controller unsigned int periphIds) // \arg IDs of peripherals to enable { pPMC->PMC_PCER = periphIds; } The disassembly listing shows: 52: int main (void) { 53: int i; 54: 55: // Enable the Clock of the PIO 0x00200584 4827 LDR R0,[PC,#0x009C] 0x00200586 C806 LDMIA R0!,{R1-R2} 0x00200588 1C0B ADD R3,R1,#0 0x0020058A 4313 ORR R3,R2 0x0020058C D005 BEQ 0x0020059A 0x0020058E 2300 MOV R3,#0x00 0x00200590 700B STRB R3,[R1,#0x00] 0x00200592 1C49 ADD R1,R1,#1 0x00200594 4291 CMP R1,R2 0x00200596 D1FB BNE 0x00200590 0x00200598 E7F5 B 0x00200586 0x0020059A 4823 LDR R0,[PC,#0x008C] 0x0020059C 1CC0 ADD R0,R0,#3 0x0020059E 2303 MOV R3,#0x03 0x002005A0 4398 BIC R0,R3 0x002005A2 C806 LDMIA R0!,{R1-R2} 0x002005A4 1C0B ADD R3,R1,#0 0x002005A6 4313 ORR R3,R2 0x002005A8 D006 BEQ main(0x002005B8) 0x002005AA 7803 LDRB R3,[R0,#0x00] 0x002005AC 1C40 ADD R0,R0,#1 0x002005AE 700B STRB R3,[R1,#0x00] 0x002005B0 1C49 ADD R1,R1,#1 0x002005B2 4291 CMP R1,R2 0x002005B4 D1F9 BNE 0x002005AA 0x002005B6 E7F1 B 0x0020059C 0x002005B8 B500 PUSH {LR} 56: AT91F_PMC_EnablePeriphClock(AT91C_BASE_PMC, 1 << AT91C_ID_PIOA); 57: 58: // Configure the PIO Lines corresponding to LED1..LED4 as Outputs 0x002005BA 481C LDR R0,[PC,#0x0070] 0x002005BC 2104 MOV R1,#0x04 0x002005BE F7FF BL AT91F_PMC_EnablePeriphClock(0x00200354) - Part #1 0x002005C0 FEC9 BL AT91F_PMC_EnablePeriphClock(0x00200354) - Part #2 59: AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, LED_MASK); I'm new to the ARM, but I think that looks like a function call, not inline code.
Can you just send your example to support.intl@kei.com. We will then give you a solution.