Cortex-M3异常

异常类型

Cortex-M3再内核水平上搭载了一个异常响应系统,支持为数众多的系统异常和外部中断(这里的外部是相对于CM3内核来说的)。

其中编号为1~15的对应系统异常,大于等于16的则全是外部中断(CM3内核外部)。

除个别异常的优先级被定死外,其他异常的优先级都是可编程的(所有能打断正常执行流的事件都成为异常)。

芯片设计者可以修改CM3的硬件描述代码,所以做成芯片后,支持的中断源数目常常不到240个,并且优先级的位数也由芯片厂商最终决定。

系统异常清单

编号类型优先级简介
0N/AN/A没有异常在运行
1复位-3(最高)复位
2NMI-2不可屏蔽中断(来自外部NMI输入脚)
3硬fault-1所有被除能的fault,都将上访成硬fault。只要FAULTMASK没有置位,硬fault服务例程就被强制执行。Fault被除能的原因包括被禁用,或者FAULTMASK被置位。
4MemManage fault可编程存储管理器fault,MPU访问犯规以及访问非法位置均可引发。企图在”非执行区“取指也会引发此fault。
5总线fault可编程从总线系统收到了错误响应,原因可以是预取流产(Abort)或数据流产,或者企图访问协处理器
6用法fault可编程由于程序错误导致的异常。通常是使用了一条无效指令,或者是非法的状态转换,例如尝试切换到ARM状态。
7-10保留N/AN/A
11SVCall可编程执行系统服务调用指令(SVC)引发的异常
12调试监视器可编程调式监视器(断点、数据观察点、或者是外部调试请求)
13保留N/AN/A
14PendSV可编程为系统设备而设的”可悬挂请求“(pendable request)
15SysTick可编程系统滴答定时器(也就是周期性溢出的时基定时器)
16IRQ #0可编程外中断#0
17IRQ #1可编程外中断#1
255IRQ #239可编程外中断#239

如果一个发生的异常不能被即刻响应,就称它被”悬起“。不过,少数fault异常时不允许被悬起的。

优先级的定义

优先级的数值越小,则优先级越高。

CM3支持中断嵌套,使得高优先级异常会抢占低优先级异常。

有3个系统异常:复位、NMI、硬fault,他们有固定的优先级,并且他们的优先级是负数,从而高于所有其他异常。

所有其他异常的优先级都是可编程的(但不能编程为负数)。

CM3支持多达256级的可编程优先级,并且支持128级抢占。但是绝大多数CM3芯片都会精简涉及,以致实际上支持的优先级会更少,如8级、16级、32级。它们在设计时会裁掉表达优先级的几个低端有效位。(优先级号是以MSB对齐的)。

举例来说,如果只使用了3个位来表达优先级,则优先级配置寄存器的结构会如下图所示:
在这里插入图片描述
CM3允许的最少使用位数为3位,即最少需要支持8级优先级。

通过让优先级以MSB对齐,可以简化程序的跨器件移植。比如,如果一个程序早先在支持4位优先级的器件上运行,在移植到只支持3位优先级的器件后,其功能不受影响。但是若对齐到LSB,则会使MSB丢失,导致数值大于7的低优先级一下子升高了。

CM3还把256级优先级分成高低两段,分别是抢占优先级和亚优先级,如下所述。
NVIC中有一个寄存器是”应用程序中断及复位控制寄存器“(AIRCR),它里面有一个位段名为”优先级组“。把优先级分为两个位段:左边的对应抢占优先级,右边的对应亚优先级。如下:

在这里插入图片描述
抢占优先级决定了抢占行为:当系统正在响应某异常L时,如果来了抢占优先级更高的异常H,则H可以抢占L。亚优先级则处理”内务“:当抢占优先级相同的异常有不止一个悬起时,就优先响应亚优先级最高的异常。

这种优先级分组还规定:亚优先级至少是1个位。因此抢占优先级最多是7个位,也就造成了最多只有128级抢占的现象。

向量表

当发生了异常并且要响应它时,CM3需要定位器处理历程的入口地址。这些入口地址存储在所谓的”(异常)向量表“中。

缺省情况下,CM3认为该表位于零地址处,且各向量占用4字节。如下表所示:
在这里插入图片描述
地址0处通常是Flash或ROM器件,并且他们的值不得在运行时改变。然而,为了动态重分发中断,CM3允许向量表重定位————从其他地址处开始定位各异常向量。这些地址对应的区可以是代码区,但也可以是RAM区。在RAM区就可以修改向量的入口地址了。

为了实现这个功能,NVIC中有一个寄存器,称为“向量表偏移寄存器”。

Fault类异常

有若干个系统异常专用于fault处理。CM3中的Fault可分为以下几类:

  • 总线fault
  • 存储管理fault
  • 用法fault
  • 硬fault

SVC和PendSV

SVC(系统服务调用,亦简称系统调用)和PendSV(可悬起系统调用),他们多用于在操作系统之上的软件开发中。

SVC用于产生系统函数的调用请求。操作系统不让用户程序直接访问硬件,而是通过提供一系列系统服务函数,用户程序使用SVC发出对系统服务函数的呼叫请求,以这种方法调用它们来简介访问硬件。因此,当用户程序想要控制特定的硬件时,它就会产生一个SVC异常,然后操作系统提供的SVC异常服务例程得到执行,它再调用相关的操作系统函数,后者完成用户程序请求的服务。
SVC异常通过执行“SVC”指令来产生。该指令需要一个立即数,充当系统调用代号。SVC异常服务立场稍后会提取出此代号,从而解释本次调用的具体要求,再调用响应的服务函数。

PendSV:可悬起的系统调用,它和SVC协同使用。SVC异常是必须得到响应的(若因优先级不比当前正处理的高,或是其他原因使之无法立即响应,将上访成硬fault)。应用程序执行SVC时都是希望所需的请求立即得到响应。PendSV则不同,它是可以向普通的中断一样被悬起的,不想SVC那样会上访。OS可以利用它“缓期执行”一个异常————直到其他重要的任务完成后才执行动作。悬起PendSV的方法是:手工往NVIC的PendSV悬起寄存器中写1。悬起后,如果优先级不够高,则将缓期等待执行。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时空旅客er

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值