【cortex-m3/m4/m7常见死机、跑飞、异常、hardfault等查找方法】

死机是所有软件从业者无法回避的坑,而死机问题导致的原因千奇百怪,对于可以稳定复现现场的问题,还是比较好处理的,最可怕的情形是你怎么也复现不了,但是在客户那偶发。在此对笔者解决过的死机问题做个分享,若有谬误,请指正。

总的思路为根据堆栈和寄存器,定位到出现异常的语句,然后从逻辑上分析导致其异常可能的原因。

  • 基础简介

在查找此类问题时,通用寄存器,堆栈,简单的汇编指令是需要必备的基础知识,以我们最常用的M3/M4内核做个简单介绍。具体知识可以自行学习cortex-M3权威手册等资料。

寄存器简介

       (cortex-M3权威手册第三章)

CM3 拥有通用寄存器 R0R15 以及一些特殊功能寄存器。

  • 通用目的寄存器 R0-R7
    R0R7 也被称为低组寄存器。所有指令都能访问它们。它们的字长全是 32 位,复位后
    的初始值是不可预料的。
  • 通用目的寄存器 R8-R12

R8‐R12 也被称为高组寄存器。这是因为只有很少的 16 位 Thumb 指令能访问它们, 32

位的指令则不受限制。它们也是 32 位字长,且复位后的初始值是不可预料的。

  • 堆栈指针 R13

R13 是堆栈指针。在 CM3 处理器内核中共有两个堆栈指针:

  1. 主堆栈指针(MSP),或写作 SP_main。这是缺省的堆栈指针,它由内核、异常服务例程以及所有需要特权访问的应用程序代码来使用。
  2. 进程堆栈指针(PSP),或写作 SP_process。用于常规的应用程序代码(不处于异常服

用例程中时)。

堆栈指针用于访问堆栈,并且 PUSH 指令和 POP 指令默认使用 SP。寄存器的 PUSH 和 POP 操作永远都是 4 字节对齐的

  • 连接寄存器 R14

常写做LR,用于在调用子程序时存储返回地址。

  • 程序计数器 R15

常写做PC,因为 CM3 内部使用了指令流水线,读 PC 时返回的值是当前指令的地址+4。

  • 程序状态寄存器(PSRs 或曰 PSR)

程序状态寄存器在其内部又被分为三个子状态寄存器:

  1. 应用程序 PSR(APSR)
  2. 中断号 PSR(IPSR)
  3. 执行 PSR(EPSR)

通过 MRS/MSR 指令,这 3 个 PSRs 即可以单独访问,也可以组合访问(2 个组合, 3 个组合都可以)。当使用三合一的方式访问时,应使用名字“xPSR”或者“PSR”。

  • 屏蔽寄存器
  1. PRIMASK 这是个只有 1 个位的寄存器。当它置 1 时, 就关掉所有可屏蔽的异常,只剩下 NMI和硬 fault 可以响应。它的缺省值是 0,表示没有关中断。
  2. FAULTMASK 这是个只有 1 个位的寄存器。当它置 1 时,只有 NMI 才能响应,所有其它的异常,包括中断和 fault,通通闭嘴。它的缺省值也是 0,表示没有关异常。
  3. BASEPRI 这个寄存器最多有 9 位(由表达优先级的位数决定)。它定义了被屏蔽优先级的阈值。当它被设成某个值后,所有优先级号大于等于此值的中断都被关(优先级号越大,优先级越低)。但若被设成 0,则不关闭任何中断, 0 也是缺省值。
  • 控制寄存器(CONTROL)

控制寄存器用于定义特权级别,还用于选择当前使用哪个堆栈指针。

  1. CONTROL[1] 堆栈指针选择

0=选择主堆栈指针 MSP(复位后缺省值)

1=选择进程堆栈指针 PSP

在线程或基础级(没有在响应异常——译注),可以使用 PSP。在 handler 模式下,只允许使用 MSP,所以此时不得往该位写 1。

  1. CONTROL[0] 0=特权级的线程模式

1=用户级的线程模式

Handler 模式永远都是特权级的。

栈内存操作

       在 Cortex‐M3 中,除了可以使用 PUSH 和 POP 指令来处理堆栈外,内核还会在异常处理

的始末自动地执行 PUSH 与 POP 操作。

笼统地讲,堆栈操作就是对内存的读写操作,但是其地址由 SP 给出。寄存器的数据通

过 PUSH 操作存入堆栈,以后用 POP 操作从堆栈中取回。

       Cortex‐M3 使用的是“向下生长的满栈”模型。堆栈指针 SP 指向最后一个被压入堆栈的 32

位数值。在下一次压栈时, SP 先自减 4,再存入新的数值。

POP 操作刚好相反:先从 SP 指针处读出上一次被压入的值,再把 SP 指针自增 4。

虽然 POP 后被压入的数值还保存在栈中,但它已经无效了,因为为下次的 PUSH 将覆盖它的值。

异常与中断

(cortex-M3权威手册第七章)

所有能打断正常执行流的事件都称为异常。

Cortex‐M3 在内核水平上搭载了一个异常响应系统, 支持为数众多的系统异常和外部中断。其中,编号为 1-15 的对应系统异常,大于等于 16 的则全是外部中断。除了个别异常的优先级被定死外, 其它异常的优先级都是可编程的。

下表列出了 Cortex‐M3 可以支持的所有异常。有一定数量的系统异常是用于 fault 处理的,它们可以由多种错误条件引发。 NVIC 还提供了一些 fault 状态寄存器,以便于 fault 服务例程找出导致异常的具体原因。

  • 异常类型:

  • 优先级

优先级对于异常来说很关键的,它会影响一个异常是否能被响应,以及何时可以响应。优先级的数值越小,则优先级越高。 CM3 支持中断嵌套,使得高优先级异常会抢占(preempt)低优先

  • 27
    点赞
  • 127
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Cortex-M4期末考试是一个重要的学术评估活动,目的是测试学生对Cortex-M4微控制器体系结构和编程的理解程度。 这个考试将测试学生的理论知识和实际应用能力,包括以下方面: 首先,学生需要掌握Cortex-M4的基本特性和体系结构。他们应该了解Cortex-M4的功能、寄存器、指令集和存储器管理单元。在考试中,他们可能会遇到有关这些方面的选择题或简答题。 其次,学生应该能够使用Cortex-M4的开发工具进行编程。他们需要掌握Cortex-M4的汇编语言和C语言编程,了解如何编写基本的程序、访问寄存器和控制外设。在考试中,他们可能会被要求编写简单的代码片段或回答有关编程问题的问答题。 此外,学生还需要了解中断和异常处理机制。他们应该知道如何配置中断控制器、编写中断处理程序并处理异常情况。在考试中,他们可能会被要求解释中断和异常的工作原理或解决与中断相关的问题。 最后,学生还应该了解Cortex-M4的内存保护机制和系统级调试接口。他们应该知道如何设置存储器保护单元、使用断点和观察点,并调试程序。在考试中,他们可能会被要求解释这些概念或回答与调试相关的问题。 总之,Cortex-M4期末考试旨在评估学生对Cortex-M4微控制器的全面理解和应用能力。期末考试的成绩将反映学生的学术水平,并帮助他们进一步提高对Cortex-M4的应用能力。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值