6410之异常中断处理
来源:互联网 发布:淘宝网蒸锅小片毕链 编辑:程序博客网 时间:2024/06/07 01:00
单片机中断方式获取键值:
1.按键按下
2.CPU发生中断,跳转到异常向量入口地址执行
3.跳转到中断处理函数
中断处理函数的工作有:
a.保存被中断的现场
b.执行中断处理函数
c.恢复现场
linux中断方式获取键值:
1.异常向量的设置:ARM架构的CPU的异常向量基地之可以在0x00000000(比如之前裸板程序中所说的异常向量基地址就在这里),也可以是0xffff0000(linux内核使用的地址)可以查看trap_init函数进行查看它是如何将异常向量赋值到0xffff0000处的。拷贝的动作如下所示:
void __init early_trap_init(void)
{
。。。
memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start);
。。。
}
2.这里vectors,__vectors_start,__vectors_end的定义如下:
vectors:
unsigned long vectors = CONFIG_VECTORS_BASE; // #define CONFIG_VECTORS_BASE 0xffff0000即为linux的虚拟地址
__vectors_start,__vectors_end定义在entry-armv.S (arch\arm\kernel),定义如下:
.globl __vectors_start
__vectors_start:
ARM( swi SYS_ERROR0 )
THUMB( svc #0 )
THUMB( nop )
W(b) vector_und + stubs_offset
W(ldr) pc, .LCvswi + stubs_offset
W(b) vector_pabt + stubs_offset
W(b) vector_dabt + stubs_offset
W(b) vector_addrexcptn + stubs_offset
W(b) vector_irq + stubs_offset
W(b) vector_fiq + stubs_offset
.globl __vectors_end
__vectors_end:
从上面可以看到__vectors_start和__vectors_end之间就是异常向量处理跳转列表。
3.取irq为例:
W(b) vector_irq + stubs_offset
vector_irq 的定义如下:
vector_stub irq, IRQ_MODE, 4
展开为:
.macro vector_stub, name, mode, correction=0
//.macro vector_stub, irq, IRQ_MODE, 4
.align 5
vector_\name:
//vector_irq:
.if \correction
//.if 4
sub lr, lr, #\correction
//sub lr, lr, #4 减去4个字节,保证中断返回还是执行的是当前指令
.endif
@
@ Save r0, lr_<exception> (parent PC) and spsr_<exception>
@ (parent CPSR)
@
stmia sp, {r0, lr}@ save r0, lr
mrs lr, spsr
str lr, [sp, #8]@ save spsr
@
@ Prepare for SVC32 mode. IRQs remain disabled.
@
mrs r0, cpsr
eor r0, r0, #(\mode ^ SVC_MODE | PSR_ISETSTATE)
msr spsr_cxsf, r0
@
@ the branch table must immediately follow this code
@
and lr, lr, #0x0f
THUMB( adr r0, 1f )
THUMB( ldr lr, [r0, lr, lsl #2] )
mov r0, sp
ARM( ldr lr, [pc, lr, lsl #2] )
movs pc, lr@ branch to handler in SVC mode
ENDPROC(vector_\name)
上面做好准备工作就会跳转到下面的列表,下面列表列出的是在各种模式下发生中断所要跳转的中断列表:
.long __irq_usr @ 0 (USR_26 / USR_32)
.long __irq_invalid@ 1 (FIQ_26 / FIQ_32)
.long __irq_invalid@ 2 (IRQ_26 / IRQ_32)
.long __irq_svc@ 3 (SVC_26 / SVC_32)
.long __irq_invalid@ 4
.long __irq_invalid@ 5
.long __irq_invalid@ 6
.long __irq_invalid@ 7
.long __irq_invalid@ 8
.long __irq_invalid@ 9
.long __irq_invalid@ a
.long __irq_invalid@ b
.long __irq_invalid@ c
.long __irq_invalid@ d
.long __irq_invalid@ e
.long __irq_invalid@ f
比如在用户模式和svc模式下发生了中断,就会跳转到__irq_usr,或__irq_svc去执行。在其他工作模式下不可能发生中断异常,否则使用"__irq_invalid",ARM架构CPU中使用4位数据来表示工作模式(目前只有7中工作模式),所以共有16个跳转分支。
4.__irq_usr所做的工作就和单片机做所的事情就很类似了
__irq_usr:
usr_entry //保存寄存器,保存现场
kuser_cmpxchg_check
get_thread_info tsk
#ifdef CONFIG_PREEMPT
ldr r8, [tsk, #TI_PREEMPT]@ get preempt count
add r7, r8, #1@ increment it
str r7, [tsk, #TI_PREEMPT]
#endif
irq_handler //中断处理调用asm_do_IRQ函数,恢复现场
#ifdef CONFIG_PREEMPT
ldr r0, [tsk, #TI_PREEMPT]
str r8, [tsk, #TI_PREEMPT]
teq r0, r7
ARM( strne r0, [r0, -r0] )
THUMB( movne r0, #0 )
THUMB( strne r0, [r0] )
#endif
mov why, #0
b ret_to_user
UNWIND(.fnend )
ENDPROC(__irq_usr)
- 6410之异常中断处理
- Arm架构异常处理流程之中断
- 6410之中断处理
- 6410之中断处理
- Linux中断系列之中断或异常处理(四)
- s3c2410 中断异常处理
- s3c2410 中断异常处理
- s3c2410 中断异常处理
- s3c2410 中断异常处理
- s3c2410 中断异常处理
- ARM 异常中断处理
- s3c24x0 中断异常处理
- 异常中断处理
- 中断与异常处理
- 异常与中断处理
- Xen处理中断、异常
- s3c2410 中断异常处理
- 6410之异常处理
- 【读书笔记】usOS-II学习笔记(2008-11-4)
- .NET架构改造
- Linux 性能监测:Memory
- How to stop recursion on Django's post_save signal
- nyoj-73-比大小
- 6410之异常中断处理
- Conversion to Dalvik format failed with error 1错误解决
- dsPIC33F串口通讯中断接收发送数据-UART
- PHPCMS V9内容页点击量如何调用
- 对linux系统运行性能的分析
- svn: None of the environment variables SVN_EDITOR...问题解决
- Android 流媒体系列(二)
- Linux 性能监测:Network
- C# WinForm 跨线程访问控件