嵌入式八股ARM篇

前言

ARM篇主要介绍一下寄存器和中断机制,至于汇编这一块...还请大家感兴趣自行学习

1.寄存器

  1. R0 - R3 R4 - R11 寄存器
    R0 - R3一般用作函数传参
    R4 - R11用来保存程序运算的中间结果或函数的局部变量
    在函数调用过程中
  • 注意在发生异常的时候 cortex-M0架构会自动将R0-R3压入栈中, 这也是为什么我们的PendSV只用压入R4 - R11
  1. R12 没啥用

  2. R13寄存器

    R13寄存器又叫做堆栈指针寄存器SP 总是指向当前正在运行的函数的栈帧

    • MSP 和 PSP

      对于 cortex-M3架构 存在两个SP 指针 一个 MSP 一个 PSP

      • PSP只能被用作线程模式 MSP可以在 线程/handler模式运行
        具体的等后面模式做详解
    • FP 与 SP

      前面将函数调用过程的时候讲到了 栈帧是靠这俩寄存器FP和SP维护的 可是为啥没见FP寄存器呢? FP似乎通常是R11寄存器 但不绝对

  3. R14寄存器---LR寄存器

    • 用来保存保存上一级函数调用者的返回地址,这样当我们函数调用返回的时候就知道从哪里接着运行了
    • 当异常发生时,LR中保存的值等于异常发生时PC的值减4(或者减2),因此在各种异常模式下可以根据LR的值返回到异常发生前的相应位置继续执行
    • 当中断发生的时候,LR寄存器的值会被设定为"EXC_RETURN"
    • BL function
      当我们通过这样的指令跳转的时候 就会更新我们的LR寄存器的值了
    • BX LR
      这个我们在RTOS的PendSV函数的最后会看到 BX LR 指令 这是因为PendSV结束调用时还处于特权模式(LR = EXC_RETURN),而我们实际上是想返回线程模式的 所以用BX LR 而不是 MOV PC, LR
  4. R15寄存器---PC寄存器

    每取一次指令,PC的值会自动 + 8

  5. 各种状态寄存器

    不必关心

  6. ARM的三级流水线

    一条指令的执行分为三步:取址, 译码 和 执行 每一条都需要一个时钟周期 所以一条指令需要三个时钟周期。 那如果我们只有第一条指令执行完才执行第二条 就意味着取址单元会有两个时钟周期啥也不干

    所以引入流水线就好了

    • 为什么是PC = PC + 8 呢
      这么理解
      "正在取值的指令" = "正在执行的指令" + 8 *
      就对了,反正这也是给你看的不是给机器看的...
      可以看到对于第一条指令add r0,r1,#5真正执行的时候,我们取的是第三条指令cmp r2,#3的值
  7. 顺序执行与乱序执行

    因为我们的指令很有可能下个指令依赖上个指令的结果,那此时三级流水线就出问题了

    比如上个指令的结果还没放回内存了 这边已经从内存开始取数据了

    此时就得加入空指令 暂停流水线了--效率低下

    所以就会有乱序执行--有专门逻辑电路进行分析做这个事

2.特权与模式

  1. cortex-M3的模式
    两种模式 -- handler模式与线程模式
    两种特权 -- 用户级和特权级
  2. ARM的七种模式
    • 用户模式(User):这是唯一的非特权模式,
    • 快速中断模式(FIQ, Fast Interrupt Request):
    • 标准中断模式(IRQ, Interrupt Request)
    • 管理模式(SVC, Supervisor)。
    • 中止模式(Abort)
    • 未定义模式(Undefined)
    • 系统模式(System)

用户级和特权级是针对访问权限 :特权级访问寄存器不受限,用户级不行

模式是针对运行状态 : 触发异常了就得进入 handler模式 普通状态就是线程模式

所以不能在用户级去操作handler模式,但是线程模式下特权级还是用户级都无所谓啦

  1. 复位后的状态
    复位后,处理器默认进入线程模式(MSP),特权极访问
    可以通过修改CTRL寄存器回到线程模式(PSP指针)
    但是线程模式可就不能修改CTRL寄存器了---那想回去怎么办?触发异常再异常中修该

3.存储区映射

对于32位的处理器 地址空间是4个G 这4G对于ARM来说是这么定义的

异常

对于所有的异常都进行了编号 前15种是系统异常 后面的都是外部中断

我们可以看到对于后面几个异常是可编程的,这个在RTOS的任务切换很重要,我们一般会把PendSV这个异常设定为最低优先级(0xffffffff)---为了在对所有中断都响应后在切换任务

  • 抢占优先级和响应优先级

    高抢占优先级可以打断低抢占优先级

    但是同抢占优先级下,高响应优先级打断不了低的响应优先级

  • 中断向量表---处理中断的关键

    这个是在starup.s中定义的 一般我们也不会有重新定义新的中断的需求

  • 对中断的响应

    正常来说需要我们在中断服务程序清除对应的标志位

    如果不清除会咋样---那就反复进入该中断处理程序操作

    如果极短时间多次请求--一般只会响应一次,因为中断就悬起了一次

    假如在中断服务函数执行过程中,又触发了一次相同的中断--就会再执行一次

  • NVIC中断控制器

    • 中断的悬起与解悬
    • 中断的优先级控制
    • 对中断响应的暂时屏蔽

中断

  • msp与psp指针
    MSP:复位后缺省使用的堆栈指针,用于操作系统内核以及异常处理例程(包括中断服务例程)
    PSP:由用户的应用程序代码使用。
    两个堆栈指针,同一时刻只能用一个。
    作用:提升程序健壮性。一定程度上保证应用的数据(栈)空间不会溢出到操作系统数据(栈)空间

  • 中断发生后做了什么
    当一个中断发生的时候 我们的内核到底做了什么

    • 寄存器入栈--保存现场

    • 地址总线从向量表查询中断向量

    • 更新寄存器--此时就进入handler模式了同时使用的也是MSP指针了

    • 跳转执行中断服务程序

    • 中断返回--包括把之前保存的寄存器的值自动弹出来(恢复现场)

  • 中断的递归调用
    不用我等操心 但是需要我们注意的是就是给栈提供一个合适的大小

  • 中断与异常的区别
    中断------外部事件引起,正在运行的程序所不期望的--异步的
    异常------内部执行指令引起--同步的

相关推荐
点纭4 分钟前
C语言 第四章 数组(3)
c语言·c#
promising-w1 小时前
硬件工程师入门教程(四)
嵌入式硬件
坏柠1 小时前
STM32与HAL库开发实战:深入探索ESP8266的多种工作模式
stm32·单片机·嵌入式硬件
电鱼智能的电小鱼2 小时前
SAIL-RK3576核心板应用方案——无人机视觉定位与地面无人设备通信控制方案
linux·嵌入式硬件·无人机·边缘计算
Amy.com2 小时前
嵌入式2-按键
stm32·单片机·嵌入式硬件
刘阿去3 小时前
tcc编译器教程7 为编译gmake编写Makefile文件
c语言
printf_013 小时前
HAL库STM32常用外设—— CAN通信(一)
stm32·单片机·嵌入式硬件
小麦嵌入式3 小时前
Linux驱动开发实战(五):Qt应用程序点RGB灯(保姆级快速入门!)
linux·驱动开发·stm32·嵌入式硬件·mcu·qt·ubuntu
小禾苗_3 小时前
32单片机——BEEP
单片机·嵌入式硬件
钡铼技术物联网关4 小时前
支持Linux、鸿蒙的工业AIOT智能终端在钢铁厂的应用
linux·arm开发·边缘计算