Как использовать SWI в ARM Cortex A9 для включения прерывания IRQ?

Я пытаюсь сделать свой собственный код с нуля для программы прерывания. Я использую zynq7000, который состоит из двух процессоров ARM Cortex A9.

Я загружаю программу, написанную на C, используя SDK вместе с FSBL и битовый файл, сгенерированный в PlanAhead, во флэш-память. Когда моя программа запускается, процессор переходит в режим пользователя. В режиме пользователя IRQ а также FIQ отключены Я пытаюсь войти в режим супервизора, используя SWI инструкция для включения IRQ а также FIQ перебивает. Когда я отлаживаю, это показывает, что встречает SIGTRAP когда я звоню SWI инструкция.

Итак, как я могу сделать свой собственный код в C, который может разрешить прерывания и запустить мой ISRдаже после загрузки процессора (FSBL) и началось?

Спасибо

1 ответ

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

Выше приведены соответствующие части из минимального примера работы. Обратите внимание, что это работает только для инструкций svc/swi в режиме arm, а не thumb или thumb2, если вы хотите сделать универсальные работы во всех режимах, я рекомендую вам не беспокоиться о svc, а вместо этого передавать что-то в регистр.

Этот пример не разрешает прерывания, он просто показывает, как выполнить вызов svc/swi и как реализовать обработчик исключений. Эти знания хорошо документированы в справочниках по архитектуре вооружений на протяжении многих лет.

Другие вопросы по тегам