您现在的位置: 主页 > MCU > 单片机技术应用 > ARM-Linux 中断分析 -
本文所属标签:
为本文创立个标签吧:

ARM-Linux 中断分析 -

来源: 网络用户发布,如有版权联系网管删除 2018-09-06 

[导读]ARM体系结构中,把复位、中断、快速中断等都看作‘异常’,当这些‘异常’发生时,CPU会到固定地址处去找指令,他们对应的地址如下: 地址 异常类型 进入时的工作模式 0x00000000 Reset Supervisor 0x00000004 Und U

ARM体系结构中,把复位、中断、快速中断等都看作‘异常’,当这些‘异常’发生时,CPU会到固定地址处去找指令,他们对应的地址如下:

本文引用地址: http://www.21ic.com/app/mcu/201807/784665.htm

地址 异常类型 进入时的工作模式

0x00000000 Reset Supervisor

0x00000004 Und Undefined

0x00000008 Soft interupt Supervisor

0x0000000c Abort(prefetch) Abort

0x00000010 Abort(data) Abort

0x00000014 Reserved Reserved

0x00000018 IRQ IRQ

0x0000001c FIQ FIQ

首先要明确的一点就是,无论内存地址空间是如何映射的,以上这些地址都不会变,比如当有快速中断发生时,ARM将铁定到0X0000001C这个地址处取指令。这也是BOOTLOADER把操作系统引导以后,内存必须重映射的原因!否则操作系统不能真正接管整套系统!

LINUX启动以后要初始化这些区域,初始化代码在main.c中的start_kernel()中,具体是调用函数trap_ini()来实现的。如下面所示(具体可参照entry-armv.S):

.LCvectors: swi SYS_ERROR0

b __real_stubs_start + (vector_undefinstr - __stubs_start)

ldr pc, __real_stubs_start + (.LCvswi - __stubs_start)

b __real_stubs_start + (vector_prefetch - __stubs_start)

b __real_stubs_start + (vector_data - __stubs_start)

b __real_stubs_start + (vector_addrexcptn - __stubs_start)

b __real_stubs_start + (vector_IRQ - __stubs_start)

b __real_stubs_start + (vector_FIQ - __stubs_start)

ENTRY(__trap_init)

stmfd sp!, {r4 - r6, lr}

adr r1, .LCvectors @ set up the vectors

ldmia r1, {r1, r2, r3, r4, r5, r6, ip, lr}

stmia r0, {r1, r2, r3, r4, r5, r6, ip, lr}

add r2, r0, #0x200

adr r0, __stubs_start @ copy stubs to 0x200

adr r1, __stubs_end

1: ldr r3, [r0], #4

str r3, [r2], #4

cmp r0, r1

blt 1b

LOADREGS(fd, sp!, {r4 - r6, pc})

以上可以看出这个函数初始化了中断向量,实际上把相应的跳转指令拷贝到了对应的地址。

当发生中断时,不管是从用户模式还是管理模式调用的,最终都要调用do_IRQ():

__irq_usr: sub sp, sp, #S_FRAME_SIZE

stmia sp, {r0 - r12} @ save r0 - r12

ldr r4, .LCirq

add r8, sp, #S_PC

ldmia r4, {r5 - r7} @ get saved PC, SPSR

stmia r8, {r5 - r7} @ save pc, psr, old_r0

stmdb r8, {sp, lr}^

alignment_trap r4, r7, __temp_irq

zero_fp

1: get_irqnr_and_base r0, r6, r5, lr

movne r1, sp

adrsvc ne, lr, 1b

@

@ routine called with r0 = irq number, r1 = struct pt_regs *

@

bne do_IRQ @ 调用do_IRQ来实现具体的中断处理

mov why, #0

get_current_task tsk

b ret_to_user

对于以上代码,在很多文章中都有过分析,这里不再赘述。

Linux每个中断通过一个结构irqdesc来描述,各中断的信息都在这个结构中得以体现:

struct irqdesc {

unsigned int nomask



              查看评论 回复



嵌入式交流网主页 > MCU > 单片机技术应用 > ARM-Linux 中断分析 -
 

网站地图

围观()