Как использовать 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 и как реализовать обработчик исключений. Эти знания хорошо документированы в справочниках по архитектуре вооружений на протяжении многих лет.