完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
ARM体系结构中,把复位、中断、快速中断等都看作‘异常’,当这些‘异常’发生时,CPU会到固定地址处去找指令,他们对应的地址如下: n 地址 异常类型 进入时的工作模式 n 0x00000000 Reset Supervisor n 0x00000004 Und Undefined n 0x00000008 Soft interupt Supervisor n 0x0000000c Abort(prefetch) Abort n 0x00000010 Abort(data) Abort n 0x00000014 Reserved Reserved n 0x00000018 IRQ IRQ n 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 : 1; /* IRQ does not mask in IRQ */ unsigned int enabled : 1; /* IRQ is currently enabled */ unsigned int triggered: 1; /* IRQ has occurred */ unsigned int probing : 1; /* IRQ in use for a probe */ unsigned int probe_ok : 1; /* IRQ can be used for probe */ unsigned int valid : 1; /* IRQ claimable */ unsigned int noautoenable : 1; /* don't automatically enable IRQ */ unsigned int unused :25; void (*mask_ack)(unsigned int irq); /* Mask and acknowledge IRQ */ void (*mask)(unsigned int irq); /* Mask IRQ */ void (*unmask)(unsigned int irq); /* Unmask IRQ */ struct irqaction *action; /* * IRQ lock detection */ unsigned int lck_cnt; unsigned int lck_pc; unsigned int lck_jif; }; |
|
相关推荐 |
|
ElfBoard ELF 1板卡-开发板启动后打印random: nonblocking pool is initialized
393 浏览 0 评论
G2D图像处理硬件调用和测试-基于米尔-全志T113-i开发板
1860 浏览 0 评论
飞凌嵌入式ElfBoard ELF 1板卡- 减少uboot阶段的等待时间
1260 浏览 0 评论
嵌入式学习-飞凌ElfBoard ELF 1板卡 - 重新打包文件系统发现ftp无法正常连接
1753 浏览 0 评论
飞凌嵌入式ElfBoard ELF 1板卡-6ull设置两个ip
2305 浏览 0 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-4-20 04:05 , Processed in 3.578839 second(s), Total 62, Slave 45 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号