arm_day12

来源:互联网 发布:40本网络禁书本地下载 编辑:程序博客网 时间:2024/04/29 08:46

   

 

异常种类:

复位异常            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

ftp://arm/day09/irq_uboot.rar

将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

 

 

 

 

 

 

 

 

 

 

 

0 0