异常种类:
复位异常 SVC管理模式
未定义指令异常 未定义模式
SWI软中断异常 SVC管理模式
预取指令异常 中止模式
数据异常 中止模式
中断 中断模式
快速中断 快速中断模式
异常处理:
CPU:
1.备份CPSR,SPSR=CPSR
2.修改CPSR
1.修改状态位bit[5],ARM状态
2.修改工作模式位bit[4:0]为相应异常模式
3.修改相应中断位
3.保存返回地址lr=pc-4
4.pc=相应异常处理程序的入口点(异常向量表的地址)
5.进入异常处理程序中去处理异常
6.异常处理完毕,异常返回
软中断异常
当程序执行swi指令时,在该指令的执行阶段,就会触发软中断异常
shell#s1
shell#s2
将irq_uboot.rar拷贝到共享目录中,在windows解压
cp bss swi -rf
cd swi
cp /mnt/hgfs/1405/irq_uboot/irq_uboot/* ./
vector.s
irq.c
go 20000000
vector.s
b reset //reset定义在reset.s文件中
reset.s
reset:
1.将模式该SVC管理模式,并且屏蔽中断
2.安装MMU地址转换表,开启MMU,之后CPU给出的地址都是虚拟地址,这些地址都会被MMU截获,之后查MMU地址转换表,将虚拟地址转换为物理地址,之后再按照物理地址去访问存储器。
3.初始化FIQ,IRQ模式下栈顶指针
4.清空BSS段
5.跳转到程序main函数
cmd.c
加了两条命令
s1 cmd_swi1 swi_test1 swi 1
s2 cmd_swi2 swi_test2 swi 2
当
tarena#s1
cmd_swi1 swi_test1 swi 1
一旦指定swi1指令,到了该指令的执行阶段,产生异常
CPU:
1.备份CPSR,SPSR_svc=CPSR
2.修改CPSR
1.修改状态位bit[5],ARM状态
2.修改工作模式位bit[4:0]为相应SVC管理模式
3.修改相应中断位
3.保存返回地址lr=pc-4
4.pc=0x8(异常向量表的地址)
5.进入异常处理程序_swi_handler中去处理异常,调用c的处理程序c_swi_handler,一级一级返回,先返回_swi_handler,再返回正常的程序
6.异常处理完毕,异常返回
7.shell#
tarena#s2
cmd_swi2 swi_test2 swi 2
一旦指定swi2指令,到了该指令的执行阶段,产生异常
CPU:
1.备份CPSR,SPSR_svc=CPSR
2.修改CPSR
1.修改状态位bit[5],ARM状态
2.修改工作模式位bit[4:0]为相应SVC管理模式
3.修改相应中断位
3.保存返回地址lr=pc-4
4.pc=0x8(异常向量表的地址)
5.进入异常处理程序_swi_handler中去处理异常,调用c的处理程序c_swi_handler,一级一级返回,先返回_swi_handler,再返回正常的程序
6.异常处理完毕,异常返回
7.shell#
tarena#s1开灯 swi 1
tarena#s2关灯 swi 2
swi指令格式
ARM状态格式32bit
cond:条件
1111:swi指令的操作码
swi number:中断号(24bit)
Thumb状态格式16bit
swi number:中断号8bit
区分号:
根据不同中断号,做不同处理
将SWI指令的中断号提取出来
1.确定执行swi指令时的,CPU所处的状态 ARM Thumb
ARM 状态:swi32bit 中断号:24bit
Thumb状态:swi16bit 中断号:8bit
在异常发生时,CPU已经将之间SPSR_svc=CPSR
判断SPSR 的bit[5]=0,ARM状态
bit[5]=1,Thumb状态
2.SWI指令码如何获得?
CPU,保存lr=pc-4,是swi的下一条指令的地址
保存lr=pc-2,是swi的下一条指令的地址
ARM:swi指令码的地址,lr-4 ldr
Thumb:swi指令码的地址,lr-2 ldrh
3.用位运算将获取到的指令码中的中断号
ARM:低24bit
Thumb: 低8bit
4.R0中就保存了中断号
5.进入c_swi_handler执行
irq.c
void c_swi_handler(unsigned int num)
{
switch(num)
case 1:
break; //开灯
case 2:
break; //关灯
}
1.读SPSR
mrs
2.条件执行加载指令
ldr r0,[lr, #-4]
ldrh
3.用位运算提取r0中的号
区分swi指令的中断号:
tarena#s1
cmd_swi1 swi_test1 swi 1
一旦指定swi1指令,到了该指令的执行阶段,产生异常
CPU:
1.备份CPSR,SPSR_svc=CPSR
2.修改CPSR
1.修改状态位bit[5],ARM状态
2.修改工作模式位bit[4:0]为相应SVC管理模式
3.修改相应中断位
3.保存返回地址lr=pc-4
4.pc=0x8(异常向量表的地址)
5.进入异常处理程序_swi_handler中去处理异常,提取中断号,中断号为1,传递给c的处理程序c_swi_handler,case1,做开灯操作,一级一级返回,先返回_swi_handler,再返回正常的程序
6.异常处理完毕,异常返回
7.shell#
tarena#s2
cmd_swi2 swi_test2 swi 2
一旦指定swi2指令,到了该指令的执行阶段,产生异常
CPU:
1.备份CPSR,SPSR_svc=CPSR
2.修改CPSR
1.修改状态位bit[5],ARM状态
2.修改工作模式位bit[4:0]为相应SVC管理模式
3.修改相应中断位
3.保存返回地址lr=pc-4
4.pc=0x8(异常向量表的地址)
5.进入异常处理程序_swi_handler中去处理异常, 提取中断号,中断号为2,传递给调用c的处理程序c_swi_handler,case2,关灯,一级一级返回,先返回_swi_handler,再返回正常的程序
6.异常处理完毕,异常返回
7.shell#
MMU
异常向量表
0x0,0x4,0x8….0x1C
0x20000000
虚拟地址 | 物理地址 |
0x0000 0000--0x0FFF FFFF (0-256M) | 0x2000 0000 –0x2FFF FFFF (外接的物理内存) |
0x1000 0000—0x1FFF FFFF (256M-512M) | 无映射,访问将报错 |
0x2000 0000—0x5FFF FFFF (512M-1.5G) | 0x2000 0000—0x5FFF FFFF |
0x6000 0000—0x7FFF FFFF (1.5G-2G) | 无映射,访问将报错 |
0x8000 0000—0xAFFF FFFF (2G-2.75G) | 0x8000 0000—0xAFFF FFFF |
0xB000 0000—0xBFFF FFFF (2.75-3G) | 0xB000 0000—0xBFFF FFFF Nand Flash SFR |
0xC000 0000—0xCFFF FFFF (3G-3.25G) | 0x2000 0000—0x2FFF FFFF |
0xD000 0000—0xFFFF FFFF (3.25G-4G) | 0xD000 0000—0xFFFF FFFF SFR |
tarena# s1
PC=0x8(虚拟地址)->由于MMU被开启,查MMU的地址转换表
0x0000 0000 ->0x2000 0000
0x0000 0008-> 0x2000 0008
tarena#tftp 20000000 shell.bin
tarena#go 20000000
中断
中断源:
通过查看Key的硬件原理图,得知,key1和key2分别连接到CPU的GPH0_0 和GPH0_1这两个管脚
外部中断0:key1 EXT_INT[0]
外部中断1:key2 EXT_INT[1]
禁止这两个管脚内部的上下拉电阻
中断触发方式:
电平触发:(高电平,低电平)
边沿触发:(上升沿,下降沿),只有在电平发生跳变时才触发中断
如果采用低电平触发,若按键按下不松开,就会一直产生中断,所以此处采用下降沿触发。
禁止滤波功能
0:使能该外部中断
1:关闭外部中断
该寄存器表示中断是否产生,当外部中断0来了,该寄存器的bit[0]会被自动置1,如果中断控制器使能,ARM核中断响应打开,则CPU响应中断,但必须在中断服务程序中将该位清除,否则,CPU一直会响应中断
清零,写1清0,写0,无效。
中断控制器
s5pv210有93个中断源
分组方式:4组:VIC0(32),VIC1(32),VIC2(32),VIC3(32)
每组有32个编号
128个编号
EXINT0
EXINT1
这两个Key中断处于VIC0组
s5pc100处理器的datasheet
S5PC100_UM_REV104(SAMSUNG).pdf
此图为s5pc100处理器的中断控制器结构图,以此作为参考:
1.TZIC0的select寄存器,是走IRQ还是FIQ(TZICINTSELECT)
2.VIC0的select寄存器,是走IRQ还是FIQ(VICINTSELECT)
VIC0->nNSFIQIN->TZIC0->nTZICFIQ->cortex-A8
3.使能中断寄存器(VICINTENABLE)
4.清除中断寄存器(VICINTCLEAR)
5.中断处理程序寄存器,VICVECTADDR,128个,93个中断,每个中断源都有一个此寄存器,用来保存对应中断处理器程序的地址
6.中断向量地址寄存器(VICADDRESS),4个,每组有一个,中断控制器写,用户读,并且在中断服务程序中的最后要将该寄存器清0
1.TZIC0的select寄存器,是走IRQ还是FIQ(TZICINTSELECT)
走IRQ:bit[0]=0
2.VIC0的select寄存器,是走IRQ还是FIQ(VICINTSELECT)
走IRQ:bit[0]=0
3.使能中断寄存器(VICINTENABLE)
使能中断:
读0,中断关闭
读1,中断打开
写1,打开中断
写0,无效
4.清除中断寄存器(VICINTCLEAR)
写0,无效果
写1,实现将VICINTENABLE对应bit位清0,中断关闭
5.中断处理程序寄存器,VICVECTADDR,128个,93个中断源,每个中断源都有一个此寄存器,用来保存对应中断处理程序的地址
6.中断向量地址寄存器(VICADDRESS),4个,每组有一个,中断控制器写,用户读,并且在中断服务程序中的最后要将该寄存器清0