Andras Tantos wrote:
> You can download a newer (actually two: 3.3.1 and 3.4.0) GCC from my
> webpage. I'm not a GCC expert, but I know they've fixed a serious ARM bugs
> in their IRQ handling around 3.3.0. You might be hitting it.
>
> --
> Regards,
> Andras Tantos
> <http://andrast.tantos.homedns.org>
>
> "Jens Hildebrandt" <jens.hildebrandt@remove_this.etechnik.uni-rostock.de>
> wrote in message news:40cd60da@news.uni-rostock.de...
>
>>Hello group,
>>
>>I'm curently trying to get familiar with the ARM7 by building some
>>example-projects for a LPC2106-controller. One such project is the
>
> blinky_irq
>
>>example from Keil which should demonstrate the use of interrupts and of
>
> the
>
>>LPC2xxx vectored interrupt controller. I'm using gcc-3.2.1 with binutils
>
> 3.13.1
>
>>and newlib 1.11.0 . So far I had no problems with these tools and I was
>
> able to
>
>>build and succesfully run some small demonstrator programs (without
>
> interrupts)
>
>>on my LPC2106 board. For the blinky_irq example program I use the linker
>
> script
>
>>and startup.s files (with adjustment for the Flash and RAM sizes of the
>
> LPC2106)
>
>>that came with the source code from Keil's download area. Since the
>
> program
>
>>didn't work I stripped it from all unnecessary functionality (main() is
>>essentially an empty loop now) and simply let the timer ISR toggle a LED
>
> on
>
>>GPIO24. That worked initially, but after some time (~ 3 minutes) the LED
>
> stopped
>
>>toggling. I suspected that somwhere I'm loosing memory such that after
>
> some time
>
>>I'm out of RAM. Hence, I took a look at the disassembled code and saw that
>
> the
>
>>ISR is messing up the IRQ-mode stack pointer, loosing seven words each
>
> time the
>
>>ISR is invoked.
>>Since the ISR entry and exit codes are automatically generated by the
>
> compiler I
>
>>suspect a bug in gcc. On the other hand, since this would be a very severe
>>failure other users should have come across it, too. Does anybody of you
>
> know
>
>>that error (i.e. should I change to another gcc version) or am I missing
>>something (e.g. gcc options)?
>>Below you'll find the build commands used, the sources of the program and
>
> the
>
>>disassembled ISR code.
>>
>>TIA,
>>Jens
>>
>>------build commands-----------------------------
>>$ make blinky_irq.hex
>>arm-elf-as -mcpu=arm7tdmi -gstabs Startup.s -o Startup.o
>>Startup.s: Assembler messages:
>><couple of warnings about rest of line after ';' being ignored>
>>arm-elf-gcc -c -g -I. -mcpu=arm7tdmi Time.c -o Time.o
>>arm-elf-gcc -c -g -I. -mcpu=arm7tdmi Blinky.c -o Blinky.o
>>arm-elf-gcc -T Flash.ld -nostartfiles -Lgcc -L. -o blinky_irq.elf
>
> Startup.o
>
>>Time.o Blinky.o
>>arm-elf-objcopy -I elf32-littlearm -O ihex blinky_irq.elf blinky_irq.hex
>>
>>------sources------------------------------------
>>
>
> /***************************************************************************
> ***/
>
>>/*
>
> */
>
>>/* BLINKY.C: LED Flasher
>
> */
>
>>/*
>
> */
>
> /***************************************************************************
> ***/
>
>>#include "LPC210x.h"
>>#include "Timer.h"
>>
>>extern long volatile timeval; /*ISR counter variable*/
>>
>>void wait (void) { /* wait function, not used
>
> actually */
>
>> unsigned long i;
>>
>> i = timeval;
>> while ((i + 10) > timeval){
>> }; /* wait 100ms */
>>}
>>
>>int main (void) {
>>
>> IODIR = 0xFF000000; /* P1.31..24 defined as
>
> Outputs */
>
>> init_timer();
>>
>> while (1) { /* Loop forever */
>> }
>>}
>>
>>
>
> /***************************************************************************
> ***/
>
>>/*
>
> */
>
>>/* TIME.C: Time Functions for 10Hz Clock Tick
>
> */
>
>>/*
>
> */
>
> /***************************************************************************
> ***/
>
>>#include "LPC210x.h"
>>#include "Timer.h"
>>
>>long volatile timeval; //counter for wait-routine
>>
>>void tc0 (void) __attribute__ ((interrupt)); // Generate Interrupt
>>
>>/* Setup the Timer Counter 0 Interrupt */
>>void init_timer (void) {
>> VICVectAddr0 = (unsigned long)tc0; // set interrupt vector
>
> in 0
>
>> VICVectCntl0 = 0x20 | 4; // use it for Timer 0
>
> Interrupt
>
>> VICIntEnable = 0x00000010; // Enable Timer0
>
> Interrupt
>
>> TIMER0_MR0 = 5898239; // 100mSec =
>>(0.1*4*14,7456E6)-1 counts
>> TIMER0_MCR = 3; // Interrupt and Reset on
>
> MR0
>
>> TIMER0_TCR = 1; // Timer0 Enable
>>}
>>
>>
>>/* Timer Counter 0 Interrupt executes each 100ms @ 4x14,7456 MHz CPU Clock
>
> */
>
>>void tc0 (void) {
>>/* timeval++;*/
>> if((IOPIN&0x01000000) == 0x00000000){
>> IOSET = 0x01000000;
>> }else{
>> IOCLR = 0x01000000; //toggle GPIO24
>> }
>> TIMER0_IR = 1; // Clear interrupt flag
>> VICVectAddr = 0; // Acknowledge Interrupt
>>}
>>
>>-------------------disassebled ISR (with some
>
> comments)---------------------
>
>>...
>>00000278 <tc0>:
>>; --ip is stored on stack but not restored at ISR exit (see below)!!
>> 278: e52dc004 str ip, [sp, -#4]!
>> 27c: e1a0c00d mov ip, sp
>> 280: e24ee004 sub lr, lr, #4 ; 0x4
>>; --write-back further decrements sp. This is not corrected on ISR exit!!
>>; --btw: why is pc stored on the stack anyway and why is ip with it's new
>>; --contents pushed onto the stack, too??
>> 284: e92dd80c stmdb sp!, {r2, r3, fp, ip, lr, pc}
>> 288: e24cb004 sub fp, ip, #4 ; 0x4
>> 28c: e3a0320e mov r3, #-536870912 ; 0xe0000000
>> 290: e283390a add r3, r3, #163840 ; 0x28000
>> 294: e5933000 ldr r3, [r3]
>> 298: e2033401 and r3, r3, #16777216 ; 0x1000000
>> 29c: e3530000 cmp r3, #0 ; 0x0
>> 2a0: 1a000004 bne 2b8 <tc0+0x40>
>> 2a4: e3a0324e mov r3, #-536870908 ; 0xe0000004
>> 2a8: e283390a add r3, r3, #163840 ; 0x28000
>> 2ac: e3a02401 mov r2, #16777216 ; 0x1000000
>> 2b0: e5832000 str r2, [r3]
>> 2b4: ea000003 b 2c8 <tc0+0x50>
>> 2b8: e3a032ce mov r3, #-536870900 ; 0xe000000c
>> 2bc: e283390a add r3, r3, #163840 ; 0x28000
>> 2c0: e3a02401 mov r2, #16777216 ; 0x1000000
>> 2c4: e5832000 str r2, [r3]
>> 2c8: e3a0320e mov r3, #-536870912 ; 0xe0000000
>> 2cc: e2833901 add r3, r3, #16384 ; 0x4000
>> 2d0: e3a02001 mov r2, #1 ; 0x1
>> 2d4: e5832000 str r2, [r3]
>> 2d8: e3e03d3f mvn r3, #4032 ; 0xfc0
>> 2dc: e243300f sub r3, r3, #15 ; 0xf
>> 2e0: e3a02000 mov r2, #0 ; 0x0
>> 2e4: e5832000 str r2, [r3]
>>; --registers are restored, pc is loaded with (lr-4) and cpsr is restored
>>; --so this causes a return to the user code. But ip is not restored to
>
> it's
>
>>; --initial value but to the value that was assigned to ip after it was
>
> saved
>
>>; --on the stack. And, sp is not restored to it's initial value!!
>> 2e8: e95b980c ldmdb fp, {r2, r3, fp, ip, pc}^ ;
>>
>>
>>
>
>
>
>
>
Hi Andras,
I already suspected such a bug but wanted to make sure that a new gcc version
would solve my problem before downloading and installing the new tools. BTW: the
link to your page gets me a "403: Forbidden" error.
Anyway, thanks for the reply,
Jens