简体   繁体   中英

How to use the SWI in ARM Cortex A9 for enabling the IRQ interrupt?

I'm trying to make my own code from the scratch for an interrupt program. I'm using zynq7000 which consists of two ARM cortex A9 processors.

I load the program written in C using SDK alongwith the the FSBL and bit file generated in PlanAhead, into the Flash Memory. When my program starts running the processor enters the user mode. In user mode IRQ and FIQ are disabled. I'm trying to enter the supervisor mode using the SWI instruction to enable the IRQ and FIQ interrupts. When I debug, it shows that it encounters the SIGTRAP when I call the SWI instruction.

So, how can I make my own code in C, which can enable the interrupts and run my ISR , even after the processor has booted( FSBL ) and started?

Thanks

vectors.s

.globl _start
_start:
    ldr pc,_reset_handler
    ldr pc,_undefined_handler
    ldr pc,_swi_handler
    b hang
    b hang
    b hang
    b hang
    b hang

_reset_handler:     .word reset
_undefined_handler: .word hang
_swi_handler:       .word swi

reset:
    mov sp,#0xD6000000
    add sp,sp,#0xC000

    bl notmain
hang: b hang

.globl PUT32
PUT32:
    str r1,[r0]
    bx lr

.globl GET32
GET32:
    ldr r0,[r0]
    bx lr

swi:
    ldr r0,[lr,#-4]
    mov r1,#0x00FFFFFF
    and r0,r0,r1
    movs pc,lr

.globl switest
switest:
    stmdb r13!,{lr}
    swi #0x23
    ldmia r13!,{lr}
    bx lr

linker script

MEMORY
{
    ram : ORIGIN = 0x00000000, LENGTH = 0x4000
}
SECTIONS
{
    .text : { *(.text*) } > ram
}

notmain.c

extern void uart_init ( void );
extern void uart_putc ( unsigned char );
extern unsigned int switest ( void );
void hexstrings ( unsigned int d )
{
    unsigned int rb;
    unsigned int rc;

    rb=32;
    while(1)
    {
        rb-=4;
        rc=(d>>rb)&0xF;
        if(rc>9) rc+=0x37; else rc+=0x30;
        uart_putc(rc);
        if(rb==0) break;
    }
    uart_putc(0x20);
}
void hexstring ( unsigned int d )
{
    hexstrings(d);
    uart_putc(0x0D);
    uart_putc(0x0A);
}
int notmain ( void )
{
    uart_init();
    hexstring(0x12345678);
    hexstring(switest());
    return(0);
}

The above are relevant parts from a minimal swi working example. Note that this only works for svc/swi instructions in arm mode not thumb nor thumb2, if you want to make a generic works in all modes, I recommend you dont bother with the svc immediate and instead pass something in a register.

This example does not enable interrupts it just shows how to make an svc/swi call and how to implement the exception handler. This knowledge has been well documented in the arm architectural reference manuals for many many years now.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM