如何在ARM Cortex A9中使用SWI来启用IRQ中断?

时间:2014-03-18 09:15:20

标签: c assembly arm cortex-a

我试图从头开始为中断程序制作自己的代码。我使用 zynq7000 ,它由两个 ARM cortex A9 处理器组成。

我使用SDK以及在PlanAhead中生成的FSBL和位文件将用C编写的程序加载到闪存中。当我的程序开始运行时,处理器进入用户模式。在用户模式下,IRQFIQ被禁用。我尝试使用SWI指令进入管理员模式以启用IRQFIQ中断。当我调试时,它显示当我调用SIGTRAP指令时遇到SWI

那么,即使在处理器启动(ISR)并启动后,我怎样才能在C中创建自己的代码,这可以启用中断并运行FSBL

由于

1 个答案:

答案 0 :(得分:0)

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

链接描述文件

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);
}

以上是最小swi工作示例的相关部分。请注意,这仅适用于arm模式下的svc / swi指令而不是thumb或thumb2,如果你想在所有模式下使用泛型,我建议你不要打扰svc immediate,而是在寄存器中传递一些东西。

此示例不启用中断,它只显示如何进行svc / swi调用以及如何实现异常处理程序。多年来,这些知识在手臂建筑参考手册中得到了很好的记录。