210学习日记(11)_中断

210学习日记(11)

--中断

由于后面的IIC会用到中断,这里就先讲讲中断吧:

写完S5PV210的按键中断程序后,我才知道"6410只是一个过渡产品"确实是正确的,为什么这样说呢?下面我就给大家进行详细的阐述:

中断处理过程等等我就不讲了,一期视频里面已经讲得非常详细了,建议大家在学习本章前,把24406410的关于中断的视频再看一次。接下来,我就直接对比他们吧:

(1).对于2440

中断向量只出现在start.s开始部分,类容如下:

.globl _start

_start: b       reset

ldr pc, _undefined_instruction

ldr pc, _software_interrupt

ldr pc, _prefetch_abort

ldr pc, _data_abort

ldr pc, _not_used

ldr pc, _irq

ldr pc, _fiq

也就是说,中断向量的入口地址是固定的!!

(2).对于6410

中断向量不仅出现在start.s开始部分,类容如下:

.globl _start

_start: b       reset

ldr pc, _undefined_instruction

ldr pc, _software_interrupt

ldr pc, _prefetch_abort

ldr pc, _data_abort

ldr pc, _not_used

ldr pc, _irq

ldr pc, _fiq

还引入了向量地址寄存器(VICxADDRESS),它会进一步存储中断处理函数的入口地址,详细类容,请大家学习一期的6410的视频的相关章节。

(注意:关于6410的讲述可能有问题,因为我没有6410开发板,无法验证,仅供参考)

(3).对于S5PV210

只说一说6410只是一个过渡产品,就中断角度而言,是因为在S5PV210中,中断向量舍弃了start.s开始的部分(因为从某种角度来讲,S5PV210上电后,不在是从0地址开始执行了,大家可以看下学习日记(2)中介绍的S5PV210的启动流程),而只保留了向量地址寄存器(VICxADDRESS)部分,而该寄存器的功能和6410的一样。

问:既然S5PV210start.s中不在有中断向量,那么S5PV210是怎么处理中断的呢?

答:以按键中断为例子,当中断发生时,PC不再是跳到0x00000018地址处,而是去访问向量地址寄存器(VICxADDRESS),在该寄存器里面读出一个地址(即可以认为是我们的中断处理函数的地址),然后进一步跳到该地址处去执行。其他的过程和2440的处理过程一样(比如模式切换等等)

接下来我一个具体的按键中断为例子(实现按K4,计数器加1,按K5,计数器减1的功能),代码放在了"Tiny210学习日记_代码"目录下了,名为"12_key_irq"

一上来,就写start.s,和2440的几乎无差别(一定不用写中断向量和关看门狗),比如初始化时钟,初始化nand,初始化内存,初始化需要模式的栈(用户模式,中断模式)等等操作,当然也会初始化中断,类容如下:

void irq_init(void)

{

/* 设置GPH2_3(K4),GPH3_0(K5)用于中断 */

GPH2CON |= 0xf<<12;

GPH3CON |= 0xf<<0;

/* 设置触发方式为下降沿触发 */

EXT_INT_2_CON |= 0x2<<12;

EXT_INT_3_CON |= 0x2<<0;

/* 使能中断(GPIO里面的) */

EXT_INT_2_MASK &= ~(1<<3);

EXT_INT_3_MASK &= ~(1<<0);

/* 设置为IRQ中断 */

VIC0INTSELECT &= ~(1<<16);

/* 使能中断(中断控制器里面的) */

VIC0INTENABLE |= 1<<16;

/* 设置中断向量 */

VIC0VECTADDR16 = (int)key_IRQ; 

}

注意:

当中断发生时,VIC0VECTADDR16中的值(即中断处理函数的地址)会被自动的复制给向量地址寄存器(VICxADDRESS),然后当中断发生时,就会访问向量地址寄存器(VICxADDRESS),从而找到key_IRQ中断处理函数。(这些在6410视频里面有讲解)

问:以前2440在中断来时,我们会计算返回地址,保护现场等操作,难道S5PV210就不用了吗?

答:答案是否定的,S5PV210一样是要做的,而且一个不能够少,过程如下(这部分程序写在start.s)

.global key_IRQ

key_IRQ:                /* 该函数就是在中断初始化中,VIC0VECTADDR16指向的函数 */

sub lr, lr, #4          /* 1.计算返回地址 */

stmdb sp!, {r0-r12, lr}  /* 2.保护现场 */

/* 3. 处理异常 */

bl do_irq

/* 4. 恢复现场 */

ldmia sp!, {r0-r12, pc}^  /* ^表示把spsr恢复到cpsr */

最终,经过上面的处理后,又和我们的2440的中断函数完全一样了,因此我们就在do_irq函数中清中断,分辨中断,执行处理等操作,该部分程序中是这样做的,如下:

void do_irq(void)

{

/* 清中断 */

EXT_INT_2_PEND |= 1<<3;

EXT_INT_3_PEND |= 1<<0;

/* 清中断向量 */

VIC0ADDRESS = 0;

if(!(GPH2DAT & (1<<3)))      /* 如果K4被按下 */

{

wy_printf("counter(k4) : %d \n",i++); /* 计数器加1 */

}

if(!(GPH3DAT & (1<<0)))      /* 如果K4被按下 */

{

wy_printf("counter(K5) : %d \n",i--);/* 计数器减1 */

}

}

注意:

1.参考代码放在了"Tiny210学习日记_代码"目录下了,名为"12_key_irq"

2.测试方法,当终端有显示后,直接按开发板上面的K4K5键,就能实现计数功能。

注:

如有问题,请到韦东山LINUX视频讨论群里面,我们一起讨论学习,或者加我QQ317312379

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值