[arm微控制器与嵌入式系统] 从CPU到MCU
CPU是计算机/微控制器的核心,进行算数/逻辑运算
MCU?
MicroController Unit 微控制器是一个完整的计算机系统,在单个芯片上包含了处理器、存储器和所有的外设IO模块。
MCU包含了什么?
- CPU
- Input/Output interface
- Peripherals
- RAM 用于数据存储
- ROM 用于程序存储, EPROM, EEPROM或 Flash Memory
MCU的特点
- 体积小
- 低成本
- 低功耗
- 高可靠性
- 大量型号和设计方案
ARM处理器的分类
从ARM v7之后,ARM处理器按照应用特征分类,分为以下三类:
- A系列 —— Application Processor —— 高性能多媒体<手机等>
- R系列 —— Real-time Controller —— 实时响应<无人机等>
- M系列 —— Micro-Controller —— 嵌入式
微控制器的内部结构
CPU
上图中右边就是之前概念CPU的实际表达ALU 运算逻辑单元。
运算逻辑单元完成逻辑和数学的运算
两个输入数据 —— A和B
一个指令 —— OP,要对A和B做什么运算
输出数据 —— Result和Flags(标志位)
怎么理解标志位
如果给ALU下面几种运算
A+B = C
如果这个ALU是一个4 bit的运算单元,则当计算加法时,可能会出现C大于15(0x1111),这时会出现溢出标志位用来表示计算结果是否溢出。
A>B ?
CPU在做比较的话,实际上是做了A-B的运算,而我们想要的结果实际上就是负数标志,同样也是在标志位中体现。
问题:ALU计算得到的结果要存在哪里呢? —— 寄存器
寄存器组
寄存器是由电路实现的保存数据的单元。
在CPU中,有一个寄存器就是用来专门保存ALU计算后的标志位,每条指令所能影响的状态位是不一样的,这类寄存器被称为程序状态寄存器(PSR寄存器),还有被称为CCR寄存器,
这个寄存器中到底要存哪些状态信息?
不同的芯片,对应的状态信息也有所区别,但是一般而言都要包括以下几个标志:
- Z 上一个运算得到了0的结果
- N 上一个运算得到了一个负数
- O 上一个运算溢出了
- C 上一个运算出现了进位
在CPU的设计当中,下图中这样的寄存器可以有若干个。
- 寄存器用于临时保存/获取操作数
- 任何CPU都包含了若干个通用/专用寄存器
- 寄存器的数目和位宽是衡量CPU的重要指标
CPU内部的寄存器个数有限,其实是无法满足程序的要求,因此出现了下图的结构
上图中的Data Memory不再是CPU的组成部分,对Memory的访问要比对寄存器的访问慢很多
地址与存储器的关系
如果要访问CPU外部的Data Memory,如何实现?
对于存储器,其结构如下:
上图中的0x0003这个地址存的数据就是0x44
类比一下,一定意义上来说,程序的存储也是这个概念。
指令集
堆栈
栈是一段连续的存储器空间
堆栈按照后入先出的工作方式
只能从/向堆栈的顶部加入或取出数据
按照这个逻辑,我们现在还缺少一个片外的存储器,用来给堆栈用。我们需要有一个类似指针的东西,指明从某个位置开始的存储器作为堆栈来使用。
堆栈空间和变量空间是使用同一端存储空间
- 变量空间从低地址向搞地质划分(例如C语言编程时声明的全局变量)
- 堆栈空间从高地址向低地址增长
这就带来一个新的问题:
存储器的空间是有限的,当某个时间点,堆栈达到一个冲突点的时候,出现了堆栈溢出。
堆?
堆是一个进程开启之后,系统分配给它的空间,一般这个空间是全局的,系统中所有动态分配的对象(比如指针)都是在这个空间上分配的。
堆里的数据是有数据结构的,其空间占用是不连续的。在没有OS的嵌入式系统中,通常不使用堆。
通常,我们把上图中红色框中的寄存器称为寄存器组,也可以称为编程模型。
中断
中断与轮询
轮询:
- 周期连续地检查外部事件是否发生
- 消耗大量CPU的处理事件
- 需要和其他功能代码结合
- 由于CPU需要处理其他事件,可能丢失关键事件
中断:
用硬件来判断是否发生外部事件并通知CPU
专用的中断服务程序来处理事件
中断是一个需要CPU立即处理的内部或外部事件
内部事件
- 定时器时间到
- AD变换结束
- …
外部事件 - 按键动作
- 发生外部通信
中断:
- 适用于处理响应要求非常高的事件
- 适用于处理持续时间非常短的事件
- 适用于低功耗的应用
- 程序设计复杂
中断允许/禁止
- 全局中断控制
时钟/复位
存储器
外设
ARM体系结构
32bit MCU Register File (ARM Cortex M)