异常与中断的概念及处理流程

中断的引入

中断:在主程序运行过程中,出现了特定的中断触发条件(中断源),使得CPU 暂停在当前正在运行的程序,转而去处理中断程序,处理完成后又返回原来被暂停的位置继续运行。

比如有这么几种情况:

  1. 对于外部中断而言,可以是引脚电平发生了跳变;
  2. 对于定时器而言,可以是定时时间到了;
  3. 对于串口通信而言,可以是接收到了数据。

中断优先级

当有多个中断源同时申请中断时,CPU 会根据中断源的轻重缓急进行裁决,优先响应更加紧急的中断源

中断嵌套

当一个中断程序正在运行时,又有新的更高优先级的中断源申请中断,CPU 再次暂停当前中断程序,转而去处理新的中断程序,处理完成后以此进行返回。

在这里插入图片描述

用一张生活的例子

在这里插入图片描述
图中的妈妈是怎么知道孩子醒了?

  1. 查询的方式: 时不时进房间看一下
    • 简单,但是累
  2. 休眠-唤醒:进去房间陪小孩一起睡觉,小孩醒了会吵醒她
    • 不累,但是妈妈干不了活。
  3. poll 方式: 妈妈要干很多活,但是可以陪小孩睡一会,定个闹钟
    • 要浪费点时间,但是可以继续干活。妈妈要么是被小孩吵醒,要么是被闹钟吵醒。
  4. 异步通知:妈妈在客厅干活,小孩醒了他会自己走出房门告诉妈妈
    • 妈妈、小孩互不耽误。

后面的3种方式,都需要小孩中断妈妈:中断她的睡眠,中断她的工作。实际上,能中断 妈妈的事情可多了:

  1. 发生了各种声音
  2. 可忽略的远处猫叫
  3. 快递员按门铃
  4. 卧室中小孩哭了

妈妈当前正在看书,被这些事件“中断”后她会怎么做?流程如下:

  • 第一步
    先在书中放入书签,合上树
  • 第二步
    去处理,对于不同的情况,处理方法不同:
    • 对于门铃:开门取快递
    • 对于哭声:照顾小孩
  • 第三步
    回来继续看书

嵌入系统中也有类似的情况

在这里插入图片描述
CPU 在运行的过程中,也会被各种“异常”打断。这些“异常”有:

  1. 指令未定义
  2. 指令、数据访问有问题
  3. SWI (软中断)
  4. 快中断
  5. 中断

中断也属于一种异常,导致中断发生的情况有很多

  1. 按键
  2. 定时器
  3. ADC 转换完成
  4. UART 发送完成数据、收到数据

这些众多的中断源,汇集到 中断控制器,由中断控制器选择优先级最高的中断并通知cpu

中断的处理流程

arm 对异常(中断)处理过程

  1. 初始化
    • 设置中断源,让它可以产生中断
    • 设置中断源控制器(可以屏蔽某个中断源,优先级)
    • 设置CPU 总开关(使能中断)
  2. 执行其他程序:正常程序
  3. 产生中断:比如按下按键—>中断控制器—>CPU
  4. CPU 每执行完一条指令都会检查有无中断/异常产生
  5. CPU 发现有中断/异常产生,开始处理。
    对于不同的异常,跳去不同的地址执行程序
    地址上,只是一条跳转指令,跳去执行某个函数(地址),这个就是异常向量。
    ③④⑤都是硬件做的。
  6. 这些函数都做了哪些事情呢?
    软件做的:
    • 保存现场
    • 处理异常(中断):分辨中断源,再调用不同的处理函数
    • 恢复现场

上面步骤是重点

在这里插入图片描述

异常向量表

u-boot 或者是Linux 内核,都有类似的代码

_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         //发生中断时, CPU 跳到这个地址执行该指令 **假设地址为 0x18**
    ldr pc, _fiq

这就是异常向量表,每一条指令对应一种异常。
发生复位时, CPU 就去 执行第 1 条指令: b reset。
发生中断时, CPU 就去执行“ ldr pc, _irq”这条指令。
这些指令存放的位置是固定的,比如对于 ARM9 芯片中断向量的地址是0x18。
当发生中断时, CPU 就强制跳去执行 0x18 处的代码。

在向量表里,一般都是放置一条跳转指令,发生该异常时, CPU 就会执行向量表中的跳转指令,去调用更复杂的函数。

当然,向量表的位置并不总是从 0 地址开始,很多芯片可以设置某个vector base 寄存器,指定向量表在其他位置,比如设置 vector base 为0x80000000,指定为 DDR 的某个地址。但是表中的各个异常向量的偏移地址,是固定的:复位向量偏移地址是 0,中断是 0x18。

  • 21
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值