异常向量表编程处理

1、像内存一样去访问异常向量表
(1)S5PV210的异常向量表可以改变(在CP15协处理器中),以适应操作系统的需求(因为操作系统建立之前和建立之后操作异常的方法是不一样的,因为操作系统运行起来整个地址变成了虚拟地址,这时候要有一个虚拟地址和物理地址的转换。这些和异常向量表有一定关联,所以异常向量表可以改变的)。但是目前系统刚启动时,此时DRAM尚未初始化,程序都在SRAM中运行,210在iRAM中设置了异常向量表,供暂时使用。
(2)查210的iROM applicationnote文档中iRAM的地址分配,可知,iRAM中的异常向量表起始地址为:0xD0037400。知道了异常向量表的起始地址后,各个异常对应的入口变很好知道了(因为每个异常相对地址是一定的,现在知道了基地址,要知道那个异常的地址只要加上相对的偏移量就行了)。
2、函数名名实质是函数的首地址
(1)函数名在C语言中的理解和变量名其实没区别。(变量名其实就是个符号,从编译器角度看变量名变这个个符号绑定了一个内存空间。也就是把变量名和一个对应的内存空间绑定)编译器会把这个函数的函数体对应的代码段和这个函数的函数名(实质是符号)对应起来,等我们使用这个函数名符号时,编译器会将函数的函数体实际上做替换。因为我们的函数体都不止4字节,而函数名这个符号只能对应1个地址,所以实际对应的是函数体那一个代码段的首地址。
(2)拿C语言中的语法来讲,函数名就是这个函数的函数指针。
总结:当我们将异常处理程序的首地址和异常向量表绑定起来后,异常处理初步阶段就完成了。到目前可以保证相应异常发生后,硬件自动跳转到对应异常向量表入口去执行时,可以执行到我们事先绑定的函数(函数只是做实验用,还不完整)。
3、为什么中断处理要先在汇编中进行
(1)中断处理要注意保护现场(中断从SVC模式来,则保存SVC模式下的必要寄存器的值)和恢复现场(中断处理完后,准备返回SVC模式前,要将保存的SVC模式下的必要寄存器的值恢复回去,不然到了SVC模式后寄存器的值乱了,SVC模式下原来正在进行的常规任务就被你搞坏了)(共用的寄存器就要保存)
(2)保存现场包括:第一,设置IRQ(模式)栈;第二,保存LR;第三,保存R0 ~ R12(共用寄存器)
(3)为什么要保存LR寄存器?要考虑中断返回的问题。中断ISR(中断服务程序)执行完后如何返回SVC模式下去接着执行原来的代码。中断返回其实取决于我们进入中断时如何保存现场。中断返回关键的2个寄存器是PC和CPSR。所以我们在进入IRQ模式时,应该将SVC模式下的下一句指令的地址(中断返回地址)和CPSR保存起来,将来恢复时才可以将中断返回地址给PC,将保存的CPSR给CPSR。
(4)中断返回地址就保存在LR中,而CPSR(自动)保存在(IRQ模式下的)SPSR中。
4、汇编保存现场和恢复现场
//IRQ栈地址
#define IRQ_STACK 0xD0037f80
//在这个汇编函数中,用来做中断模式下的现场保护和恢复,并且调用真正的中断处理程序
IRQ_handle:
//设置IRQ模式下的栈
ldr sp, IRQ_STACK
//保存LR
//因为ARM有流水线,所以PC的值会比真正执行的代码地址+8(多两节),(取指、解码、执行,因为中断规定当发生中断时在执行了一条完整指令后去跑转)如我们有两条 //指令,第一条在执行,同时第二条正在解码。所以要返回第二条指令开始处要减4

sub lr, lr #4 //因为ARM流水线所以要减4
//保存r0 — r12 和 lr 到irq 模式下的栈上面
stmfd sp! { r0 - r12, lr }
//在此调用真正的isr来处理中断
bl irq_handler
//处理完成开始恢复现场,其实就是做中断返回,关键是将 r0 - r12, pc, cpsr 一起恢复
ldrfd sp! { r0 - r12, pc }^ //(!号表示SP会叠加)(^号表示把中断下的SPSR恢复到cpsr)

//,这个应该定义在另外一个文件中(int.c),真正的中断处理程序。意思就是说这里只考虑中断处理,不考虑保护/恢复现场
void irq_headler(void)
{
printf(“irq_exception.当前我们只给个中断处理提示\n”);
}

参考图解:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

发布了41 篇原创文章 · 获赞 2 · 访问量 713
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 深蓝海洋 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览