CM3异常实现

作者:@登云上人间

目录

支持 256 个优先级,为什么只有 128 个抢占级?

异常类型
1-15 是系统异常,大于等于 16 是外部中断。
image

image

优先级的定义

  • 优先级的数值越小,则优先级越高。CM3 支持中断嵌套,使得高优先级异常会抢占(preempt)低优先级异常。
  • 3 个系统异常:复位,NMI 以及硬 fault。有固定的优先级,优先级号是负数,从而高于所有其它异常。且不可编程。除此之外其他的异常都是可编程的。
  • CM3 支持 3 个固定的高优先级和多达 256 级的可编程优先级支持 128级抢占
  • 只使用 3 个位来表达优先级的优先级配置如下图:
    image
    [4:0]没有被实现,所以读它们总是返回零。CM3 允许的最少使用位数为 3 个位,亦即至少要支持 8 级优先级。
  • 优先级号是以MSB 对齐的(左对齐,高位对齐)

支持 256 个优先级,为什么只有 128 个抢占级?

答:为了使抢占机能变得更可控,CM3 把 256 级优先级按位分成高低两段,分别是抢占优先级和亚优先级

  • 应用程序中断及复位控制寄存器:有一个位段名为“优先级组”。该位段的值对每一个优先级可配置的异常都有影响——把其优先级分为个位段:MSB 所在的位段(左边的)对应抢占优先级,而 LSB 所在的位段(右边的)对应亚优先级,如下图。
    image
    image
  • 抢占优先级分工: 当系统正在响应某异常 L 时,如果来了抢占优先级更高的异常 H,则 H 可以抢占 L
  • 亚优先级分工: 当抢占优先级相同的异常不止一个悬起时,就优先响应亚优先级最高的异常

规定:亚优先级至少是 1 个位。因此抢占优先级最多是 7 个位
image

  • 除能 CM3 的中断嵌套机制:CM3 允许从比特 7 处分组,此时所有的位都表达亚优先级,没有任何位表达抢占优先级,所有优先级可编程的异常之间就不会发生抢占,

  • 复位,NMI 和硬 fault。无论何时出现,都立即无条件抢占所有优先级

  • 如果优先级完全相同,则先响应异常编号最小的

  • 优先级的分组要预先经过计算论证,并且在开机初始化时一次性地设置好,以后再也不动它。

向量表

  • “(异常)向量表”存放CM3异常处理函数的入口地址。CM3 认为该表位于零地址处,且各向量占用 4 字节
    image

  • 地址 0 处存储引导代码,通常是 Flash 或者是 ROM 器件,它们的值不得在运行时改变

  • CM3 允许向量表重定位——从其它地址处开始定位各异常向量。其他地址包括:代码区、RAM区。

  • 动态地更改向量表,对于任何器件,向量表的起始处都必须包含以下向量:

    • 主堆栈指针(MSP)的初始值
    • 复位向量
    • NMI
    • 硬 fault 服务例程
  • “向量表偏移量寄存器”,实现在 RAM区修改向量的入口地址,修改它的值就能定位向量表。向量表的起始地址要求:先求出系统中共有多少个向量,再把这个数字向上增大到是 2 的整次幂,而起始地址必须对齐到后者的边界上。例如,如果一共有 32 个 中断,则共有 32+16(系统异常)=48 个向量,向上增大到 2 的整次幂后值为 64,因此地址 地址必须能被 64* 4=256 整除,从而合法的起始地址可以是:0x0, 0x100, 0x200 等。
    image

中断输入以及悬起行为

  • 当中断输入脚被 assert 后,该中断就被悬起。即使后来中断源取消了中断请求,已经被标记成悬起的中断也被记录下来。到了系统中它的优先级最高的时候,就会得到响应。
    image

  • 在某个中断得到响应之前,其悬起状态被清除(例如,在 PRIMASK 或FAULTMASK 置位的时候软件清除了悬起状态标志),则中断被取消。
    image

  • 当某中断的服务例程开始执行时,称此中断进入了“活跃”状态,其悬起位被硬件自动清除。在一个中断活跃后,直到其服务例程执行完毕,并且返回 (亦称为中断退出),才能对该中断的新请求予以响应(即单实例)。中断服务例程也可以在执行过程中把自己对应的中断重新悬起
    image

  • 中断源咬住请求信号不放,该中断会在其上次服务例程返回后再次被置为悬起状态
    image

  • 如果某个中断在得到响应之前,其请求信号以若干的脉冲的方式呈现,则被视为只有一次中断请求,多出的请求脉冲全部错失。
    image

  • 在服务例程执行时,中断请求被释放,但是在服务例程返回前又重新被置为有效, 则 CM3 会记住此动作,重新悬起该中断。
    image

Fault 异常

  • 专用于 fault 处理的若干个系统异常。CM3 中的 Faults 分类:
    • 总线 faults
    • 存储器管理 faults
    • 用法 faults
    • 硬 fault

总线 Faults

  • AHB 接口上正在传送数据时,如果回复一个错误信号(error response),则会产生总线 faults

  • 使能总线 fault 服务例程,在 NVIC的 “系统 Handler 控制及状态寄存器”中置位BUSFAULTENA 位。

  • 针对数据传输的场所:

    • 取指,通常被称作“预取流产”(prefetch abort)
    • 数据读/写,通常被称作“数据流产”(data abort)
  • 针对错误信号触发的动作

    • 中断处理起始阶段的堆栈 PUSH 动作。 称为“入栈错误”
    • 中断处理收尾阶段的堆栈 POP 动作。 称为“出栈错误”
    • 在处理器启动中断处理序列(sequence)后的向量读取时。是一种罕见的特殊情况,被归类为硬 fault

哪些因素会导致 AHB 回复一个错误信号?

  • 企图访问无效的存储器 region。常见于访问的地址没有相对应的存储器。
  • 设备还没有作好传送数据的准备。比如,在尚未初始化 SDRAM 控制器的 时候试图访问 SDRAM。
  • 在企图启动一次数据传送时,传送的尺寸不能为目标设备所支持。例如, 某设备只接受字型数据,却试图送给它字节型数据。
  • 因为某些原因,设备不能接受数据传送。例如,某些设备只有在特权级下 才允许访问,可当前却是用户级。

总线 fault悬起和硬fault

  • 在检测到总线 fault 时还检测到了更高优先级的异常,则先处理后者,而总线 fault 则被标记成悬起。
  • 如果总线fault被除能,或者总线 fault 发生时正在处理同级或更高优先级异常,则总线 fault 被迫成为“硬伤”——上访成硬 fault,使得最后执行的是硬 fault 的服务例程。在硬 fault 服务例程的执行中又产生了总线 fault(钻牛角尖),内核将进入锁定状态

发生总线 fault 后,如何找出该 fault 的事故原因?

  • NVIC 提供若干个 fault 状态寄存器

  • “总线 fault 状态寄存器”(BFSR),确定产生 fault 的场合:在数据访问时?在取指时?还是在中断的堆栈操作时?以字方式访问,地址是 0xE000_ED28,以字节方式访问,地址是0xE000_ED29
    image

  • 精确的总线 fault,肇事的指令的地址被压在堆栈中。如果 BFSR 中 的 BFARVALID 位为 1,还可以找出是在访问哪块存储器时产生该总线 fault ,该存储器的地址被放到“总线 fault 地址寄存器(BFAR)”。

  • 不精确的总线 fault,无从定位

精确的总线 fault vs. 不精确的总线 fault

  • 数据访问产生的总线 fault,被归类为精确总线 fault 和不精确总线 fault
  • 不精确的总线 faults 中,导致此 fault 的指令早已完成。例如,缓冲区写入。启动缓冲区写入的指令不知何时已经执行了,但是写到中途时才触发总线 fault。可见,这个操作是在若干个时钟周期前执行的,而且不能确定是具体几个周 期之前,也没有记录这期间的程序跳转动作,因此无法确认“肇事者”,故而是不精确的。
  • 精确的总线 fault 是被最后一个完成的操作触发的。例如,一个存储器读取导致的 fault总是精确的,因为该指令必须等全部读完时才算执行完成。这样,任何在读取过程中发生的 fault 总能落在该指令的头上。
  • 取指和堆栈操作产生的 fault 总是精确

image

  • BFSR 寄存器是一个 8 位的寄存器,可以使用字传送和字节传送来读取
  • 以字方式访问,地址是 0xE000_ED28,且第 2 个字节有效;
  • 以字节方式访问,地址是 0xE000_ED29

存储器管理 faults

  • 多与MPU有关,其诱因一是某次访问触犯了MPU设置的保护策略。二是某些非法访问。
  • MemManage faults 的常见诱因:
    • 访问了 MPU 设置区域覆盖范围之外的地址(越界)
    • 往只读 region 写数据(越权)
    • 用户级下访问了只允许在特权级下访问的地址(越权)
  • MemManage fault 发生后,其服务例程是使能的,则执行服务例程。如果同时还发生了其它高优先级异常,则优先处理这些高优先级的异常,MemManage 异常被悬起。如果此时处理器已经在处理同级或高优先级异常,或者 MemManage fault 服务例程被除能,则和总线 fault 一样:上访成硬 fault,最终执行的是硬 fault 的服务例程。如果硬 fault 服务例程或 NMI 服务例程的执行也导致了 MemManage fault,那就不可救要了——内核将被锁定。
  • 和总线 fault 一样,MemManage fault 必须被使能才能正常响应。
  • MemManage fault在 NVIC“系统 handler 控制及状态寄存器”中的使能位是 MEMFAULTENA
  • 存储器管理 fault 状态寄存器(MFSR”,调查 MemManage fault 的案发现场,指出导致 MemManage fault 的原因

image

  • 8 位的寄存器,可以使用字传送和字节传送来读取。
  • 两种访问方式的地址都是 0xE000_ED28,按字访问时第 1 个字节有效。

用法 faults

硬 fault

  • 硬 fault 是总线 fault、存储器管理 fault 以及用法 fault 上访的结果(非硬fault 的服务例程无法执行,它们就会成为“硬伤”——上访(escalation)成硬 fault。)
  • 取向量(异常处理是对异常向量表的读取)时产生的总线 fault 也按硬 fault 处理
  • 硬fault 状态寄存器(HFSR),指出产生硬 fault 的原因

image

应对 faults???

  • 根据各种 fault 状态寄存器的值来判定程序错误,并且改正它们
  • 应付 fault 的常用方法:
    • 复位。设置 NVIC“应用程序中断及复位控制寄存器”中的VECTRESET 位,将只复位处理器内核而不复位其它片上设施有些CM3 芯片可以使用该寄存器的 SYSRESETREQ 位来复位。这种只限于内核中的复位不会复位其它系统部件。
    • 恢复。如果程序尝试访问了协处理器,可以通过一个协处理器的软件模拟器来解决此问题(牺牲性能)
    • 中止相关任务。系统运行了一个 RTOS,则相关的任务可以被终结或者重新开始

SVC 和 PendSV

NVIC

中断配置基础

中断的使能与除能

中断的悬起与解悬

优先级

活动状态

PRIMASK 与 FAULTMASK 特殊功能寄存器

BASEPRI寄存器

异常的配置寄存器

中断建立全过程、

软件中断

SysTick定时器

中断的具体行为
中断/异常的响应序列

异常返回

嵌套的中断

咬尾中断

晚到(的高优先级)异常

异常返回值

中断延迟

异常响应期间的faults

使用异常系统
使用中断

异常/中断服务程序

软件触发中断

使用SVC

SVC示范:用于输出函数

在C中使用SVC

异常服务例程的范例

posted @   登云上人间  阅读(113)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10亿数据,如何做迁移?
· 推荐几款开源且免费的 .NET MAUI 组件库
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 易语言 —— 开山篇
· Trae初体验
历史上的今天:
2021-07-12 STM32中断学习笔记
  1. 1 原来你也在这里 周笔畅
  2. 2 世间美好与你环环相扣 柏松
  3. 3 起风了 吴青峰
  4. 4 极恶都市 夏日入侵企划
  5. 5 パレード ヨルシカ
パレード - ヨルシカ
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

作词 : n-buna

作曲 : n-buna

身体の奥 喉の真下

身体の奥 喉の真下

心があるとするなら君はそこなんだろうから

ずっと前からわかっていたけど

ずっと前からわかっていたけど

歳取れば君の顔も忘れてしまうからさ

身体の奥 喉の中で 言葉が出来る瞬間を僕は知りたいから

このまま夜が明けたら

このまま夜が明けたら

乾かないように想い出を

乾かないように想い出を

失くさないようにこの歌を

忘れないで もうちょっとだけでいい

一人ぼっちのパレードを

ずっと前から思ってたけど

ずっと前から思ってたけど

君の指先の中にはたぶん神様が住んでいる

今日、昨日よりずっと前から、ずっとその昔の昔から。

わかるんだ

身体の奥 喉の真下

身体の奥 喉の真下

君の書く詩を ただ真似る日々を

忘れないように

忘れないように

君のいない今の温度を

乾かないような想い出で

乾かないような想い出で

失くせないでいたこの歌で

もう少しでいい もうちょっとだけでいい

一人ぼっちのパレードを

点击右上角即可分享
微信分享提示