【问题标题】:How to use the SWI in ARM Cortex A9 for enabling the IRQ interrupt?如何使用 ARM Cortex A9 中的 SWI 来启用 IRQ 中断?
【发布时间】:2014-03-18 09:15:19
【问题描述】:

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

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

那么,即使在处理器启动 (FSBL) 并启动之后,我如何在 C 中编写我自己的代码,它可以启用中断并运行我的ISR

谢谢

【问题讨论】:

  • 要使用 SWI,您需要提供一个 SWI 处理程序,在该处理程序中您可以做任何您想做的事情。 C 作为一种语言不了解启用/禁用中断所需的 ARM 指令,因此需要一些汇编。所有这些都可能以编译器特定的方式为您完成,但这当然会使您的代码极难移植。
  • 我根据 armgcc 提供的语法制作了自己的 SWI 处理程序,但它从未进入处理程序。我还在 arm_vectors.S 中找到了 SWI 处理程序(我猜它是启动文件),它使用“BL”命令跳转到处理程序。我试图将其更改为跳转到我的处理程序,但它永远不会。关于传递给 SWI 指令的值意味着什么的任何想法可能会有所帮助?
  • swi指令中传入的值在指令中编码,见arm手册。同样,正如 arm 手册告诉您的那样,您可以使用链接寄存器来了解什么指令称为 swi,然后您必须阅读指令然后提取传递的值。这些值仅对处理程序有任何价值,如果您使用一些股票 arm rom 监视器或 arm linux 或任何操作系统处理程序,那么它们会有一个数字含义列表。

标签: c assembly arm cortex-a


【解决方案1】:

向量.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 立即数,而是在寄存器中传递一些东西。

这个例子没有启用中断,它只是展示了如何进行 svc/swi 调用以及如何实现异常处理程序。多年来,这些知识已在 arm 架构参考手册中得到详细记录。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-24
    • 1970-01-01
    • 1970-01-01
    • 2013-12-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多