We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hi,
Setup: - Keil MCB2103 Evaluation Kit - Keilmdk303j.exe installed - gccARM331.exe installed
I did a little software with I2C, Timer, WD, etc. It compiled with the Keil compiler. I tried the software on flash and ram and worked as expected.
Then, I tried to compile with GNU (Cygnus). I had some issues, but did succeed.
Because I am new with GNU, I used the LinkerScript.ld from C:\Keil\ARM\GNU. I changed the size to:
CODE (rx) : ORIGIN = 0x00000000, LENGTH = 0x00004000 DATA (rw) : ORIGIN = 0x40000000, LENGTH = 0x00004000
In the /Options for Target/Linker I have:
Text Start: 0x00000000 Data Start: 0x40000000
I took the Startup.s file from C:\Keil\ARM\GNU\Boards\Keil\MCB2100\Blinky
Once the debugger is started, the first line that is pointed is
119: Vectors: LDR PC, Reset_Addr 0x00000000 E59F4034 LDR R4,[PC,#0x0034]
Then, I step by step in the code until I reached the swp line:
120: LDR PC, Undef_Addr 0x00000004 E3A05002 MOV R5,#0x00000002 121: LDR PC, SWI_Addr 0x00000008 E5845000 STR R5,[R4] 122: LDR PC, PAbt_Addr 0x0000000C E3A05003 MOV R5,#0x00000003 123: LDR PC, DAbt_Addr 0x00000010 E5845004 STR R5,[R4,#0x0004] 124: NOP /* Reserved Vector */ 0x00000014 E59F201C LDR R2,[PC,#0x001C] 125: LDR PC, IRQ_Addr 0x00000018 E3A03000 MOV R3,#0x00000000 126: LDR PC, FIQ_Addr 127: 128: Reset_Addr: .word Reset_Handler 129: Undef_Addr: .word Undef_Handler 130: SWI_Addr: .word SWI_Handler 131: PAbt_Addr: .word PAbt_Handler 132: DAbt_Addr: .word DAbt_Handler 133: .word 0 /* Reserved Address */ 134: IRQ_Addr: .word IRQ_Handler 135: FIQ_Addr: .word FIQ_Handler 136: 0x0000001C E1020093 SWP R0,R3,[R2] 0x00000020 E2822028 ADD R2,R2,#0x00000028 0x00000024 E1021093 SWP R1,R3,[R2]
What happened after that line is the code points to:
0xFFFFFFF3 FFFF (???) PC, Reset_Addr
Not good at all!
Anybody has a clue why I have this behavior. It looks like I did not configure my memory correctly, but I am not sure.
I tried the C:\Keil\ARM\GNU\Boards\Keil\MCB2100\Blinky. After the debugger is started, it points to:
50: int main (void) { 51: unsigned int n; 52: 0x00000310 E1A0C00D MOV R12,R13
After couple of lines, it goes to
123: LDR PC, DAbt_Addr 0x00000010 E59FF018 LDR PC,[PC,#0x0018]
Not really good either.
Thanks in advance for your help
Is the C runtime startup somehow failing to initialize R13 for use as the stack pointer?
GNU version
At the beginning, R13 = 0x40003F70 Once the abort occurs, R13 = 0x40003FFC
Keil version
At the beginning, R13 = 0x400004A8
I am a new with this kind of stuff, but should the stack pointer initialize itself?
I wrote a little dummy program and had the same problem (R13 was set at 0x40003FFC:
void test(); int main() { int i = 0; int j = 1; i = i + 1; j = i; if (j == 1) { i = 1; test(); } } void test() { int i = 1; if (i == 1) { i++; } }
When I said that I used the Keil compiler I was in error. I am using the Realview one.
"I am a new with this kind of stuff, but should the stack pointer initialize itself?"
No, setting the initial SP usually occurs during post-reset initialization or in the C runtime startup code.
Anyway, looking up your eval board, then looking the CPU used on the board (LPC2103), I see that it only has 8K of internal SRAM, yet your linker file has it set for 16K. That might be the problem.
"... your linker file has it set for 16K. That might be the problem."
I see your subsequent .ld file edit, yet the R13 value at the abort suggests that 16K is still being used for some reason.
Any clue what it could write at that address? Even the basic program that I did (see other post) has the same behavior and there is nothing special in that code.
How the Realview result is working and not the GNU one? Ok, they do not compile the same way, but still it is the same code.
"Any clue what it could write at that address?"
I believe that the intent of the STMDB you mentioned above is to set up a stack frame, but it must be within existing memory, hence the data abort exception.
"How the Realview result is working and not the GNU one?"
You showed us above that the GNU version's R13 = 0x40003F70 is beyond the 8K SRAM space, whereas the other version's R13 = 0x400004A8 is within the valid address range. The GNU version must have the notion that the data space is bigger than it is and is initializing SP up too high.
Hi Dan,
Guess what?
I re-scan for the X times the Startup.s and I saw that:
.equ Top_Stack, 0x40004000
I changed it for 0x40002000. No more "Data Abort" exception error!
Now, I need to know why my interrupts are not working now. You have some knowledge about interrupt with GNU?
By the way, thanks for all the help that you gave me.
"Now, I need to know why my interrupts are not working now."
What kind of trouble are you having?
"You have some knowledge about interrupt with GNU?"
Enough to know that GCC provides special extension syntax for the interrupt function attribute.
There should be interrupt examples in your directory tree somewhere.
Also see:
www.hitex.co.uk/.../index.html
Ok, here is the situation.
I set an interrupt TIMER0 and I2C0.
// Initialise VIC for I2C use VICIntSelect = 0x0; VICVectAddr0 = (u32) i2cISR; VICVectCntl0 = 0x20 | 9;// use it for I2C Interrupt VICIntEnable = 0x200; // Enabling I2C Channel (9) // Initialise VIC for TIMER0 use VICIntSelect = 0x0; VICVectAddr1 = (u32)timerInt; VICVectCntl1 = 0x20 | 4; // use it for Timer 0 VICIntEnable = 0x10; // Enable Timer0 Interrupt
Of course, there is other code around that
When I run the program, I never receive any I2C interrupt.
I tried to take out the TIMER0 interrupt, and nothing happened on I2C.
I tried to take out the I2C module and confirmed that the timer works.
So, why the I2C module does not work? Are those definition are ok?
void timerInt(void) __attribute__ ((interrupt)); void i2cISR(void) __attribute__ ((interrupt));
By the way, what is the difference between:
void timerInt(void) __attribute__ ((interrupt)); and void timerInt(void) __attribute__ ((interrupt("IRQ")));
Regards
Looks like with:
void timerInt(void) __attribute__ ((interrupt("IRQ"))); void i2cISR(void) __attribute__ ((interrupt("IRQ")));
it is working.
But I still want to know what is the difference between the two syntax
"But I still want to know what is the difference between the two syntax"
Isn't it that "IRQ" is implicit with ((interrupt)) compared to the explicit ((interrupt("IRQ"))) and that ((interrupt("???"))) supports others like FIQ?
I think you are right
Thanks for all the tips!