--- lpc2100 <lpc2100@...> wrote:
> interrupt keyword does not work in GCC 3.3.1
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12637
>
> try a new version or refer to
I am using a GNUARM-3.4.1.
[fragment of app.s]
irq_handler:
@ Interrupt Service Routine.
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 1, uses_anonymous_args = 0
str ip, [sp, #-4]!
mov ip, sp
stmfd sp!, {r0, r1, r2, r3, r4, fp, ip, lr, pc}
sub fp, ip, #4
mvn r4, #4032
sub r4, r4, #15
ldr r3, [r4, #0]
mov lr, pc
mov pc, r3
mov r3, #0
str r3, [r4, #0]
ldmfd sp, {r0, r1, r2, r3, r4, fp, sp, lr}
ldmfd sp!, {ip}
subs pc, lr, #4
Everything (except VIC) works fine.
I don't known what is wrong :(
[app.c]
#include "iolpc210x_gcc.h"
#define bit(n) (1U << (n))
static void delay(int d)
{
while (d > 0)
d--;
}
typedef enum { YELLOW, GREEN, RED } LEDS;
static void ledOn(LEDS led)
{
switch (led)
{
case YELLOW: IOCLR.bit.P0_12 = 1; break;
case GREEN: IOCLR.bit.P0_25 = 1; break;
case RED: IOCLR.bit.P0_26 = 1; break;
}
}
static void ledOff(LEDS led)
{
switch (led)
{
case YELLOW: IOSET.bit.P0_12 = 1; break;
case GREEN: IOSET.bit.P0_25 = 1; break;
case RED: IOSET.bit.P0_26 = 1; break;
}
}
static volatile int ledStatus = 0;
void timer0_isr()
{
ledStatus = !ledStatus;
if (ledStatus)
ledOff(RED);
else
ledOn(RED);
T0IR.reg = 0xFF;
}
void init_timer()
{
VICIntSelect.reg &= ~bit(VIC_TIMER0);
VICVectAddr2 = (unsigned)&timer0_isr;
VICVectCntl2.reg = 0x20 | VIC_TIMER0;
VICIntEnable.reg = bit(VIC_TIMER0);
T0TCR.bit.CE = 0;
T0TCR.bit.CR = 1;
T0MR0 = (14745600/4)/2; // 2Hz
T0PC = 0;
T0MCR.bit.MR0INT = 1;
T0MCR.bit.MR0RES = 1;
T0CCR.reg = 0;
T0EMR.reg = 0;
T0TCR.bit.CE = 1;
}
void __irq irq_handler()
{
((void (*)())VICVectAddr)();
VICVectAddr = 0;
}
int main()
{
PINSEL0.bit.P0_12 = 0;
PINSEL1.bit.P0_25 = 0;
PINSEL1.bit.P0_26 = 0;
IODIR.bit.P0_12 = 1;
IODIR.bit.P0_25 = 1;
IODIR.bit.P0_26 = 1;
ledOff(RED);
ledOff(YELLOW);
ledOff(GREEN);
init_timer();
while (1)
{
ledOn(YELLOW); delay(50000);
ledOff(YELLOW); delay(50000);
}
}
[startup.s]
.set SYSTEM_MODE, 0x1F
.set UNDEFINED_MODE, 0x1B
.set ABORT_MODE, 0x17
.set SUPERVISOR_MODE, 0x13
.set IRQ_MODE, 0x12
.set FIQ_MODE, 0x11
.set USER_MODE, 0x10
.text
.arm
.align 0
# exception vectors
ldr pc, reset_handler_addr
ldr pc, undefined_instruction_handler_addr
ldr pc, software_interrupt_handler_addr
ldr pc, prefetch_abort_handler_addr
ldr pc, data_abort_handler_addr
ldr pc, endless_loop
ldr pc, irq_handler_addr
ldr pc, fiq_handler_addr
reset_handler_addr: .long reset_handler
undefined_instruction_handler_addr: .long
undefined_instruction_handler
software_interrupt_handler_addr: .long
software_interrupt_handler
prefetch_abort_handler_addr: .long
prefetch_abort_handler
data_abort_handler_addr: .long data_abort_handler
.long 0 /* ARM-reserved vector */
irq_handler_addr: .long irq_handler
fiq_handler_addr: .long fiq_handler
.global reset_handler
reset_handler:
msr cpsr_c, #UNDEFINED_MODE
ldr sp, =__UNDEFINED_SP__
msr cpsr_c, #ABORT_MODE
ldr sp, =__ABORT_SP__
msr cpsr_c, #SUPERVISOR_MODE
ldr sp, =__SUPERVISOR_SP__
msr cpsr_c, #IRQ_MODE
ldr sp, =__IRQ_SP__
msr cpsr_c, #FIQ_MODE
ldr sp, =__FIQ_SP__
msr cpsr_c, #USER_MODE
ldr sp, =__USER_SP__
# setup a default stack limit (when compiled with
"-mapcs-stack-check").
sub sl, sp, #__USER_STACK_SIZE__
# relocate .data(rw) section (copy from FLASH to RAM).
ldr r1, =__text_end__
ldr r2, =__data_start__
ldr r3, =__data_end__
reset_handler_L01:
cmp r2, r3
ldrlo r0, [r1], #4
strlo r0, [r2], #4
blo reset_handler_L01
# clear .bss(rw) section.
mov r0, #0
ldr r1, =__bss_start__
ldr r2, =__bss_end__
reset_handler_L02:
cmp r1, r2
strlo r0, [r1], #4
blo reset_handler_L02
# set up arguments to main and call.
mov r0, #0
mov r1, #0
bl main
.global endless_loop
endless_loop:
b endless_loop
.end
[lpc2104.ld]
MEMORY
{
FLASH(rx) : ORIGIN = 0x00000000, LENGTH = 128K
RAM(rw) : ORIGIN = 0x40000000, LENGTH = 16K
}
__STACK_START__ = 0x40000000 + 16K;
__UNDEFINED_STACK_SIZE__ = 0x0004;
__ABORT_STACK_SIZE__ = 0x0004;
__SUPERVISOR_STACK_SIZE__ = 0x0004;
__FIQ_STACK_SIZE__ = 0x0004;
__IRQ_STACK_SIZE__ = 0x0080;
__USER_STACK_SIZE__ = 0x0200;
__UNDEFINED_SP__ = __STACK_START__ - 4;
__ABORT_SP__ = __UNDEFINED_SP__ -
__UNDEFINED_STACK_SIZE__;
__SUPERVISOR_SP__ = __ABORT_SP__ -
__ABORT_STACK_SIZE__;
__FIQ_SP__ = __SUPERVISOR_SP__ -
__SUPERVISOR_STACK_SIZE__;
__IRQ_SP__ = __FIQ_SP__ - __FIQ_STACK_SIZE__;
__USER_SP__ = __IRQ_SP__ - __IRQ_STACK_SIZE__;
SECTIONS
{
. = 0;
.text :
{
__text_start__ = .;
startup.o(.text)
*(.text)
*(.glue_7)
*(.glue_7t)
}
>FLASH =0
. = ALIGN(4);
.rodata :
{
*(.rodata)
*(.rodata*)
}
>FLASH
. = ALIGN(4);
__text_end__ = .;
.data : AT(__text_end__)
{
__data_start__ = .;
*(.data)
}
>RAM
. = ALIGN(4);
__data_end__ = .;
.bss :
{
__bss_start__ = .;
*(.bss)
*(COMMON)
}
>RAM
. = ALIGN(4);
__bss_end__ = .;
}
PROVIDE(undefined_instruction_handler = endless_loop);
PROVIDE(software_interrupt_handler = endless_loop);
PROVIDE(prefetch_abort_handler = endless_loop);
PROVIDE(data_abort_handler = endless_loop);
PROVIDE(irq_handler = endless_loop);
PROVIDE(fiq_handler = endless_loop);
__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com