当前课程知识点:智能车制作:嵌入式系统 > 第三章 MCU基础 > 3.3.1 ARM的体系结构 > Video
各位同学大家好
我是清华大学工程物理系的曾鸣老师
欢迎大家回到我们
ARM控制器与嵌入式系统的慕课课程
继续学习我们第三章基础知识的学习
那么在前面几个单元
我们逐步的进入了一个
真正的微控制器片上寄存器系统
特别是在前几个单元
深入一个CPU
看真正的我们汇编的指令
在这个CPU里是怎么运行起来的
我们学习了它的结构
它的寄存器组
它的编程模型
然后看这些指令
在这样一个结构里究竟怎么运行
那么上个单元
我们做了个小小的头脑体操
看了看一个十六位的MCU系统上
我们这个程序
究竟是怎么一步一步跑起来的
让大家觉得汇编程序是不是不再神秘
那么这个单元我们来进入32位的系统
特别是一点一点的来看看
我们要学习的对象
ARM Cortex M 的32位微处理器
它的结构究竟是什么样的有什么特点
当然最后我们还是会做一个头脑体操
看看ARM的指令汇编指令汇编程序
是怎么运行的
那么我们前面在第二章
已经学习过32位的系统
并不仅限于ARM一种体系结构
非常著名的一脉相承
从IBM的合作开始的
PowerPC 乃至从68k内核
一路继承下来的ColdFire
还有我们现在要学习的ARM
如果我们看看它的内部结构呢
也会发现各有特点
比如ColdFire的结构
就是由八个数据寄存器
和八个地址寄存器
每个都是三十二位
来组成了一个内部的寄存器组
再加上被复用为堆栈指针寄存器
PC指针寄存器和条件状态寄存器这样一些
特殊的寄存器构成了整个的编程模型
看起来比较简单
那么PowerPC的内核
就比它要复杂的多
我在这里不展开讲
只是给大家感受一下
当它在用户态的时候
它的内部寄存器
有这么一张图可以表示
而当它在特权态的时候
已经密密麻麻
多得大家一眼可能看不清楚了
那么我们学习的ARM是什么样的呢
在最初的学习
我们已经知道我们所学习的对象ARM
在v7核开始分成了
ARM Cortex A R和M
三个系列分别对应高端的多媒体计算
中间的实时系统和低端的微控制器
而微控制器所对应的
我们所学习的这个领域
M的核它保持了高度兼容性
我们后面会讲
不管从M0 M1乃至到M3 M4
和现在的M7等等
不同档次的ARM Cortex核
它内部的编程模型
保持了高度的一致和兼容
从寄存器上来看在数据和地址的
通用寄存器角度 ARM Cortex M的内核
不管是M几
它基本上都是这样一个寄存器组
从R0到R15
一共十六个32比特位宽的寄存器
构成了它的内部寄存器组
而这些寄存器当中从R0到R12
我们一般就当作通用的用途
而在芯片设计的时候R13 R14 R15
使用了类似的结构和指令来控制
但是它已经指定为了特定的用途
比方说R13规定为了
我们前面所反复讲到的
堆栈指针寄存器
它总是保存一个地址
你可以把它理解为
C语言类似一个指针对吧
那这个地址
总是指向我们堆栈所使用的内存地址
那R15呢
也就是我们前面
讲过很多次的程序计数器
也就是PC指针寄存器
它同样也保存一个地址
就是我们的程序运行到了第几条指令的
那个指令的地址
所以它的变化
就是我们前面反复讲
一条条指令运行的那个地址的更新
那么R14在前面没有讲过
但是隐隐约约也涉及到了
它是一个Link Register
它总是在函数调用子程序跳转的时候
自动保存一个函数
和子程序的返回地址
那有同学说
老师你不是讲这个返回地址
总是保存在堆栈里头吗
是的 但是我同样也讲过
最早的CPU
是用CPU内部的寄存器来保存返回地址的
后来因为函数的嵌套调用的层次
需要动态的变化
才开始发明和使用堆栈
而有了Link Register这样一种机制
使我们当发生单次调用的时候
能够使程序的跳转和调用变快很多
而如果发生嵌套有更多的地址
要保存的时候仍然还是会使用堆栈
那么这就是
R0到R15十六个CPU片内的
寄存器组的编程模型的一个概况
那么除了这些以外
我们当然说过CPU片内
还会有一些其它的寄存器
比如在讲通用计算机CPU模型的时候
我们会说有一个状态寄存器来保存
CPU内部的运算的得0
溢出等等这些状态对吧
那实际上我们对于CPU
还会要有些设置的功能
在前面讲过的8位16位的MCU里
往往都把它们合并在一个寄存器里
包括开关中断
包括这个运算状态
而在ARM的体结构里呢
它把它总体归纳成了这五个寄存器
其中的最上面的x这个PSR寄存器
总体来讲是保存各种CPU的设置状态的
便于我们读写访问待会会展开讲
那么第二个呢
PRIMASK呢是主要设置中断的开和关的
那么这是一个中断开关
给了一个独立的寄存器
那么最下面有Control register
它只有1到2个比特可以用
是设置这个CPU的实际的工作模式和状态的
那么中间用灰色遮挡掉的两个寄存器
分别控制不可屏蔽中断的开和关
以及按优先级关闭中断的功能
那么这五个寄存器在整个
ARM Cortex M系列里头是都一致和兼容的
唯一的区别就是在M3和M4的内核上
被我挡掉的这两个寄存器是有并且可以用的
而在我们这门课程所学习的M0+
乃至比它更低的M0的处理器上
这两个寄存器没有
所以我们所涉及的对象
只是白色的这三个寄存器
那么这三个寄存器在别的CPU上
就是刚才0812里头
就是一个寄存器就集成在里头不同的比特
而在ARM里为了操作的方便
把它分离出来讲解
但是实际上并没有变得复杂
那我们来看一下
程序状态寄存器
也就是xPSR这个寄存器
如我们所说它是一个32位的寄存器
那么xPSR这个32位的寄存器里头
每一个比特 都有它自己唯一的功能
便于我们对它进行访问获得CPU的一些状态
那么为了编程方便
这个寄存器非常有意思
它还有三个别名
我们用这三个别名
来加以访问的时候呢
只关注和读取其中特定的字段
来实现单一的功能
比如我们用APSR
这个名字来访问这个寄存器的时候
读到的主要是高四位的值
而后面都是属于reserved的
那么这高四位的值一点都不神奇
它存的就是是否有得0 是否有负数
是否有借位进位和是否有溢出
这样一些基本的指令运算产生的状态位
也就与我们在这一章的一个单元所讲的
那些位是完全一致的
那么这些位
随着每条指令的运行
会被CPU自动的更新
而又被后续的指令
可能拿来使用
作为程序判断和跳转的依据
而如果我们使用IPSR来访问
也就是这张图中间这一行
那么它的高位都是reserved
我们主要读到的是
最后面的几位
这几位呢是保留了我们
发生中断的时候发生异常的时候
那个中断的中断号
这我们在后面会讲中断
然后最后一个这个EPSR呢
主要就是中间有个T这一位
来记录我们
是否发生了异常和是否发生了中断
所以说这样一个32位寄存器好像很复杂
但是大家不要怕
其实有用的
还是原来那四位
那四位就进入了我们各种运算的状态
作为后面指令跳转的依据
这是它的体系结构
那么另外一个片内
会涉及到的寄存器呢
就是我们的优先级的
这个控制寄存器或者叫优先级MASK寄存器
但是在ARM Cortex M这个CPU上面
这个名称被得到高度简化
我们在这里使用的只是这个最低的这一位
这一位不是根据优先级来控制中断
而是控制了所有中断的使能或者关闭
所以大家在下一个单元
学习中断的时候会记住
在这里有这么一个位控制中断的总开关
这一个比特我们可以对它设置0或者1
那么最后还有一个寄存器呢
是CPU的一些状态的寄存器
那么CPU的状态的寄存器呢
有两个比特可以使用
我标成阴影的这个比特控制这个CPU
是工作在用户态还是特权态
那么在M0和M0+的CPU上这个态
是不加以区分的
就是CPU不支持这两种状态
所以这一位就是Reserved
而如果大家使用的是ARM Cortex M3
或者M4的CPU 这一位用来区分
CPU工作在用户态和特权态是可以设置的
那么BIT1也就第二个比特
它的功能是规定了
我们所使用的堆栈是主堆栈
还是进程堆栈
好这件事情可能在现在初学的同学
会觉得有点绕
那么我简单的说
在刚才讲通用寄存器的时候
观察细致的同学
如果没观察你可以倒回去看一下
会发现R0到R15那十六个寄存器当中
R13画了两遍
这是CPU设计上的一个技巧
也就是用来作为堆栈指针寄存器的R13
其实有两个
那么当我们用的是
我们自己写的程序的时候
我们完全感觉不到这些事情存在
它就是堆栈指针寄存器
如果有朝一日大家要在这样的CPU上
跑一个实时操作系统的时候
像这样的CPU设计
给大家留了一个非常好的功能
就是堆栈指针寄存器可以有两个
分别指向内存的两个不同的区域
所以这两个区域
一个给我们的操作系统的内核来使用
一个区域这个堆栈给我们的用户程序
就是任务来使用 这样当任务跑飞的时候
对堆栈使用出现问题的时候
不会使整个操作系统崩溃
这个比特就是设置当前程序
是使用主堆栈还是使用辅堆栈
当调用堆栈的时候
是根据主的那个R13
还是根据那个辅的R13
来寻找内存的地址
我不知道这么讲大家明白了没有
但是它的原理
其实非常的简单
也许大家日后倒过来再看这段会理解的更好
那么这样一系列的寄存器就构成了我们一个
ARM Cortex M的CPU的编程模型
那么这种编程模型
对于整个M0到M4的整个体系结构
是高度兼容的
所以呢
大家在理解的时候学一个
其它的就非常容易学习
这就是学习ARM的好处
那么除了这个寄存器的编程模型以外
如果我们这门课程是深入的学习
ARM Cortex M 那么还有几件事情
是我们不得不讲的
另外一件事情
就是CPU的工作状态
对ARM Cortex M0
M0+工作状态这张图上非常简单
就只是左侧这一列
也就是说它工作在跑普通的程序
我们称为是这个程序的
进程模式 Thread模式
那么说得更通俗一点
就是大家有用C语言编程
在跑大家的MAIN函数和MAIN函数
调用这些函数的时候
我们认为是在Thread模式
那么还有一个特殊状态是什么呢
就Handle模式句柄模式
它对应的是什么呢
对应的是下一段我们要讲的
当它发生中断的时候去响应中断的那个状态
所以M0和M0+的CPU MCU
它只在这两个状态里切换
进中断出中断
而如果大家使用的是M3和M4的MCU
为了考虑实时操作系统的使用
考虑到实时操作系统内核和用户程序的区分
它还在横着的这张表里出现了
用户态和特权来的区分
所以这样三种状态之间的加以切换
当从特权态进入用户态
用户态如果要返回系统内核 返回特权态
需要通过一次特殊的中断调用才能实现
所以有条件的同学在日后可以加以学习
但是无论如何大家理解M0 M1的MCU
是M3 M4 MCU的一个子集
并且高度兼容
那么这个概念 除了编程的模型
除了用户态再展开讲
回到我们第二章所讲过的指令集也是如此
大家回过头看这张图
感觉就会更加清晰
从指令集上来讲
类似的内部的编程模型寄存器
只是程序高度兼容的一个部分
还有一个重要的部分就是它们不同的CPU
所使用的指令集是否一样
换言之CPU拿到的0和1的序列
所代表的含义是否兼容
那么我们会看到
重新看这张图的时候会发现绿色的区域
是ARM Cortex M0 M1的CPU的指令集
也就是是那个绿色的这个五十多条指令
这当中包含了
绝大多数的十六位的Thumb指令只缺三条
然后和一部分的32位的Thumb-2指令
那么蓝色的区域
是在它基础上加以扩充的
ARM Cortex M3的指令集
所以它兼容支持所有ARM Cortex M0 M1
所拥有的指令
自己另外支持了额外的Thumb-2的32位指令
所以我们可以想象学习ARM的时候
我们学习一个子集
学习一个入门的CPU
我们能够非常容易学懂
而我们学习的所有的指令
所写的程序在更高级的CPU上
是高度兼并且可运行的
紫色的区域呢
是M4的内核的指令集
粉色的区域是M4f
增加的浮点运算的指令集
所以我们可以说
ARM的指令集体系结构
就是这么一步一步扩充的
而如果我们学习更高端的ARM
那么它可以不仅仅是
这里所列举的16位32位
混合的Thumb-2指令集
它还有纯32位的ARM指令集
可以进行两种状态之间的切换
这样扩展到R系列和A系列
这就是ARM的体系结构和学习的差异
如果我们多花一点点
来看我们所学习的这个
ARM Cortex M0+在这门课里这个CPU
这个MCU所处的位置就是这张表格
从最左边最简单的M0核 到M0+核
到最右边的M3 M4和 M SEVEN就是M7这样的核
那么它们之间所支持的指令集
就像这张表格所绘
分别对于16比特32比特
乃至重加运算 DSP运算
浮点运算的指令集的支持程度
是略有差异的
而这样一种差异
保证了它的向下兼容
根据不同的应用需要
可以进行不同的开发
另外一方面呢
作为初学者
我们学习一个相对简单
能够充分掌握的CPU 你的知识
可以非常好的延展到其它的系列上
因为它们在体系结构上是高度一致的
那么这些东西讲完也就是我们这门课
所要学习的
ARM Cortex M核的一些基本的概念
当然ARM Cortex M核
还有很多很多它的特殊性和概念
我们在后面的学习当中会更加详细的讲
在这个单元里讲过多可能大家会犯晕
那么我们仅就理解的这些寄存器和它的指令
在下个单元我们就来做一个头脑体操
看一看在这样一个ARM的核上
汇编程序怎么运行
看完了
大家就会对这个核的理解相信又上一个层次
-1.1 课程概览
--Video
-1.2 进入嵌入式系统的世界
--Video
-1.3 如何学好嵌入式系统
--Video
-2.1 计算机的基本概念、发展历史
--Video
-2.2 从晶体管到CPU
--Video
-2.3 概念CPU、微控制器MCU和嵌入式系统
--Video
-2.4 八卦计算机史
--Video
-2.5 不同领域、不同系列的嵌入式系统
--Video
-2.6 ARM历史与MKL25Z128 MCU
--Video
-3.1 CPU的基本结构和运行机制
--Video
-3.2.1 堆栈的概念
--Video
-3.2.2 堆栈的概念-头脑体操
--Video
-3.3.1 ARM的体系结构
--Video
-3.3.2 ARM的体系结构-头脑体操
--Video
-3.4 中断的概念和机制
--Video
-3.5 中断子程的概念和编程
--Video
-3.6 复位、时钟、存储器和总线
--Video
-3.7 小结:MCU的总体结构和程序运行机制
--Video
-4.1 第一种外设:IO
--Video
-4.2 IO外设的编程实操-点亮LED
--Video
-4.3 IO外设的进阶知识
--Video
-4.4 嵌入式开发的基本概念与工具链
--Video
-4.5 嵌入式开发的进阶知识
--Video
-4.6 嵌入式开发中的C语言(上)
--Video
-4.7 嵌入式开发中的C语言(下)
--Video
-E0.1 实验零 开发板的初步认识与工具链的安装
--Video
-E0.2 实验零 体验一个例程的编译与下载
--Video
-E0.3 实验零 编写第一个程序:点亮核心板LED
--Video
-E1 实验一 点灯秘籍
--Video
-5 智能车视角的嵌入式设计
--Video