嵌入式与微机原理总复习复习大纲1. 概述1.1. 计算机的发展简史1.1.1. 计算机的诞生1.1.2. 现代计算机发展历程1.1.3. 计算机的类型1.2. 计算机系统的组成1.2.1. 计算机硬件1.2.1.1. 存储器1.2.1.2. 运算器1.2.1.3. 控制器1.2.1.4. 输入设备1.2.1.5. 输入设备1.2.1.6. 适配器1.2.1.7. 总线1.2.2. 计算机软件1.2.2.1. 计算机软件分类1.2.2.2. 计算机软件的发展1.3. 计算机中数的表示方法1.3.1. 进位计数制1.3.2. 有符号数的原码、反码和补码表示1.3.3. 定点数和浮点数1.3.4. 其他信息编码1.4. 嵌入式系统简介1.4.1. 嵌入式系统的基本概念1.4.2. 嵌入式系统的硬件1.4.3. 嵌入式系统软件1.4.4. 嵌入式系统的发展概况1.4.5. 典型嵌入式处理器简介2. 计算机系统的基本结构与工作原理2.1. 计算机系统的基本结构与组成2.1.1. 计算机的层次模型2.1.2. 基于冯诺依曼架构的模型机系统结构2.2. 模型机存储器子系统2.2.1. 存储器的组织和地址2.2.2. 字的对齐——对准存放2.2.3. 小端格式和大端格式2.2.4. 存储器操作2.2.5. 存储器的分级2.3. 模型机CPU子系统2.3.1. 运算器2.4.2. 控制器2.4.3. 寄存器阵列2.4.4. 地址与数据缓冲器2.4.5. 数据通道2.4. 模型机指令集和指令执行过程2.4.1. 模型机指令集2.4.2. 指令周期2.4.3. 模型机指令执行流程2.5. 计算机体系结构的改进2.5.1. CISC和RISC2.5.1. 流水线技术2.5.3. 超标量处理器和多发射技术2.5.4. 超线程处理器2.5.5. 多处理器计算机和多计算机系统2.5.6. 多核处理器2.6. Intel x86典型微处理器简介2.6.1. Intel 8086处理器2.6.2. Intel Pentium处理器2.7. ARM嵌入式处理器简介2.7.1. ARM体系结构、ARM处理器和ARM内核2.7.2. ARM处理器的特点2.7.3. 典型ARM内核的基本结构2.8. 计算机性能评测2.8.1. 定性描述指标2.8.2. 定量指标描述3. 存储器系统3.1. 概述3.1.1. 存储器的类型及特点3.1.1.1. 半导体存储器3.1.1.2. 磁介质存储器3.1.1.3. 光存储器3.1.2. 微机系统的存储体系架构3.1.3. 辅助存储器主要接口标准3.2. 半导体存储芯片的基本结构和性能指标3.2.1. 随机存取存储器RAM3.2.2. 只读存储器ROM3.2.3. 存储芯片的性能指标3.3. 内存条性能的改进3.3.1. 内存条的组成3.3.2. 内存条的演变3.4. 存储系统的层次架构3.4.1. 存储系统的分层管理3.4.2. 虚拟存储器与地址映射3.5. 高速缓冲存储器Cache3.5.1. 高速缓冲存储器Cache的原理3.5.2. 高速缓冲存储器Cache的基本结构3.5.3. 地址映射与转换3.5.4. Cache更新与替换策略3.5.5. 影响Cache性能的因素3.6. 存储器系统设计3.6.1. 主存储器系统设计技术3.6.2. 存储器系统扩展方式3.6.3. 嵌入式存储器系统设计4. 总线和接口4.1. 总线技术4.1.1. 总线技术概述4.1.1.1. 总线的概念4.1.1.2. 总线的分类4.1.1.3. 总线的结构4.1.2. 总线仲裁4.1.2.1. 集中式仲裁4.1.2.2. 分布式仲裁4.1.3. 总线操作与时序4.1.3.1. 同步总线时序4.1.3.2. 异步总线时序4.1.3.3. 半同步总线时序4.1.3.4. 周期分裂式时序4.2. 片内总线AMBA4.2.1. AMBA总线概述4.2.2. AHB总线4.2.2.1. AHB系统的构成4.2.2.2. AHB信号定义4.2.2.3. AHB的数据传输过程及“流水线”4.2.2.4. AHB的突发传输4.2.2.5. AHB的译码4.2.2.6. AHB的仲裁4.2.2.7. AHB主机接口及时序参数4.2.2.8. AHB从机接口及流水线分离4.2.3. AXI总线4.3. 系统总线/外部总线4.3.1. PCI4.3.2. PCI Express4.3.3. USB4.3.4. 典型的计算机总线系统4.4. 输入/输出接口4.4.1. 输入/输出接口概述4.4.1.1. I/O接口的功能4.4.1.2. I/O接口的分类4.4.1.3. I/O接口规范的常规内容4.4.1.4. I/O接口的结构4.4.1.5. I/O端口编址4.4.2. 输入/输出接口的数据传送方式4.4.2.1. 无条件传送方式4.4.2.2. 查询传送方式4.4.2.3. 中断传送方式4.4.2.4. 直接存储器访问(DMA)方式4.4.3. 并行接口4.4.3.1. 无握手信号的并行接口4.4.3.2. 带握手信号的并行接口4.4.3.3. 可编程并行接口(GPIO)4.4.4. 串行接口4.4.4.1. 串行接口概述4.4.4.2. 异步串行接口4.4.4.3. I2C接口及总线4.4.4.4. SPI接口及总线5. ARM处理器体系结构和编程模型5.1. ARM体系结构与ARM处理器概述5.1.1. 指令集体系结构与微架构5.1.2. ARM处理器体系结构简介5.1.3. ARM处理器主要产品系列简介5.1.3.1. ARM处理器的特点5.1.3.2. ARM处理器相关产品的层次关系5.1.3.3. ARM处理器产品命名规则5.1.3.4. ARM7系列5.1.3.5. ARM9系列5.1.3.6. ARM11系列5.1.3.7. Cortex-A5.1.3.8. Cortex-R5.1.3.9. Cortex-M5.2. Cortex-M3/M4处理器结构5.2.1. Cortex-M3/M4处理器概述及指令集架构5.2.1.1. Cortex-M3/M4主要特性5.2.1.2. Cortex-M3/M4所支持的指令集5.2.2. Cortex-M3/M4处理器结构5.2.2.1. 内核5.2.2.2. 处理器5.2.2.3. 处理器系统5.2.3. 存储器管理5.2.3.1. 存储器管理特性5.2.3.2. 存储器映射5.2.4. 总线系统5.2.4.1. 总线系统结构5.2.4.2. 各类总线的连接对象5.2.5. 异常与中断处理5.2.5.1. 嵌套向量中断控制器NVIC5.2.5.2. 中断向量表5.2.5.3. 系统节拍定时器SysTick5.3. Cortex-M3/M4的编程模型5.3.1. 操作状态与操作模式5.3.1.1. 操作状态5.3.1.2. 操作模式和特权等级5.3.2. 常规寄存器5.3.2.1. 通用寄存器:R0~R125.3.2.2. 栈指针:R135.3.2.3. 链接寄存器:R145.3.2.4. 程序计数器:R155.3.3. 特殊寄存器5.3.3.1. 程序状态寄存器5.3.3.2. 三个中断屏蔽寄存器5.3.3.3. CONTROL寄存器5.3.3.4. 系统控制块SCB5.3.4. 堆栈结构5.3.4.1. 堆栈的作用和堆栈类型5.3.4.2. Cortex-M处理器的堆栈模型5.3.4.3. Cortex-M3/M4处理器中的双堆栈5.4. Cortex-M处理器存储系统5.4.1. 存储器映射5.4.2. 连接存储器和外设5.4.3. 存储器的端模式5.4.4. 非对齐数据的访问5.4.5. 位段操作5.4.5.1. 位段与位段别名5.4.5.2. 位段操作的优点5.4.5.3. C程序实现位段操作5.4.6. 存储器访问权限5.4.7. 存储器访问属性5.4.8. 排他访问5.4.9. 存储器屏障5.4.10. MCU中的存储器系统5.5. Cortex-M处理器的异常处理5.5.1. Cortex-M异常管理模型5.5.1.1. 异常类型5.5.1.2. 异常状态5.5.1.3. 异常处理程序5.5.1.4. 异常向量表5.5.1.5. 异常的优先级5.5.1.6. 中断优先级分组5.5.1.7. 异常流程5.5.2. 向量表重定位机制5.5.3. 中断请求和挂起5.5.4. NVIC寄存器5.5.4.1. 中断的使能和禁止5.5.4.2. 中断挂起和中断清除5.5.5. SCB寄存器6. ARM指令系统6.1. ARM处理器指令集概述6.1.1. ARM的不同指令集6.1.2. ARM指令集扩展6.2. T32指令格式6.2.1. 16比特指令二进制格式6.2.2. 32比特指令二进制格式6.2.3. T32指令的汇编语法6.2.4. T32的条件执行指令6.2.5. T32指令格式示例6.3. T32指令集寻址方式6.3.1. 立即数寻址6.3.2. 寄存器寻址6.3.3. 寄存器间接寻址6.3.4. 寄存器移位寻址6.3.5. 寄存器偏移寻址6.3.6. 前变址寻址6.3.7. 后变址寻址6.3.8. 多寄存器寻址6.3.9. 堆栈寻址6.3.10. PC相对寻址6.4. Cortex-M3/M4指令集6.4.1. 处理器内的数据传送指令6.4.2. 存储器访问指令6.4.3. 算术运算指令6.4.4. 逻辑运算指令6.4.5. 移位运算6.4.6. 数据格式转换6.4.7. 位域处理指令6.4.8. 比较和测试指令6.4.9. 程序流控制指令6.4.9.1. 无条件跳转和函数调用指令6.4.9.2. 条件跳转6.4.9.3. 比较和跳转6.4.9.4. 条件执行6.4.9.5. 按跳转表跳转6.4.10. 饱和运算6.4.11. 其他杂项指令6.4.11.1. 休眠模式指令6.4.11.2. 异常相关指令6.4.11.3. 空指令和断电指令6.4.12. Cortex-M4特有指令7. ARM程序设计7.1. ARM程序开发环境7.1.1. 常用ARM程序开发环境7.1.2. MDK开发环境简介7.2. ARM汇编程序中的伪指令7.2.1. 符号定义伪指令7.2.2. 数据定义伪指令7.2.3. 汇编控制伪指令7.2.4. 其他常用的伪指令7.2.5. 汇编语言中常用的符号7.2.6. 汇编语言中常用运算符和表达式 7.3. ARM汇编语言程序设计7.3.1. ARM汇编语言的语句格式7.3.2. ARM汇编语言程序结构7.3.3. ARM汇编程序设计实例7.4. ARM汇编语言与C/C++的混合编程7.4.1. C语言与汇编语言之间的函数调用7.4.2. C/C++语言与汇编语言的混合编程8. 基于ARM微处理器硬件与软件系统设计开发8.1. 嵌入式硬件与软件系统设计与开发综述8.1.1. 概述8.1.2. 嵌入式生态系统8.1.3. 开发环境、开发工具和调试方式8.1.4. 嵌入式系统开发过程8.2. ARM内核常用微处理器8.2.1. 三星S3C2440A8.2.2. 恩智浦LPC21328.2.3. 意法半导体STM328.3. 最小硬件系统8.3.1. 微处理器最小硬件系统8.3.2. S3C2440A最小硬件系统8.3.3. STM32最小硬件系统8.3.4. MCU及其周围电路设计8.3.4.1. 电源电路8.3.4.2. 复位电路8.3.4.3. 时钟电路8.3.4.4. 调试和下载电路8.3.4.5. 启动电路8.3.4.6. 启动代码和启动过程8.4. 嵌入式软件系统设计8.4.1. 系统结构及工作流程8.4.2. 嵌入式操作系统8.4.3. 程序开发模式8.4.4. 软件开发流程8.5. ARM中的GPIO8.5.1. 概述8.5.2. 工作原理8.5.2.1. 内部结构8.5.2.2. 工作模式8.5.2.3. 输出速度8.5.2.4. 复用功能重映射8.5.2.5. 外部中断映射和事件输出8.5.2.6. STM32F10x的GPIO主要特性8.5.3. 相关库函数及寄存器8.5.3.1. 库函数8.5.3.2. 常用寄存器8.5.3.3. AFIO寄存器8.5.4. 应用与举例8.6. 定时器8.6.1. 概述8.6.2. 基本定时器TIM6和TIM78.6.2.1. 内部结构8.6.2.2. 时钟源8.6.2.3. 计数模式8.6.2.4. 基本工作原理8.6.2.5. 主要特性8.6.3. 通用定时器TIM2~TIM58.6.3.1. 内部结构8.6.3.2. 时钟源8.6.3.3. 计数模式8.6.3.4. 普通输入捕获模式8.6.3.5. PWM输入捕获模式8.6.3.6. 比较输出模式8.6.4. 高级定时器TIM1和TIM88.6.5. 主从模式、触发与同步8.6.5.1. 主从模式8.6.5.2. 触发8.6.5.3. 从模式下的工作模式8.6.5.4. 定时器级联及同步8.6.6. 相关库函数及寄存器8.6.6.1. 库函数8.6.6.2. 常用寄存器8.6.7. 小结及应用要点8.6.7.1. 定时器配置要点8.6.7.2. PWM程序实现步骤8.6.7.3. PWM程序实现的3个要点8.7. 中断控制器8.7.1. 中断系统综述8.7.1.1. 嵌套向量中断控制器NVIC8.7.1.2. 中断优先级8.7.1.3. 中断向量表8.7.1.4. 中断服务函数ISR8.7.1.5. 中断设置过程8.7.2. 外部中断/事件控制器EXTI8.7.2.1. 内部结构8.7.2.2. 工作原理8.7.3. 相关库函数及寄存器8.7.3.1. 库函数8.7.3.2. 常用寄存器8.7.4. 小结及应用要点8.8. USART8.8.1. 主要特性8.8.2. 内部结构8.8.3. USART中断8.8.4. 相关库函数及寄存器8.8.4.1. 库函数8.8.4.2. 常用寄存器8.8.5. 小结及应用要点8.8.5.1. 库函数开发STM32F103外设过程8.8.5.2. STM32F10x标准外设库函数的分类和命名8.8.5.3. USART配置的一般步骤8.8.5.4. 注意事项8.9. SPI8.9.1. SPI工作原理8.9.1.1. 主要特性8.9.1.2. 内部结构8.9.1.3. SPI主模式8.9.1.4. SPI从模式8.9.1.5. SPI状态标志和中断8.9.1.6. SPI发送/接收数据8.9.2. SPI相关库函数及寄存器8.9.2.1. 库函数8.9.2.2. 常用寄存器8.9.3. SPI小结与应用要点8.10. I2C8.10.1. I2C工作原理8.10.1.1 主要特性8.10.1.2. 内部结构8.10.1.3. I2C主/从模式8.10.1.4. I2C中断8.10.2. I2C相关库函数及寄存器8.10.2.1. 常用库函数8.10.2.2. 初始化结构体8.10.2.3. 典型库函数8.10.3. I2C小结及应用要点附录中英文术语对照表
概述
计算机系统的基本结构与工作原理
存储器系统
总线和接口
ARM处理器体系结构
ARM处理器指令系统
ARM程序设计
基于ARM微处理器硬件与软件系统设计开发
附录
中英文术语对照表
布莱兹·帕斯卡(Blaise Pasca):基于齿轮结构的机械加减法器
莱布尼茨(Gottfried Wilhelm Leibniz):可进行乘法、除法和自乘运算的机械计算器
查尔斯·巴贝奇(Charles Babbage):基于齿轮结构的差分机和分析机
阿兰·图灵(Alan Turing):图灵机
莫克利(John Mauchly)、艾克特(Eckert)团队:ENIAC(电子数字积分器和计算器)
冯诺依曼(Von Neumanm):EDVAC(离散变量自动电子计算机)
确定计算机五个构成部分:运算器,控制器,存储器,输入设备,输出设备
三方面重大改进
莫里斯·威尔克斯(Maurice Wilkes):EDSAC
第一阶段: 电子管阶段 (1946至20世纪50年代中期)
第二阶段: 晶体管时代 (1955至20世纪六十年代中期)
第三阶段: 集成电路时代 (1965至20世纪七十年代初期)
第四阶段: LSI & VLSI时 (1972~1990)
第五阶段: ULSI & GSI时代 (1991年至今)
微型计算机
服务器
具有较强大计算能力,可通过网络为大量用户提供计算、信息处理和数据存储服务,用于大型企事业单位和政府机构的信息处理服务。可分为:
采用Unix操作系统的小型机(服务器)
采用Intel架构的x86服务器
嵌入式计算机
超级计算机
计算机硬件: 构成计算机的物理部件
计算机软件: 按特定顺序组织的指令和数据集合
主存储器
辅助存储器
主存特点:读写速度相对较快,价格高、容量受限、掉电后RAM存储的信息消失
辅存特点:读写速度慢,价格低,容量大、具有非易失性,又称为外存
常见外存包括:
主要功能: 完成各种数据运算和处理
核心构成: 算术逻辑单元ALU和寄存器阵列
ALU:在控制信号的作用下完成任意的算术或逻辑运算 (加、减、乘、除、移位或比较大小等)
寄存器: 运算器内部的高速存储单元,访问速度最快
计算机的指挥控制中心
主要功能: 根据指令对计算机各部件进行操控,协调各部件有序工作
主要构成:
VLSI出现后,运算器和控制器被集成到CPU中
CPU与主存是计算机的核心部分
主要功能:将信息进行编码后输入计算机
最常见输入设备: 键盘和鼠标
用于人机交互的输入设备:
其他输入设备
主要功能: 在计算机与和外设之间进行桥接和匹配,解决种类繁多、速度快慢不一、信息编码格式各异的输入输出设备的互连问题
适配器又称I/O接口
多个不同种类的外设,需要多个接口
常见的外设接口:并行接口、I2C接口、串行接口和USB接口
主要功能: 实现各部件之间的信息传输和交换
按用途分三类:
按特定顺序组织的计算机数据和指令的集合,可分为:
系统软件
应用软件
中间件软件
第一代 1846~1953
第二代 1954~1964
第三代 1965~1970
第四代 1971~1989
第五代 1990~至今
10进制
二进制
16进制 (两位16进制表示1字节)
位、字节、字和字长
原码
约定: 数值的原码记为,若机器(处理器)字长为位,那么数值的原码定义为:
最高位为符号位:0为正数,1为负数,其余为绝对值
n bit原码可表示的数值范围是:
例:8位有符号二进制数:
原码表示的0有正负之分,习惯上将0用+0表示
原码存在的问题:原码表示的有符号数在运算时会出现错误 (原因:在运算过程中,符号位也参与了运算)
反码
约定:数值的反码记为,若机器(处理器)字长为位,那么数值的反码定义为:
n bit反码可表示的数值范围为:
整数的反码与原码相同;负数的反码符号位为1,其余各位与原码相反
反码表示的0有正负之分,习惯上将0用+0表示
使用反码表示数据,在运算时符号位也参与运算,故计算机未采用反码
补码
约定:数值的补码记为,若机器(处理器)字长为位,那么数值的补码定义如下:
正数的补码与原码完全相同
负数的补码用模的补数的二进制编码表示
补码运算
对于有符号数和有:
采用补码运算的前提:结果不能发生溢出(结果超出了补码所能表示的范围)
结论:若记符号位向前进位为CP,次高位向前进位为CF,当且仅当时,结果发生溢出
推论:
定点数:采用定点格式表示的数据,能够表示的数值范围较小,所需的硬件电路较简单
浮点数:采用浮点格式表示的数据,可以表示的数值范围很大,所需的硬件电路较复杂
浮点格式:有效数字和数值范围(比例因子)分别表示,小数点位置将随比例因子不同在一定范围内浮动
任意一个二进制数也可以表示为:
IEEE-754规定的浮点数格式
BCD编码
4位二进制表示1位十进制数,最常用的是8421 BCD码,简称BCD码
例如:10进制数135,其BCD码位0001 0011 0101
计算机以字节为基本存储单位,有两种BCD码表示方法
压缩BCD码:一个字节表示2位十进制数
非压缩BCD码:一个字节仅用来表示一位BCD码,其中低4位表示0~9,高4位为0
存在的问题
每4位二进制数可以表示成16种状态,但是BCD码只使用其中的10个,二进制数状态空间利用率低
计算机对数据运算均按照二进制运算规则将带来问题
例如:7+5用非压缩BCD码计算
错误原因:使用二进制运算法则计算BCD码
解决方法:BCD码运算后必须对结果进行调整
ASCII码——美国信息交换标准代码
ASCII等同于国际标准的7单位制IRA码
用于给西文字符编码,由7位二进制数组合而成,可以表示128种字符
在ASCII码中,按其作用可分为
字符串表示方法
字符串:一串连续字符,在内存中占用连续多个字节,每个字节存放一个字符
字长为多字节的计算机,一个字可存放多个字符
不同类型的计算机,一个字有两种字符存放顺序
Embedded System:嵌入式计算机系统的简称
IEEE定义:嵌入式系统是用于控制、监视或者辅助设备、机器和车间运行的装置
中国大陆定义:以应用为中心、以计算机技术为基础,软件硬件可裁剪,适应应用系统对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统
三个特点:嵌入性、专用性和计算机系统
嵌入性的两层含义:
主要包括:
嵌入式微处理器(核心)
存储器(外存多采用半导体非易失存储器,如flash)
嵌入式外围设备
I/O接口
嵌入式微处理器 (EMPU)
原理和功能和通用微处理器相同
MPU没有存储器和外设接口 (MPU的特征)
使用MPU构建嵌入式系统需要外接存储器和I/O接口芯片
如果所有器件安装在一块主板上—单板机
单板机特点:
嵌入式微控制器 (EMCU)
数字信号处理器 (DSP)
通过内部硬件电路和专门的DSP指令,快速实现各种高强度数字信号处理,广泛用于数字滤波、信号特征分析、电子对抗、音视频编/解码等领域
有非嵌入式和嵌入式、定点和浮点之分
片上系统 (SOC)
分为嵌入式操作系统和嵌入式应用软件
嵌入式操作系统
应用软件
第一个嵌入式处理器:Intel 4004
嵌入式系统发展的四个阶段:
ARM
Advanced RISC Machines:全球最大的IP供应商
体系架构版本先后有ARMv1~v8,从v4开始成熟,从v8开始升级到64位,版本号与产品名称之间的关系较为复杂
早期产品:ARM7、ARM9和ARM11等系列
v7版本以后产品名称改用Cortex,有CortexA、M和R三大系列,分别适用不同的应用需求
MIPS
分层目的:分析计算机各个部件之间的逻辑关系
层次模型发展历程:
最初阶段:只有两层
第二阶段:微程序 vs RISC
微程序设计思想 → 三层模型
微程序
微程序简化了控制器硬件,并可实现复杂指令
增加新指令,引入新的寻址方式,导致
RISC
二八定律
为提高性能,应该:
第三阶段:操作系统
第四阶段:编程语言
结构特点:
每个字节拥有一个独一无二的物理地址(PA),字节是计算机可访问的最小存储单元
字节寻址存储器:按照字节组织存储器,连续地址对应于连续的字节单元(存储器按照字节组织)
计算机的分体结构:
问题描述:若总线宽度为16位、32位或64位,CPU访问存储器时,为一次能够传输一个完整的字(2/4/8字节),或根据需要一次传送这个字中的一部分字节,应如何组织存储器和连接存储器与总线?
以32位模型机为例,总容量为232的存储器分成4个存储体,每个存储体为230,分别与32位数据总线按下图连接,每个存储体只需30条地址线,用字节选择信号进行选择
Intel 8086系统存储器的分体结构
Intel 8086数据总线位宽为16位,地址总线位宽为20位
8位计算机没有对准存放问题
对准存放:
对准存放不是必须的,但如果采用对准存放,存取一个字只需要一次总线操作即可完成
假设由,,和组成,是最高字节,是最低字节,存储需使用4个地址连续的内存单元
对于地址依次为、、和的连续4个存储单元,单元地址最小,称为尾部;单元地址最大,称为头部
有两种存放格式:
如果采用对准存放,是整个字的地址
现代许多CPU兼容大端格式和小端格式,如:ARM处理器默认小端格式,但可通过硬件引脚或者指令选择大端格式
计算机运行时所需的指令和数据都存放在存储器中。一条指令在执行之前必须将这条指令完整地从存储器取出并传送到CPU中;指令执行时所需的操作数和操作结果有时也需要在CPU和存储器之间进行传送
两个最基本操作:读出和写入
读操作
作用:将一个指定内存单元的内容读出并传送到CPU中
特点:读操作之后存储单元的内容保持不变
过程:
写操作
作用:从CPU中向一个指定存储单元传送一条数据
特点:传送的数据将覆盖目的单元中原有的内容
过程:
连续数据读写
对存储器的要求:速度快、容量大、成本低
分级存储体系结构
使用外存满足大容量、低成本和非易失的要求
使用DRAM型内存,兼顾容量、速度和成本
使用高速缓存,减少CPU访问内存的开销
模型机CPU内部结构:
基本组成
算术逻辑单元ALU:运算器的核心
累加器ACC:特殊寄存器
暂存器
标志寄存器:也称为程序状态寄存器
标志寄存器的内容称为程序状态字PSW,PSW分为状态标志位(条件码标志位)和控制标志位
状态标志位:记录ALU运算后的状态或者特征
如:结果是否为零?是否为负数?是否有溢出?是否有进位?
后续指令可根据状态标志决定程序执行顺序
例如:
ARM处理器的程序状态寄存器(PSR)中有4个状态(条件码)
Intel 8086中还有辅助进位位A和奇偶校验位P(P现已不用)
后续指令可根据这些状态标志决定程序是顺序执行还是跳转执行
控制标志位:是对CPU的某些行为进行控制和管理
Intel 8086的标志寄存器中有3个控制标志位
Intel 8086提供了对D和I进行单独操作的指令,如
Intel 8086还提供了对状态标志位C的3条操作指令,操作内容分别是置位、复位和取反
整个CPU的指挥控制中心
功能和作用:
根据指令中的操作码和时序信号,产生各种控制信号,对系统各个部件的工作过程进行控制,指挥和协调整个计算机有序地工作
控制器主要构成:
指令寄存器IR (Instruction Register)
指令译码器ID (Instruction Decoder)
操作控制器OC (Operation Controller)
有观点认为包括程序计数器PC (Program Counter)
(也有观点认为PC属于数据通道)
指令寄存器IR
指令译码器ID
计算机能且只能执行“指令”
指令由操作码和地址码两部分构成
指令译码器只对操作码进行译码,分析和识别指令应该执行什么样的操作
操作控制器OC
程序计数器PC
控制器的工作过程:
微操作
每条指令的执行过程都可以分解为一系列的微操作
特点:可由简单电路实现;可被多个指令复用
举例:
假设指令“ADD R1,R2,R3”的功能为R2+R3→R1
这条指令的执行过程可以分解为以下几个微操作:
控制器的实现方式
微程序控制器
简介
结构
工作原理和过程
硬连线控制器
简介
设计步骤
一般结构
特点:速度快,电路复杂,不支持复杂指令,调试和改动困难,一度被微程序取代。近年因RISC的兴起和VLSI的进步,再度兴起
也称为寄存器组、寄存器堆和寄存器文件
CPU内部若干高速存储单元,每个都有编号或名称,根据指令中的编号或者名称对其直接访问
CPU与寄存器之间的数据交换是通过内部总线直接进行的,所以CPU与寄存器之间的数据传送速度最快
受指令长度限制,寄存器数量有限,只能暂时存放CPU工作时所需的少量数据和地址
分为专用寄存器和通用寄存器两大类
CPU内部总线与系统总线之间的接口,提供地址和数据传送缓冲,同时增加CPU的系统总线驱动能力
计算机各部件按功能划分为两大阵营:控制单元CU和执行单元EU
CU就是控制器,也是计算机中指令流的终点。控制器的组成包括指令寄存器、指令译码器和操作控制器。负责指令译码,生成相应的控制信号,控制执行单元完成指令规定的各种操作
EU负责指令执行,如生成地址、读取和传送数据、计算和处理数据、存储结果、更新PSR和PC。执行单元包括运算器、寄存器组、内部总线以及系统总线接口
在指令执行过程中,数据是在运算器、寄存器阵列和系统总线接口之间通过内部总线进行传送,所以这几个部件也被称为数据通道
指令
根据计算机组成的层次结构,可以分为:微指令,机器指令和宏指令
指令系统
一台计算机中所有指令的集合称为这台计算机的指令系统
汇编指令
使用助记符(容易理解和记忆的字母)表示指令的操作码
使用标号和符号地址代替指令和操作数的地址
模型机部分常用汇编指令:
RISC指令风格:定长指令,Load/Store体系,三操作数
Rs-源操作数,Rd-目的操作数,Imm-立即数
Label-标号(用符号表示的指令地址)
定长指令
每条指令长度固定
特点(假设32位机,32位指令长度)
一次取指操作读取一个完整的指令
受指令位数限制,对立即数的大小或者类型有要求
同样原因,对内存寻址时,无法在指令中直接给出内存的单位地址
内存单元地址可用如下方法表示:
计算机运行流程
开始 → 取指 → 执行 → 取指 → 执行 → ……
指令周期
开始取指到完成指令操作的时间
CPU时间
T周期
示例:利用模型机汇编指令编程实现如下操作:
将数据000FF000h(0x000FF000)与内存中某个字数据相加,字数据的地址位于R3寄存器中,如果相加结果没有溢出,则将0x000FF000存入由R3+80h指定的内存单元,然后停机;如果溢出,直接停机
模型机汇编语言源程序片段:
模型机系统结构:
用汇编语言编写的程序称为汇编语言源程序,简称汇编程序。将其转换成机器语言的过程称为汇编,能够实现汇编功能的软件称为汇编器或者汇编软件
汇编后的机器指令顺序存放,若指令长度为4字节,后一条指令地址等于前一条地址加4(PC的单位为字节)
模型机结构假设:
执行过程:
第一条:源操作数是立即数(取指时能从指令编码中立即得到的数),被装入R0寄存器后指令执行完毕
根据程序的名字,把0x20000000装入程序计数器PC
程序计数器PC内容0x20000000送至地址缓冲器/驱动器,地址总线的输出经地址译码器译码,寻址内存单元
操作控制器OC发读信号,将“E3 A0 06 FF”读出到数据总线
由于是取指操作,数据总线上的数据被装入指令寄存器IR
程序计数器PC值自动加4(假设PC内容的单元是字节),指向下一条指令的存放地址
指令译码器ID对操作码译码,操作控制器OC产生相应的控制信号
指令的地址码部分对应着汇编指令的操作数部分。本条指令中,源操作数为立即数#0x000FF000,目的操作数是R0寄存器
在操作控制器OC输出的控制信号作用下,立即数#0x000FF000经地址形成部件和地址驱动器送到地址总线,再经地址译码后寻址到源操作数存放的内存单元
操作控制器OC发出读信号,将源操作数读出到数据总线,然后加载到R0寄存器
第二条:Load操作,从内存取操作数到R1,操作数地址由R3提供
第三条:ADD运算,R0与R1相加,结果存入R1寄存器,完成运算后更新到FR中相关状态位
第四条:条件转移,溢出则跳转执行标号为L2的指令,PC=PC+m(m是转移目的指令与转移指令之间的相对距离);否则继续执行下一条指令
第五条:Store操作,源操作数是R0寄存器的内容,目的操作数的地址是R3寄存器的内容再加上偏移量80h
第六条:HTL停机,持续执行空操作
总结与讨论
指令执行时,指令操作码送到IR,经IR译码后OC产生操作控制信号,指令的地址码送到地址形成部件,生成地址信号
CPU中的所有数据都在数据通道中传送
指令执行过程属于多级串行作业,始终有一部分部件处于空闲状态,部件的利用率不高
模型机属于冯诺依曼架构,串行工作方式的取指和存取操作数在时间上相互错开,不会出现冲突
如果改用流水线方式,前后指令的取指和存取操作数可能同时发生。冯诺依曼体系结构将造成总线竞争,故不太适合流水线模式
CISC:指令数量多、功能丰富、可实现复杂操作
简介
CISC处理器指令的特点
指令长度不一
较长指令取指需要使用多个总线周期和多次总线操作
长短不一的指令给指令译码器设计带来挑战,增加了控制器的复杂性和电路规模,也不利于采用流水线和超标量等新技术
举例:
非Load/Store体系
算术和逻辑运算指令的操作数可以是存储数
ADD[addr], Ri
LDR
、ADD
和STR
,比CISC至少多出2次取值和译码操作MOVE操作
格式为:Move destination,source
的传送指令,可实现寄存器与存储器之间的数据传送
大多数CISC处理器规定,MOVE指令的源操作数和目的操作数最多只能有一个是存储单元
同一条总线上的两个存储单元,如果彼此之间需要传送数据,无论是RISC和CISC处理器,无论采用多条简单指令还是一条复杂指令,数据传送过程都分为两步
两操作数
在现代CISC处理器中,大多数算术和逻辑运算指令只有两个操作数,其格式一般为:
OPR(操作码) DST(目的操作数), SRC(源操作数)
例如,加法指令:
xxxxxxxxxx
Add B, A
对应的操作是(B)+(A)→B。指令执行后,结果送到B原来的存储位置,替换原先的内容。意味着DST既是目的操作数,也是参与运算的两个源操作数中之一
指令功能强大,寻址方式多样,程序简洁
CISC处理器的性能问题
主要影响因素:微程序控制器的工作流程
两种解决思路:
RISC
特点
RISC指令特点
CISC & RISC借鉴与融合
流水线原理
指令执行过程可分解为多个步骤,假设分解为:
每个步骤都有专用部件完成操作,各部件分工明确,各司其职,每个步骤按照顺序执行
模型机任何时候只能执行一条指令,前后指令呈多级串联作业模式,将会造成部件的“窝工”
将功能部件按指令操作步骤顺序进行排列部署,前后部件之间增加缓冲寄存器,构成指令处理流水线
前后两个部件经过缓冲寄存器隔离后,可以相对独立地并行工作
从流水线时空图可看出,在10个流水线周期内
流水线中技术存在的主要问题
流水线高效运行的前提:保持畅通,不发生断流
指令执行过程中可能发生的三种相关冲突:
资源相关,又称结构相关
多条指令在同一周期内争用同一个公用部件
例如:冯诺依曼结构计算机的Fetch、Load和Store操作都使用公用总线接口访问同一个存储器,前一条指令的数据存取操作可能会影响后续指令的取指操作
解决方法
数据相关
后一条指令执行需要使用前一条指令的结果。例如流水线上前后执行的两条运算逻辑令
SUB指令在第5个周期才将结果写回R1,但是AND指令在第4个周期就要读R1进行运算,而程序的本意是“写后读”(RAW)
RAW是一种最为常见的数据相关
流水线可能还存在“写后写”(WAW)和“读后写”(WAR)两类数据相关
解决方法
控制相关
遇到转移指令时,后续已进入流水线的指令都应清空
以无条件转移(包括子程序调用)指令为例:
减少转移代价的方法
依旧存在的问题:大多数条件转移指令是否转移取决于状态标志位,而标志位在ALU运算后才更新,转移代价较大。流水线级数却多,代价越大
转移预测技术
转移延迟槽:转移指令后面的一个时间片。无论是否转移,位于转移延迟槽的指令总是会被执行
动态转移预测:根据转移指令过去的行为进行预测
评估:用2bit(权值)对转移指令过去行为进行量化,‘11’总是转移,‘00’总是不转移
动态打分:每发生一次转移,权值+1,加到11b为止;每发生一次不转移,-1,减到00b为止
使用BTB(转移目标缓冲器),收集和存储了近期所有转移指令的有关信息,并按照查找表的形式进行组织,为动态转移预测提供信息
BTB不能太大,一般为1024个表项,其内容包括:
每条指令在取指时,处理器根据其地址在BTB中进行快速搜索,若有记录则表明这是一条转移指令,并根据其“档案”进行相应处理,最后根据这条指令的实际行为修正BTB的记录内容
标量处理器:只能处理标量数据,一条指令一次只能处理一个数据,属于SSID
向量处理器(阵列处理器),一条指令完成一个向量计算,属于SIMD,用于科学计算和信号处理等领域
超标量处理器:拥有多条流水线,通过空间并行方式提高处理能力
将多条指令分发到多条流水线上,同时执行
分发前需配对检查,不同流水线上的指令不相干
可以使用不同类型的流水线,如整数和浮点数
多发射技术:多个指令分发单元
进程:程序的动态执行过程
线程:能独立执行的代码最基本单元
单处理器同时只能执行一个线程,多线程只是利于操作系统的任务调度,减少无效开销,性能提高有限
超线程技术:为进一步减少处理器内部的硬件资源闲置,对流水线进行改造并添加少量部件,使处理器在同一时间可以执行两个线程
多处理器计算机
一个计算机有分布在不同的芯片上的多个处理器
多个处理器芯片通过共享内存或者共享总线进行数据交换,并行工作,属于一种紧耦合多处理器系统
多处理器计算机分为:
非对称多处理器计算机AMP
全对称多处理器计算机SMP
多计算机系统
分布式计算机系统
可集成的电路数越来越多,可以把多个功能完整的CPU集成在一个芯片上——单芯片多内核处理器
每个计算内核普遍采用超标量和超级流水线技术,拥有所需的全部计算资源,可彼此独立地执行任务
多个内核通过片内总线或交叉开关矩阵互连,可看作一个片上多处理器机CMP系统,对外呈现为一个统一的处理器
分为同构多核和异构多核两种类型
同构
异构
多核处理器性能与任务的并行性有关
安达尔定律:性能加速比
其中,为节点数,为可并行代码比例
应在核数、功耗、代价和实际效果间寻求平衡
ARM体系结构
ARMv1~ARMv7属于32位架构,ARMv8属于64位架构
ARMv7子版本
ARM处理器和ARM内核
严格地说,ARM处理器是ARM公司设计的处理器
芯片制造商获得授权后,根据实际需求和产品定位,在某款ARM设计的处理器基础上,再增加诸如实时时钟、ADC、DAC、存储器、协处理器、DSP,以及各种接口单元部件,形成多种各具特色的嵌入式处理器芯片,实际上应该属于SOC,但是往往也被称为ARM处理器(芯片)
ARM处理器成功三要素
不同版本的ARM内核都具有如下RISC架构的共同特征:
ARM内核吸取的CISC架构特点:
其他特点
ARM7TDMI——ARM7系列基本型产品
属于ARMv4T版本,产品后缀含义:
内部结构:
简介
ARM7家族其他产品的基础,内核中的内核
包括一个32位ALU,一个32位桶形移位寄存器和一个32位x8位乘法器
共有37个程序可访问的32位物理寄存器,包括31个通用寄存器和6个状态寄存器
“写”和“读”数据总线分开,片外只需配置单向总线驱动器,没有双向驱动器的方向转换时延
特点
ARM920T基本结构和特点
ARM9系列简介
ARM9产品家族可分为ARM9和ARM9E两个系列
ARM9系列与ARM7相比在体系结构上的改进
ARM9TDMI处理器简介
ARM9TDMI是ARM9产品家族中的基本型产品
同系列的其他处理器都是以ARM9TDMI为核心,扩展和集成其他功能部件所构成:
ARM920T处理器简介
属于ARM9系列,以ARM9TDMI为核心,另外配置了
支持VxWorks,WindowsCE和Linux等嵌入式OS
高性价比和低功耗,典型的目标SOC芯片
提供1.1MIPS/MHz的哈佛结构
ARM920T处理器结构
两类地址信号:物理地址PA和虚拟地址VA
CP15:系统控制协处理器,用于管理和控制Cache、MMU、时钟类型和大小端设定等系统级操作
回写物理地址TAG:地址标记寄存器,存放Cache中需要回写(更新)数据字段在主存中的地址信息
数据总线上的写缓存:提高数据回写操作的速度
JTAG:符合JTAG规范的测试接口
机器字长
计算机中的字长不仅影响计算精度,也影响运算速度。64位计算机的性能显然高于32位
存储容量
在计算机存储系统中,高速缓存和内存(主存)容量和类型是评价计算机系统性能的两项重要指标
一般来说,高速缓存和内存容量越大、存取速度越快,计算机的处理能力就越强
总线带宽和数据吞吐速率
一般来说,总线带宽取决于总线结构、位宽、主频等。数据吞吐速率还与存储器的存取速度、传送方式、数据的组织形式以及外设接口速度等因素有关
能耗与环保
关于CPU效能的指标主要有EPI,EPI指标越低,表明CPU的能源效率越高
计算机的环保指标:耗电量、辐射、噪声、各种器件中有害物质的含量、各种废弃物的可处理性等
RASIS特性
定量描述指标:速度
一般来说,一台计算机的主频高、CPU数量或者内核数量多、高速缓存和主存容量大、总线传输速率高,表明计算机运算速度也快
早期指标:MIPS
对于执行相同的任务,RISC计算机相比CISC计算机要花费更多的指令,MIPS对CISC和RISC不能客观评价
现在指标:基准测试
Whetstone和Dhrystone
CoreMark
SPEC测试,通用计算机使用最多的基准测试
其他基准测试
TPC
大型信息系统核心主机选型的重要依据
主要针对计算机在数据库应用及事务处理方面的性能,常见的有
Linpack(线性系统软件包)
一种高性能计算机系统浮点性能测试基准。通过在计算机(集群)系统中运行Linpack测试程序,可以得到能够反映高性能计算机浮点性能的测试结果Flops。在高性能计算领域,Linpack指标收到普遍重视
SAP基准测试
原理
半导体存储器是一种以半导体电路作为存储媒体的存储器,内存储器就是由成为存储器芯片的半导体集成电路组成
分类
按其功能分
按地位和作用分
按结构和工艺分
按存储信息的可保存性分
按存储器在计算机中的功能分
优点
缺点
原理
利用磁性介质的磁极化来存储信息
分类
特点
磁芯存储器结构和工作方式
磁芯在导线上流过一定电流情形下会被磁化或者改变磁化方向,实现通过实验和材料的工艺控制得到这个能够让磁芯磁化的电流最小阈值。根据磁化时电流的方向磁芯可产生两个相反方向的磁化,这就可作为0和1的状态来记录数据。每个磁芯都有XY互相垂直的两个方向的导线穿过,另外还有一条斜穿的读出线,这些线组成阵列,XY分别做两个不同方向的寻址
磁盘结构和工作方式
磁带结构和工作方式
原理
光盘上刻有凹点和空白,光照射后辐射强度不同,接收电路再转化为0、1地数字信号
分类
光驱结构和工作方式
特点
微型计算机系统的存储体系架构是分层次的,离CPU越近的存储器,速度越快,每字节的成本越高,同时容量越小。按照与CPU由近到远的距离,有
按照访问速度快慢和容量,有
简单的二级结构:内存+外存
完整的四级结构:寄存器+Cache+主存+辅存(联机、脱机外存)
寄存器
组成
功能
特点
高速缓冲存储器Cache
组成
存在于CPU与内存之间,由静态存储芯片SRAM组成
功能
CPU向内存读取数据时,首先查询Cache存储体缓存区是否有对应数据,如果有则直接读取,没有再从内存中读取
特点
主存储器
组成
功能
程序的运行都是在内存中进行。存储指令(编译好的代码段),运行中的各个静态,动态,临时变量,外部文件的指针等等
特点
成本较高,容量比较大,速度高,但比Cache低得多
辅存
联机外存储器
组成:主要为磁介质的机械硬盘、固态硬盘SSD
功能:存储需要永久存储的文件
特点:
脱机外存储器
常将联机、脱机存储器称为辅助存储器。辅助存储器接口,主要包括硬盘接口标准、Flash存储卡的接口标准等。通用的接口标准为不同类型辅助存储器产品提供接入的互换性,便于产品升级和维护
微机常用存储接口:
嵌入式设备常用存储接口:
IDE接口
SCSI接口
SATA接口
SAS接口
SD接口
eMMC接口
嵌入式存储器接口
特点
UFS
UFS,即“通用闪存存储”,同样是一种内嵌式存储器的标准规格,由JEDEC(Joint Electron Device Engineering Council)发布。同样是整合有主控芯片的闪存,不过其使用的是PC平台上常见的SCSI结构模型并支持对应的SCSI指令集
UFS是UFSHCI标准JESD223的扩展
UFSHCI标准定义了UFS驱动程序和UFS主机控制器之间的接口。除寄存器接口外,它还定义了系统内存中的数据结构,用于交换数据,控制和状态信息
技术特点
电子计算机主板上主要采用半导体存储器,称为内存
内存用来存放当前执行的数据和程序,有易失性和非易失性两种
RAM:易失性存储器,仅用于暂时存放程序和数据,关闭电源或断电数据会丢失
ROM:非易失性存储器,用于存放程序或静态数据,即使断电,数据也不会丢失
简介
特点:
分类:
静态RAM(SRAM):其存储电路以双稳态触发器为基础,状态稳定,只要不掉电,信息不会丢失。
动态RAM(DRAM):其存储单元以电容为基础,电路简单,集成度高。但也存在问题,即电容中电荷由于漏电会逐渐丢失,因此DRAM需定时刷新电路。它适用于大存储容量的计算机
静态RAM(SRAM)
特点
基本存储电路
工作原理
保持状态
读出状态
选择线通过译码控制为高电平
写入状态
选择线通过译码控制为高电平
静态RAM芯片结构
静态RAM芯片内部由多个基本存储电路单元组成,容量为单元数与数据线位数之乘积
为了选中某一个单元,往往利用矩阵式排列的地址译码电路:行选择信号 + 列选择信号
常用的典型SRAM芯片有6116、6264、62256、628128等
以6116芯片为例:
6116芯片的容量为位
2048个存储单元需11根地址线
6116控制线有三条:片选CS#、输出允许OE#和写入允许(读写控制)WE#
工作过程:
读出
写入
无读写操作
动态RAM(DRAM)
特点
存储原理
存储单元由1个MOS管和1个小电容构成
数据输入输出端连数据总线的某一位Di(位线)
低位地址(如A0~ A7)译码产生行选信号X,高位地址(如A15~A8)译码产生列选信号Y。X、Y都为高电平时该单元被选中
刷新操作:
写操作时,X=1,Y=1,Q和T管均导通,要写入的值(0或1)从Di加到C上
读操作时,Q和T同样导通,存储在C上电荷通过Q、刷新放大器和T输出到Di
DRAM芯片举例
常见小容量DRAM芯片有:
大容量DRAM芯片有:
DRAM芯片举例:Intel 2164A
以Intel 264A为例
Intel 264A的地址线与寻址
64K×1存储主体,设计成4个128×128矩阵
4个128路刷新放大器,接收由行地址选通的4×128个存储单元信息,经放大后再写回原存储单元进行刷新
16位地址分为行地址A7~ A0和列地址A15~A8,以分时复用方式,分两次送入芯片。行地址在先,列地址随后,各由一个8位地址锁存器保存
两次送来的8位地址信息的最高位(A7和A15),形成RA7和CA7去控制4选1的I/O门电路,从4个矩阵中选择1个进行读/写
行/列地址译码器对行/列地址的低7位进行译码,从某个128×128个单元中选择1个进行读/写
行地址到达,选通信号RAS#变低;列地址到达,选通信号CAS#变低。经行/列时钟缓冲器协调后,有序控制行/列地址的选通以及数据读/写或刷新
要写入的1位数据从脚输入,由数据输入缓冲器暂存;准备从脚读出的1位数据,也先由输出缓冲器暂存
写允许WE#以及RAS#、CAS#信号, 通过写允许时钟缓冲器控制后, 决定打开哪个数据缓冲器
DRAM存储条
内存条
内存条的主要技术指标
存储条示例
图中是采用HYM59256A存储芯片,构成256K×9位存储容量的存储条
其中,2片256K×4位的存储芯片通过位扩展形成256K字节的存储单元,1片256K×1位的存储芯片作为奇偶校验
引脚
只读存储器(ROM)掉电后信息不会丢失(非易失性或不会挥发性),弥补了RAM的不足,因此成为计算机中的一个重要部件
ROM包括掩模ROM、PROM、EPROM、EEPROM等多种类型
掩模ROM和PROM已淘汰,广泛使用的是EEPROM 和Flash
注意:
掩膜ROM
Mask ROM(掩膜ROM)的存储数据由专门设计的掩模板决定,为固化数据,用户不能修改
ROM电路结构包括存储矩阵、地址译码器和输出缓冲器三个组成部分
掩膜ROM芯片示例:
4位数据输出,4×4位的MOS管,单译码结构
地址线A1、A0,译码后可译出4种状态W3~ W0。输出4条选择线,分别选中4个单元,每个单元4位输出
存储矩阵由MOS门组成,当W3~ W0每根线上给出高电平信号时,都会在4根线d3~ d0上输出一个4位二值代码
将每个输出代码称为一个“字”,并将W3~ W0称为字线,将d3~d0称为位线(或数据线),而A1、A0称为地址线
输出端的缓冲器用来提高带负载能力,并将输出的高、低电平变换为标准的逻辑电平
通过给定EN#信号实现对输出的三态控制,将数据反相输出
若地址线A1A0=00,则选中0号单元,即字线0为高电平,若有MOS管与其相连(如位线d2和d0),其相应的MOS管导通,位线输出为0,而位线1和3没有MOS管与字线相连,则输出为1
掩膜ROM存储矩阵的内容:
单元/位 | d3 | d2 | d1 | d0 |
---|---|---|---|---|
0 | 1 | 0 | 1 | 0 |
1 | 0 | 1 | 0 | 0 |
2 | 1 | 0 | 1 | 1 |
3 | 0 | 0 | 0 | 1 |
可编程ROM(PROM)
简介
PROM采用经典的“双极性熔丝结构”
编程过程
EPROM
简介
可擦除可编程ROM
是一个N沟道增强型的MOS管,有两个重叠的栅极—控制栅Gc和浮置栅Gf
初始状态
重复擦写编程的EPROM
编程原理
擦除原理
EPROM芯片示例
EPROM芯片有多种型号,如2716(2K×8 位)、2732(4K×8 位)、2764(8K×8 位)、27128(16K×8 位)、27256(32K×8 位)等
典型EPROM芯片2764A
读方式(数据)
读方式(读Intel标识符)
备用方式
编程方式
编程禁止
编程校验方式
快速编程方式
小结
2764A的工作方式选择表
方式/引脚 | CE# | OE# | PGM# | A9 | A0 | VCC | Vpp | 数据端功能 |
---|---|---|---|---|---|---|---|---|
读 | 低 | 低 | 高 | × | × | 5V | VCC | 数据输出 |
输出禁止 | 低 | 高 | 高 | × | × | 5V | VCC | 高阻 |
备用 | 高 | × | × | × | × | 5V | VCC | 高阻 |
编程 | 低 | 高 | 低 | × | × | VCC | 12.5V | 数据输入 |
校验 | 低 | 低 | 高 | × | × | VCC | 12.5V | 数据输出 |
编程禁止 | 高 | × | × | × | × | VCC | 12.5V | 高阻 |
标识符 | 低 | 低 | 高 | 高 | 低 | 5V | VCC | 制造商器件编码 |
EPROM存在的问题
电可擦除可编程ROM(EEPROM,E2PROM)
基本特性
工作原理
结构示意
为了提高擦、写的可靠性,并保护隧道区超薄氧化层,在E2PROM的存储单元中除Flotox管外还附加了一个选通管T2。右图中的T1为Flotox管(也称为存储管),T2为普通的N沟道增强型MOS管(也称为选通管)
工作过程
读出
写入
擦除
典型芯片
E2PROM的主要产品有:
主要技术指标
举例:2816芯片
基本特点
工作方式选择表
方式/引脚 | CE# | OE# | VPP/V | 数据端功能 |
---|---|---|---|---|
读 | 低 | 低 | +4V~+6V | 输出 |
备用 | 高 | × | +4V~+6V | 高阻 |
字节擦除 | 低 | 高 | +21V | 输入为高电平 |
字节写 | 低 | 高 | +21V | 输入 |
片擦除 | 高 | +9~+15V | +21V | 输入为高电平 |
擦写禁止 | 低 | × | +21V | 高阻 |
2816读方式
2816写方式
以字节为单位的擦除和写入是同一种操作,即均为写
字节擦除与写入
2816片擦写方式
2816备用方式
快闪存储器Flash
简介
工作原理
目前常见的半导体闪存工作原理类似于E2PROM,采用MOS工艺
Flash与E2PROM的区别
Flash没有选通管T,因此集成度高,容量大,但稳定性和擦写次数都不如E2PROM
E2PROM可按位擦除,Flash只能按块(或按页或行)擦除
Flash的缺陷:由于闪存写入时有“突破氧化膜”这一剧烈动作,不仅限制了写入速度,而且随着反复的写入,氧化膜出现老化。NOR和NAND闪存可擦写次数分别限制在10万次和100万次左右
工作方式
分类
NOR型闪存
NAND型闪存
N是NOT,含义是浮置栅中有电荷时,读出‘0’,无电荷时读出‘1’,是一种‘非’的逻辑;OR的含义是同一个位线下的各个基本存储单元是并联的,是一种‘或’的逻辑
NAND型闪存的优点是存储密度和存储容量大
NAND型闪存也需要先擦除再写入,擦除和写入是以块或者页为单位进行的,一个块包含了若干页,每一页的有效容量是512字节的倍数
存储容量
在一个存储器中容纳的存储单元总数通常称为该存储器的存储容量
存储容量可以用位数、字数或字节数来表示
以位数表示的存储器芯片容量计算:存储器芯片容量=单元数×数据线位数
例如,设地址线位数为n,数据线位数为m,则:
存储器芯片是以存储1位二进制数(bit)为最小单位
存放一个机器字的存储单元,通常称为字存储单元,相应的单元地址叫字地址。而存放一个字节的单元,称为字节存储单元,相应的地址称为字节地址
如果计算机中可编址的最小单位是字存储单元,则该计算机称为按字编址的计算机。如果计算机中可编址的最小单位是字节,则该计算机称为按字节编址的计算机
一个机器字可以包含数个字节,所以一个存储单元也可以包含数个能够单独编址的字节地址
虽然微型计算机的字长已经达到16位、32位,甚至64位,但其内存仍以一个字节为一个单元
计算机存储单位换算表:
中文单位 | 中文简称 | 英文单位 | 英文简称 | 进率(Byte=1) |
---|---|---|---|---|
位 | 比特 | bit | b | 0.125 |
字节 | 字节 | Byte | B | 1 |
开字节 | 开 | KiloByte | KB | 210 |
兆字节 | 兆 | MegaByte | MB | 220 |
吉字节 | 吉 | GigaByte | GB | 230 |
太字节 | 太 | TeraByte | TB | 240 |
拍字节 | 拍 | PetaByte | PB | 250 |
艾字节 | 艾 | ExaByte | EB | 260 |
泽字节 | 泽 | ZettaByte | ZB | 270 |
尧字节 | 尧 | YottaByte | YB | 280 |
布字节 | 布 | BronteByte | BB | 290 |
存取时间和存取周期
存取时间(访问时间)Ta
影响Ta的因素
存取周期TM
其他指标
数据传送速率(频宽)BM
数据传送速率,指单位时间内能够传送的信息量
若系统的总线宽度为W,则BM=W/TM(b/s)
例如,若W=32位,TM=100ns,则
体积与功耗
可靠性
内存条的特点:
内存颗粒
内存芯片称为内存颗粒
芯片封装:TSOP(Thin Small Outline Package)和BGA(Ball-Gird-Array)
TSOP:引脚由四周引出
BGA:引脚由芯片中心方向引出
有效缩短信号的传导距离,使信号衰减减少,更加快速有效的散热
在相同容量下,体积只有TSOP封装的三分之一
根据内存条容量,集成数量不等的内存颗粒
SPD芯片
PCB电路板
内存条的PCB采用4层或6层电路板
引脚/金手指
排阻和电容
SIMM
FPM DRAM & EDO DRAM
SDR SDRAM (Single Data Rate SDRAM)
SDRAM(Synchronous DRAM,同步动态随机存取内存)
传统DRAM采用“异步”的方式进行存取,存储器的吞吐速率受限从而导致系统性能难以提高
SDRAM采用同步方式进行存取。送往SDRAM的地址、数据和控制信号都在一个时钟信号的上升沿被采样和锁存,SDRAM输出的数据也在另一个时钟上升沿锁存到芯片内部的输出寄存器
SDRAM收到地址和控制信号之后,在内部进行操作。在此期间,处理器和总线主控器可以处理其它任务(例如,启动其它存储体的读操作),无需做无谓等待,从而提高了系统性能
输入地址、控制信号到数据输出所需的时钟个数可以通过对芯片内“方式寄存器”的编程来确定
SDRAM芯片支持“突发总线模式(Burst)”进行读写操作。当对一组相邻的存储单元进行访问时,第一个地址给出后,后续地址自动生成,无需再发,可以进行连续读写,大大提高了速度
RDRAM (Rambus DRAM)
Intel与Rambus合作并推出了Rambus DRAM内存条以代替SDR SDRAM,简称为RDRAM
与SDRAM不同,采用了新的高速简单内存架构,减少数据复杂性,提高整个系统性能
RDRAM采用RIMM(Rambus In-line Memory Module)插槽,184脚,总线位宽16位,插两条组建双通道时就是32位,工作电压2.5V,频率有600、700、800、1066MHz等
RDRAM内存条通常都是用在Socket 423的奔腾4平台上,搭配Intel 850芯片组使用。由于RDRAM的制造成本高,使得RDRAM的价格居高不下。同时由于奔腾4平台的成本相对较高,最终导致RDRAM被DDR SDRAM替代
DDR SDRAM (Double Data Rate SDRAM)
DDR(Double Data Rate)SDRAM(双倍速率同步内存),原来的SDRAM被称为SDR SDRAM
SDR仅在时钟脉冲的上沿进行一次写或读操作,DDR内部有两个乒乓交替工作的存储体,还有2bit的预取缓冲,可在时钟上沿和下沿都进行一次对等的写或读操作,至少在理论上DDR的数据传输能力比同频率的SDR提高了一倍
DDR内存条的工作电压是2.5V,共有184线,金手指只有一个“缺口”
DDR工作频率有100/133/166/200/266MHz等。所谓双倍速率就是传输速率是工作频率的两倍,因此型号上所标识的是工作频率×2,即标称为DDR200、266、333、400和533,容量128/256/512MB等,主要用于P4级别的64位PC机
DDR内存条最初只有单通道,后来出现了支持双通芯片组,让内存的带宽直接翻倍,两根DDR-400内存条组成双通道,可以满足FBS800MHz的奔腾4处理器
DDR2 SDRAM
DDR2内存采用了4bit预读取(类似于快餐店里的备餐)技术,数据通过四条线路串行传输到I/O缓存区,使工作频率为100MHz的内存可实现400MHz的数据传输频率,因此称为DDR2-400,其带宽为(100MHz×4)×(64b/8b)=3200MB/s=3.2GB/s
数据预取以及多路串行传送,实际数据传送速率相同时的功耗更低;或同样的功耗下拥有更快的传送速率
DDR3 SDRAM
在DDR2基础进一步改进为8位预取,如100MHz的DDR3-800,带宽可达到: (100MHz×8)×(64b/8b)=6.4GB/s
预存比特数 vs 数据传送速率
其他特性
DDR4 SDRAM
DDR4是目前的主流,相比DDR2和DDR3有以下几项关键技术
Bank Group架构。使用2个或4个可选择的采用8n预取的Bank Group分组,每个Bank Group可以独立读写数据,如果是2个独立的Bank Group,相当于将内存预取值提高到了16n,如果是4个独立的Bank Group,则等效的预取值提高到了32n。
点到点传输。每个通道只连接一根内存条,消除了共享传输带来的性能瓶颈。
3D堆叠。在散热允许情况下,采用3D堆叠封装技术,使得单根内存条的容量从目前8GB提高到64GB。
其他技术变化
DDR5 SDRAM
主导内存标准制定的JEDEC(Joint Electron Device Engineering Council)规范组织,虽然之前宣布2018年正式发布DDR5标准,但实际上并没有,最终规范要到2020年才能完成。
DDR5主要特性是芯片容量,而不仅仅是更高的性能和更低的功耗。
此外,DDR5将具有改进的命令总线效率,更好的刷新方案以及增加的存储体,以获得额外的性能,提高总线效率
小结:
完整的四级结构
存储系统的基本特点
存在的问题
虚拟存储器的意义
特点
提供三个重要能力
解决三个根本需求:
虚拟存储器简介
虚拟存储器思想的诞生
虚拟存储器的基本思路
Cache与虚拟内存的异同
相同点:
不同点
虚拟地址与物理地址
概念
虚拟地址与物理地址之间需要映射
虚拟存储器地址映射方式
虚拟存储器利用大容量的外存来扩充内存,产生一个比实际内存空间大得多的、逻辑的虚拟内存空间,简称虚存
PageFile.Sys
。虚拟内存有时候也被称为是“页面文件”就是从这个文件的文件名中来的一般情况下,程序代码是保存在虚存。但是当代码需要运行的时候就必须将其装入内存,要将虚存地址以一定的规则转换成物理地址
虚存的地址变换,分三种:段式,页式,段页式
段式虚拟存储器
简介
段式存储管理是一种把主存按段分配的存储管理方式,主存与辅存间信息传送单位是不定长的段
地址变换
段式存储管理的优点
段式存储管理的缺点
页式虚拟存储器
简介
页式存储管理是一种把主存按页分配的存储管理方式,主存与辅存间信息传送单位是定长的页
地址映射
地址转换
特点
段页式虚拟存储器
简介
地址转换
Cache的意义
CPU与DRAM的发展现状
CPU和主存储器的速度总是有差距,CPU的发展一直是提高速度为核心目标;主存的发展则一直以提高容量为核心目标
程序访问的局部性原理
程序在一定时间段内通常只访问较小的地址空间
两种局部性:时间局部性和空间局部性
在主存与CPU之间设置Cache
思想:根据程序访问的时空局部性,把经常访问的代码和数据保存到高速缓冲存储器(Cache)中,把不常访问的代码和数据保存到大容量的相对低速DRAM中,尽量减少CPU访问DRAM的概率,在保证系统性能的前提下,降低存储器系统的实现代价
实现:Cache设置在CPU与主存储器之间,通常采用存取速度快并且无需刷新的SRAM来实现
在主存和CPU之间设置了Cache之后,如果当前正在执行的程序和数据存放在Cache中,则当程序运行时不必再从主存储器读取指令和数据,而只需访问Cache即可
使用场合:CPU与主存之间、显示系统、硬盘和光驱,以及网络通讯中
Cache的基本运行原理
当CPU访问主存时,给出的地址同时送往Cache。首先检查Cache,如果要访问的数据已经在Cache中,则CPU就能很快完成访问,这种情况称为Cache“命中”(Cache hit)
否则,CPU就必须从主存中提取数据,称为Cache“未命中”(Cache miss)
如果组织的好,那么程序所用的大部分的数据都可在Cache中找到。Cache的“命中率”(hit rate)和Cache的容量大小、控制算法和组织方式等有关,当然还和所运行的程序有关
Cache的“命中率”通常应在90%以上。某些组织较好的Cache系统,命中率可达95%(例如早期IBM 360可达99%)
Cache的组织方式
Cache的基本单元称为行或区块,其中包括:
在Cache系统中,主存是以区块为单位映象到Cache中。以CPU读取一个字节的数据为例,如果所需字节不在Cache中,在CPU从内存中读取数据的同时,Cache控制器将把该字节所在的整个区块从主存复制到Cache
Cache的管理
Cache管理的基本问题
Cache中存放近期需要重复运行的指令数据,形成主存储器内容的副本。CPU首先从副本中读取数据,只有Cache中没有所需的数据时或Cache中已满时,才直接访问内存。从而提高CPU对存储器的访问速度。
Cache和主存储器一起构成一级存储器。高速缓冲存储器和主存储器之间信息的调度和传送由硬件自动进行。
高速缓冲存储器Cache,需要解决两个问题:一是主存地址与缓存地址的映像及转换;二是按一定原则对Cache的内容进行替换。
计算机的Cache系统基本组成
Cache的基本结构
Cache由Cache Tag、Tag存储体和Cache控制器三部分组成
Cache Tag主要用来记录Cache存储体中数据的位置,判断Cache内数据是否命中
Cache存储体主要用来存储片外数据,方便处理器直接调用
Cache控制器由主存地址寄存器、Cache地址寄存器,主存-Cache地址变换部件及替换控制部件等四部件组成。Cache控制器控制整个Cache的具体工作,决定了Cache的工作效率
注意:地址寄存器中存放的信息不是直接地址,要得到地址信息必须通过地址变换部件按地址映射方式进行变换
Cache控制器的控制行为
Cache控制器控制主存和Cache间的数据传输
Cache控制的特点
影响命中率的因素
影响命中率的因素:Cache容量、存储单元组数目和组大小、地址映射方案、联想比较策略、数据替换算法、写操作处理方法、程序本身特性等
命中率的计算:
地址映射(或称映像):主存单元的数据在被复制到Cache中的同时,该主存单元的地址,在经过某种函数关系处理后也被写进Tag,这一过程被称为Cache的地址映像
地址变换:CPU读写数据时,把访问主存地址变换为访问Cache的地址,这一过程被叫做Cache的地址变换。再根据地址变换结果对Cache进行检查
按照主存和Cache之间的映像关系,Cache的组织方式分为以下几种:
全相联映射
简介
地址变换
主存地址到Cache地址的转换是通过查找块表完成
CPU的访主存地址:M为主存的块号,W为块内的字号
CPU访Cache的地址:C为Cache的块号,W为块内的字号
当一个主存块调入Cache中时,会在一个存储主存块号Mj和Cache块号Ci映射关系的块表中进行登记。 CPU访问内存时:
特点
直接相联映射
简介
直接相联映射(Direct-Mapped)方式是将主存空间按照Cache的大小划分为若干页,也称为区,页内分块。主存储器中一块只能映射到Cache的一个特定的块中
地址变换
CPU的访主存地址为如下形式:T为标志号,C为Cache的块号,W为块内的字号。在这里,原主存的块号M实际上被分成了两个字段:T和C,其中C用于指出主存的块可以映射的Cache的块(即对2C求余后的余数部分),而对于余数相同的不同的主存块来讲,整除2C后的商(即T)部分则不相同。在直接相联映射方式下,标志号T是随Cache的每个块一起存储的
CPU送来一个访存地址时
特点:
组相联映射
简介
地址变换
主存划分为2s页,每页2u块,Cache分成2u组,每组包含2v块
Cache的块号C=u+v,而主存的块号M=s+u
主存块被调入Cache时,同时将其地址的前s位写入块表的s字段
CPU访问存储器时
特点
读取结构
贯穿读出(Look Through)
旁路读出(Look Aside)
写入更新策略
当CPU对Cache数据做了修改之后,应修改主存相应位置内容
写通方式(Write Through)
写回方式(Write Back)
替换策略
Cache一个块对应主存多个块,块大小相同。主存数据块装入Cache时,如果相应位置被其他块占用,则必须替换掉旧块,以新块填充
随机(Random)替换策略
最不经常使用(Least Frequently Used,LFU)替换策略
先进先出(FIFO)替换策略
近期最少使用(Least Recently Used,LRU)替换策略
Cache脱靶的原因
分块太小
程序开始执行时,主存块逐步复制进Cache,因此容易脱靶,需经过一段时间后Cache才装满。首次执行产生脱靶的次数,与分块大小有关,块越大,不命中次数就越小
容量太小
不能将所需指令和数据都调入Cache,因此频繁的替换,导致CPU访问慢速主存次数增多
替换进Cache的主存块过大或过多
提高Cache性能的方法
增大Cache容量来降低不命中率
Cache太小致命中率太低,过大改善不明显。一般选Cache与内存容量比4:1000,命中率90%以上。每块取4~8字节(或字)较好
通过结构设计减少不命中次数
指令、数据分开存储,存取比例不一样,可将两类Cache分开,并采用二级、三级Cache结构
通过预取技术提高命中率
预测将要访问的指令和数据,提前将下条要执行指令取入Cache,提高CPU取指令的速度
CPU总线的负载能力
CPU通过总线直接驱动负载的能力有限,应根据需要连接的存储器芯片参数,考虑在总线上增加缓冲器或驱动器,增大CPU的负载能力
CPU时序与存储器存取速度间的配合
CPU要对存储器频繁读/写,选芯片时要考虑其存取速度能否与CPU读/写时序匹配
存储器的地址分配和片选
需要为存储器分配地址范围。由于每块芯片存储容量有限,一个存储器系统可能是由多块芯片组成,要重点考虑容量的扩充方案和片选信号的形成
控制信号的连接
CPU提供的存储器控制信号,如CS#、OE#、WE#等,应与存储器的相关引脚正确连接,才能实现读/写等控制功能
位扩展
在存储器芯片字数不变的前提下,进行数据的位数扩展
举例:1M×1位的芯片扩展为1M×8位的RAM并与CPU总线连接
字扩展
在存储器芯片的位数满足的前提下,进行字数扩展
举例:存储器芯片为256K×8位,采用4片进行字扩展为1M×8位的RAM,并与CPU总线连接
复合扩展
在位长和字数均不足时,采用复合扩展方式
举例:如将256K×1位的芯片扩展为1M×8位的存储器系统
存储结构特点:
嵌入式微处理器内置小容量NOR Flash内存和小容量的SRAM
嵌入式系统的存储器扩展
NOR Flash内存的存储器扩展设计
HY29LV160 NOR Flash芯片
ARM微处理器对NOR Flash的访问不需要其他任何软件的设置,系统在上电复位后,从NOR Flash的0X0地址开始执行第1条指令,即开始执行NOR Flash存储器的启动代码
NAND Flash内存的存储器接口设计
NAND Flash与嵌入式微处理器的连接,通过NAND Flash控制器实现
NAND Flash 是以存储外设方式存在,故ARM微处理器对NAND Flash的访问,是通过NAND Flash控制器接口进行
SDRAM的存储器扩展设计
SDRAM作为同步动态存储器,是利用同一个时钟信号同步控制DRAM的地址、数据和控制信号。从而保持SDRAM的时钟频率与系统前端时钟频率,保证CPU对存储器的访问速度与处理速度一致
嵌入式系统采用SDRAM或者SRAM作为系统的主存储器器,用于保存程序运行过程中的实时数据或者存储从外存装入的程序或数据
在SDRAM与ARM微处理器进行电路连接时,要根据实际,对扩展主存容量、芯片粒数、单元数、芯片位宽与Bank之间的关系进行配置
ARM微处理器SDRAM控制器Bank地址配置:
HY57V561620T SDRAM的引脚定义:
ARM微处理器与HY57V561620T SDRAM的连接示意图:
HY57V561620T的存储器组织为4M×16位×4Banks,从而构成32MB的总存储容量
计算机不同部件间,如从硬盘到处理器、从CPU到内存,从内存到显卡,都需要进行数据传输。总线提供了一种经济的思路:把不同计算机部件均接到一个公共的通道上
总线的作用
总线:计算机系统内部或者计算机系统之间传输信息的公共信道。总线是由一些电导体的互连组成,其具体形式可以是印刷线路、各种连接器、多路电缆等
系统早期的互联方式——分散连接
现代的系统互连方式——总线连接
接口的作用
计算机数据处理过程中存在大量数据交换
外部设备种类繁多、差异大
需要中间环节来协调
总线与接口的区别与联系
电路单元之间的硬件电路
点到点连接和多点互联
有时候并不做严格区分
总线的意义
考虑一个具有个电路模块的计算机系统,若模块间两两采用直接连接的方式,则实现所有模块互联共需要组连接线
总线的基本特性
总线的两个基本特性:共享、分时
共享:当多个部件连接在同一组总线上,各部件之间相互交换的信息都可以通过这组总线传送
分时:是指任意时刻只能有一个设备向总线发送信息,但是允许多个部件同时从总线接受相同信息(广播)
总线的主要性能指标
总线频率
总线宽度
总线带宽
又称总线最大数据传输速率,单位MB/s。影响带宽的因素有总线宽度、总线频率等,并行总线的带宽为:
带宽(MB/s)=总线宽度/8×总线频率
例:求33.3MHz@32位总线的带宽
总线带宽=32b/8×33.3 MHz =133.2MB/s
并行总线一次能传输多位数据,但信号间存在干扰,频率越高,位宽越大,干扰越严重,带宽难于提高
串行总线可通过较高的总线频率获得较大的总线带宽。此外,为弥补一次只能传送一位数据的不足,串行总线常用多条管线传输,其带宽为:
带宽=总线频率×管线数
同步方式
总线复用
在一条线路上,不同的时刻传送不同的内容,例如某一时刻传输地址,另一时刻传输数据或命令信号,以减少总线的信号线数量,并提高信号线的利用率
信号线数
数据、地址、控制和电源总线数的总和。信号线数量与总线的性能不成正比
总线控制方式
包括并发工作、自动配置、仲裁方式、逻辑方式、计数方式等
寻址能力
指地址总线的位数及所能直接寻址的存储器空间大小
总线的定时协议
为使源与目的同步,需要有信息传送的时间协议。分为同步总线定时、异步总线定时、半同步总线定时
负载能力
指总线上最多能连接的器件数,一般指总线上的扩展槽的个数
总线特性
按物理接口分类:电缆式、主板式、背板式
按总线信号传输类型分类:数据总线、地址总线、控制总线、电源总线
按控制特性分类:同步总线、异步总线、半同步总线
按通信方式分类:串行总线和并行总线
按总线位置分类
片上总线的由来:片上系统SoC的发展,采用片上总线来描述芯片内部使用的总线(实际涵盖传统内总线及外总线的定义)
总线的层次结构:
外总线的分层结构:
总线按功能分类
地址总线AB:专门用来传送地址
数据总线DB:用于传送数据信息
双向三态
数据总线的位数(宽度)通常与微处理的字长相一致
带宽(B/s)=总线宽度/8X总线频率
控制总线CB:用于传输完成各项操作所需要的控制信号
按数据传输方式分类
串行传输:串行总线
并行传输:并行总线
过去,内总线一般为并行总线,系统外总线多采用串行总线
按时序控制方式分类
异步总线
同步总线
按时分复用方式分类
非复用
复用
某些信号线在不同时段传输不同的数据,目的为了减少信号线的数量
区分服用信号的方法:
约定。例如PCI总线上的AD[31:0]是32根地址和数据复用的信号线,按照数据传送的规律,首先传送地址,然后再传送数据
增加专用信号线加以标识,如下图所示:
单总线
双总线:面向CPU的双总线结构
双总线:面向存储器的双总线结构
典型的三总线结构
注意:任意时刻只有一套总线能够使用,主线总线与DMA总线不能同时访问主存
四总线结构
总线上的设备
总线上的设备一般分为总线主设备(主控模块)和总线从设备(从属模块)。常把总线主设备称作总线主机,把总线从设备称作总线从机
总线主设备是指具有控制总线能力的模块,在获得总线控制权之后能启动数据的传输
从设备能够对总线上的数据请求做出响应,但本身不具备总线控制能力
总线仲裁(bus arbitration)是在多总线主设备的环境中提出来的
总线仲裁
总线的使用权分配即总线判优控制,也称为总线使用权仲裁。当有多个主设备同时申请总线时,按一定的优先等级顺序,判定哪个主设备能优先使用总线
两种仲裁方式:
串行仲裁
串行仲裁是最为常见的链式仲裁(“菊花链仲裁”)
仲裁过程:
特点:
举例:
并行仲裁
并行仲裁又称为“独立请求式仲裁”
仲裁过程:
独立请求方式的工作原理:
特点:
混合仲裁
混合仲裁又叫多级仲裁
两级混合仲裁的结构:
仲裁过程:
特点:兼具有串行仲裁和并行仲裁的优点,既有较好的灵活性、可扩充性,又可容纳较多的设备而结构也不会过于复杂,且具有较快的响应速度
分布式仲裁方式中,每个设备模块都包含总线访问的控制逻辑,这些设备模块共同作用,分享总线
以自举分布式的总线仲裁为例:
假定模块1~4通过BR1~4进行自举分布式仲裁。其中BR1为总线忙信号,正在使用总线的模块应将BR1置为有效;BRi为模块i的总线请求信号线,只有在BR1无效时才能发总线请求。下图中设备1的优先级最低,设备4的优先级最高(主设备4输出,主设备1只能取回)
特点:使用多个请求线,不需要中心裁决器,每个设备独立地决定自己是否是最高优先级请求者
原理:分为申请期和裁决期
举例:NuBus(Macintoshi II中的底板式总线)和SCSI总线
计算机系统中,通过总线进行信息交换的过程称为总线操作
总线设备完成一次完整信息交换的时间称为总线周期(或总线传输周期)
在含多个主控制器的总线系统中,一个总线操作周期一般分为如下四个阶段:
总线时序是指总线操作过程中总线上各信号在时间顺序上的配合关系,即主从设备如何在时间上协调和配合,以实现可靠的寻址和数据传送
总线时序的分类:同步总线时序、半同步总线时序、异步总线时序、周期分裂式总线时序
总线上的数据传输由统一时标控制
时标通常由CPU的总线控制部件发出,送到总线上的所有部件;也可以由每个部件各自的时序发生器发出,但是必须由总线控制部件发出的时钟信号对它们进行同步
优点:模块间的配合简单一致
缺点:主从模块之间的时间配合属强制性同步,必须按速度最慢的部件来设计公共时钟
例1:写命令
传输周期为:
例2:读命令
传输周期为:
STD总线的读存储器时序
异步总线允许各模块速度的不一致性,提高了模块的适应性
异步总线中系统没有公用的时钟,主从模块之间通信时,采用应答方式进行联络和协调工作
根据问答信号之间的关系,异步总线时序可分成不互锁方式、半互锁方式和全互锁方式(又称握手方式)
主设备在发数据的同时发选通信号STB,从设备收到数据后应答ACK;主从模块之间增加两条握手应答线
不互锁方式
半互锁方式
全互锁方式(四边沿协议)
主从设备相互等待,传输可靠性最高
关于同步和异步通信方式的讨论
传输速度
可靠性
兼顾传输速度和通信的可靠性
半同步总线是对同步总线的一种优化,对于大多数速度较快的传送对象,均按照同步方式定时
对于系统所连接的少数速度较慢的设备,增加一条Ready/wait状态信号线,当慢速设备被访问时,可以利用这条信号线请求主模块延长传送周期
半同步总线提高了系统的适应性,但是速度依然偏慢
示例
在上述各种传输过程中,占用总线使用权的主设备以及被其选中的从设备,无论是否进行数据传输,始终占据着总线资源
若对读命令过程的进一步分析:在读命令传输周期中,除了申请总线这一阶段外,其余时间主要被用于如下三个方面的开销:
周期分裂总线的思想:将一个传输周期(或总线周期)分解成两个子周期(或称子阶段)
分裂式操作的技巧是总线设计中一种重要的思路:
简介
AMBA(Advanced Microcontroller Bus Architecture)总线是ARM公司研发的一种片上总线(on-chip bus)标准
AMBA设计独立于处理器和芯片制造工艺
AMBA拥有众多第三方支持
AMBA定义了三种不同的总线:
AMBA AHB | AMBA ASB | AMBA APB |
---|---|---|
高性能 流水线(pipelined)操作 多总线主机(multiplebusmasters) 突发传输(bursttransfers) 分裂式操作(splittransactions) | 高性能 流水线操作 多总线主机 | 低功耗 地址锁存和控制 接口简单 适合大多数外设 |
基于AMBA总线的系统:
一个基于AMBA2总线的微控制器系统如下:
在AMBA2中,AHB担当高性能系统的中枢总线。AHB支持处理器、片上存储器、片外存储器,以及低功耗外设单元之间的有效链接
AHB总线是支持多主机的总线,能支持高带宽、高时钟频率的数据传输操作
AHB系统要素
AHB主机(Master)
即总线的主控模块。总线主机能够通过提供地址和控制信息发起读写操作。任何时候只允许一个总线主机处于有效状态并能使用总线
AHB从机(Slave)
即总线的从属模块。从机在给定的地址空间范围内响应主机发起的读写操作。从机将成功、失败或等待的信号返回给有效的主机
AHB仲裁器(Arbiter)
确保每次只有一个总线主机被允许发起数据传输。AHB要求即便在单总线主机系统中也要实现仲裁器,且所有系统中只有一个仲裁器
AHB译码器(Decoder)
AHB译码器用来对每次传输进行地址译码,从而为从机提供选择信号。AHB要求实现集中式的译码器
基于多路选择器的AHB总线互联
AHB特点概述
支持突发传输(burst transfer)
启动一次AHB传输可以连续传输一个数据块
支持分裂式操作(split transaction)
寻址和数据传输子周期分离
单周期总线主机移交(single cycle bus master handover)
主机在时钟上升沿发出总线使用请求,仲裁器在时钟下降沿采样获得该请求,随即在下一个时钟上升沿更新总线允许信号。即:仲裁器在每个时钟周期都更新总线允许信号
单一时钟沿操作(single clock edge operation)
所有信号变化均发生在时钟上升沿,这利于芯片内集成更多的电路单元
非三态实现(non-tristate implementation)
可扩展至更宽的数据总线架构(64位或128位)
前缀 | 含义及示例 |
---|---|
T | 测试信号(与总线类型无关) |
H | AHB信号,如HREADY是表示AHB的数据传输完毕的信号,高电平有效 |
A | ASB信号,主机与仲裁器之间的单向信号 |
B | ASB信号,如BRESn为ASB复位信号,低电平有效 |
D | ASB信号,单向的ASB译码信号 |
P | APB信号,如PCLK表示APB使用的主时钟 |
所有的信号名均为大写字母,信号若为低电平有效,则信号名称的最后加小写字母n
信号名称 | 信号来源 | 用途说明 |
---|---|---|
HCLK 总线时钟 | 时钟源 | 为所有总线传输提供时基,所有信号时序都与HCLK的上升沿相关 |
HRESTn 复位 | 复位控制器 | 总线复位信号,用于复位系统和总线,低电平有效 |
HADDR[31:0] 地址总线 | 主机 | 32位系统地址总线 |
HTRANS[1:0] 传输类型 | 主机 | 主机表示当前传输的类型,可以是不连续、连续、空闲和忙(NONSEQUENTIAL,SEQUENTIAL,IDLE,BUSY) |
HWRITE 传输方向 | 主机 | 高电平时表示一个写传输,低电平时表示读传输 |
HSIZE[2:0] 传输大小 | 主机 | 表示传输的大小,可以是字节(8位)、半字(16位)或字(32位)等,协议允许的最大传输大小是1024位 |
HBURST[2:0] 突发类型 | 主机 | 表示传输是否组成了突发的一部分。支持4个、8个或16个节拍的突发传输,突发传输可以是增量或回环的 |
HPROT[3:0] 保护控制 | 主机 | 提供总线访问的附加信息,指示当前传输的安全保护级别 |
HWDATA[31:0] 写数据总线 | 主机 | 用来在写操作期间,从主机到从机传输数据。建议最小数据宽度为32位,在高带宽运行时可扩展 |
HSELx 从机选择 | 译码器 | 每个AHB从机都有自己独立的从机选择信号,并且用该信号来表示当前传输是否打算送给选中的从机。该信号是地址总线的组合译码 |
HRDATA[31:0] 读数据总线 | 从机 | 用来在读操作期间,由从机向主机传输数据。协议允许的数据宽度为:8、16、32、64、128、256、512、1024位 |
HREADY 传输完成 | 从机 | 当该信号为高电平时,表示总线上的传输已经完成。在扩展传输时该信号可能会被拉低 |
HRESP[1:0] 传输响应 | 从机 | 给传输状态提供了附加信息,提供四种不同的响应:OKAY、ERROR、RETRY和SPLIT |
信号名称 | 信号来源 | 用途说明 |
---|---|---|
HBUSREQx 总线请求 | 主机 | 从总线主机x传向总线仲裁器,用来表示该主机请求(控制)总线的信号。系统中每个总线主机都有一个HBUSREQx信号,最多16个总线主机 |
HLOCKx 锁定的传输 | 主机 | 当该信号为高时,表示主机请求锁定对总线的访问,并且在该信号为低之前,其他主机不应该被允许授予总线 |
HGRANTx 总线授予 | 仲裁器 | 该信号用来表示总线主机x目前是优先级最高的主机。当HREADY为高电平时,传输结束,地址控制信号的所有权发生改变。所以主机应在HREADY和HGRANTx都为高电平时,获得对总线的访问 |
HMASTER[3:0] 主机号 | 仲裁器 | 表示哪个总线主机正在执行传输,被支持突发传输的从机用来确定哪个主机正在尝试一次访问 |
HMASTLOCK 锁定顺序 | 仲裁器 | 表示当前主机正在执行一个锁定序列(sequence)的传输。该信号与HMASTER信号有相同时序 |
HSPLITx[15:0] 分离式传输请求 | 从机(支持分裂式操作) | 指示仲裁器,总线主机被允许重试一个分裂式操作。每位对应一个总线主机 |
信号后缀x表示模块x。如,HBUSREQx可能分别表示HBUSREQarm或HBUSREQdma
在一次AHB传输开始之前,总线主机必须先获得总线访问的授权
该授权过程由总线主机向仲裁器发出一个请求信号而发起,随后仲裁器指示主机何时被授权
获得授权的主机通过提供关于地址信号、传输方向、传输宽度和传输类型等控制信号发起一次AHB传输
单个数据简单传输
两个阶段:地址阶段和数据阶段
地址阶段仅持续一个时钟周期,用来传输地址和控制信息
数据阶段可持续一个或多个时钟周期,用来传输有效数据
主机写传输应关注HADDR[31:0]
和HWDATA[31:0]
;
主机读传输应关注HADDR[31:0]
和HRDATA[31:0]
传输过程:
HADDR[31:0]
及其他控制信号线)HRDATA[31:0]
上HRDATA[31:0]
上采样即可获得从机响应的数据AHB的流水线机制
地址信息和数据信息交叠的操作方式,被称为流水线机制
流水线分离:
2级流水线
周期分裂式时序
HSPLITx
通知仲裁器HSPLITx
后,知道从机当前不进行传输,则可以把总线的使用权出让给其他主机HSPLITx
发出重新启动传输的信号,仲裁器根据挂起操作主机的优先级决定何时再次分配总线使用权单个数据简单传输中插入等待状态
如果数据阶段持续一个时钟周期不足以完成数据的传输,从机可以通过HREADY
信号(拉为低电平)扩展数据周期(即插入等待周期)
传输过程:
HREADY
拉为低电平,插入等待周期HREADY
电平HRDATA[31:0]
获得从机响应的数据说明:
多个数据的传输
三次AHB传输分别需要传输的是地址A、地址B和地址C对应的数据
突发传输
突发传输就是一次传输过程传输一个数据块而不是单个数据。既然是传输一个数据块,就涉及到数据块的长度,数据块的地址递增方式等
用突发传输类型信号HBURST[2:0]标识:
HBURST[2:0] | 类型 | 类型的描述 |
---|---|---|
000 | SINGLE | 单次传输 |
001 | INCR | 未标识长度的地址递增式传输 |
010 | WRAP4 | 突发长度为4的地址循环增式传输 |
011 | INCR4 | 突发长度为4的地址顺序增式传输 |
100 | WRAP8 | 突发长度为8的地址循环增式传输 |
101 | INCR8 | 突发长度为8的地址顺序增式传输 |
110 | WRAP16 | 突发长度为16的地址循环增式传输 |
111 | INCR16 | 突发长度为16的地址顺序增式传输 |
突发传输的状态
HTRANS[1:0]
用来向从机指示突发传输过程中的不同状态,因而从机可知自身下一步的操作提示
HTRANS | 状态 | 状态含义描述 |
---|---|---|
00 | IDLE | 指示当前周期没有数据需要传输,当主机被授权使用总线,但是不需要传输时使用该状态 |
01 | BUSY | 指示主机正在进行突发传输,但是下一次数据传输不会马上发生。地址和控制信号线上的信号对应下一次即将发生的传输 |
10 | NONSEQ | NONSEQUENTIAL,指示当前传输是一次突发传输过程或单次传输的第一次传输。地址和控制信号线上的信号与前一次传输无关 |
11 | SEQ | SEQUENTIAL,一次突发传输过程中非第一次的传输。地址和信号线上的信号对应上一个刚完成的传输 |
WRAP4突发传输时序
WRAP4,拟传输数据的地址在16字节的边界处发生回转,0x38、0x3C → 0x30、0x34
整个传输过程共进行4次数据传输,插入1个等待周期T2
HADDR[31:0]
上,T1周期传输状态指示信号HTRANS[1:0]
为NONSEQ,指示拟传输的数据是突发传输中的第1次HWDATA[31:0]
上INCR4突发传输时序
INCR4,4个传输数据的地址变化是递增的(0x38,0x3C,0x40,0x44),没有在16字节边界处发生回转
AMBA规范中定义:突发传输过程中拟传输的数据块不能跨越1kB的边界
地址译码和从机选择信号
AHB总线通过一组多路选择器实现主从设备的互连
从机选择信号HSELx
:AHB总线上的所有从机使用一个中央地址译码器提供从机选择信号HSELx
。选择信号是高位地址信号的组合译码结果。从机x
在HSELx
和HREADY
有效的情况下,对地址和控制信号进行采样,从而获得地址和相关的控制信息
能够分配给单个从机的最小地址空间是1KB。所有总线主机不允许执行超过1KB的地址边界的增量传输,因此确保了一个突发传输不会超过地址译码的边界
总线允许信号与主机号的生成
主线允许信号HGRANTx
:由于采用了一个集中式的译码器,每个主机可以在需要的时候随即驱动自身的地址信号,而无须等待总线允许信号HGRANTx
对于主机而言,HGRANTx
信号是自身获得总线控制权的指示,同时,通过HGRANTx
可知自己所驱动的地址是否已经被从机采样
集中式的译码器根据各个主机的总线使用请求产生总线允许信号HGRANTx
,并在仲裁器的控制下生成主机号HMASTER[3:0]
,HMASTER[3:0]
指示地址和控制多路选择器把主机的地址总线与对应从机的地址总线连接
AMBA2中AHB的仲裁器接口信号
信号后缀x表示模块x,每个总线主机都有一个HBUSREQx
信号,最多支持16个总线主机
仲裁机制是为了保证在同一时刻,只有一个主机能够控制总线。仲裁器通过检测请求的优先级等信息确定哪个主机能够获取总线控制权。同时,仲裁器也响应从机分离式传输的请求
无等待状态的仲裁授予
基本步骤:
HBUSREQx
信号请求对总线的使用需求,如果主机x
希望使用总线的时候能够锁定总线资源,则同时需要发出HLOCKx
信号HGRANTx
信号指示主机x
获得了总线使用权HREADY
有效,则不需要等待,仲裁器通过HMASTER[3:0]
以指示当前获得总线使用权的主机号HREADY
有效的前提下的仲裁授予过程:
HGRANTx
有效HMASTER[3:0]
指示了当前获得总线使用权的主机号,同时获取了总线控制权的主机将地址A驱动到地址总线HADDR[31:0]
HWDATA[31:0]
有等待状态的仲裁授予
如果HGRANTx
有效,HREADY
为无效状态(低电平),则需要插入等待周期
有等待状态的仲裁授予过程:
HREADY
无效,插入了一个等待周期HREADY
有效,仲裁器开始驱动HMASTER[3:0]
指示了当前获得总线使用权的主机号,同时,获取了总线控制权的主机将地址A驱动到地址总线HADDR[31:0]
上HREADY
无效,故获得总线使用权的主机又等待了一个周期HWDATA[31:0]
上总线控制权在两个主机之间移交
总线的控制权包括地址总线控制权和数据总线控制权,数据总线控制权滞后于地址总线
当一次传输完成后(通过HREADY
信号高电平予以指示),随后拥有地址总线控制权的主机接管数据总线
主机2控制地址总线的时候,主机1仍在控制数据总线
突发传输后的总线移交
总线控制权移交发生在一次突发传输的末尾
仲裁器在倒数第二个地址被采样后改变总线允许信号HGRANTx
新得总线允许信号HGRANTx
将与最后一个地址在相同时刻被采样
复位信号HRESETn
:
HRESETn
是AHB中定义的唯一一个低电平有效的信号,该信号将引起所有总线上电路单元进行复位操作HRESETn
的产生可以与时钟信号HCLK
异步,但是复位信号的撤除是与HCLK
同步的,需要与HCLK
上升沿对齐HTRANS[1:0]
指示处于IDLE
状态主机接口:
HREADY
和HGRANTx
都为高电平时,获得对总线的访问x
通过HBUSREQx
向总线仲裁器请求使用总线,通过HLOCKx
告知其他主机不应该被允许授予总线HMASTER[3:0]
、HMASTLOCK
和HSPLIT[15:0]
用于支持“SPLIT”传输模式
SPILT传输
HSPLITx[15:0]
发出启动SPLIT传输的信号。仲裁器检测到HSPLITx
后,知道从机当前不进行传输,则可以把总线的使用权出让给其他主机HSPLITx[15:0]
发出重新启动传输的信号,仲裁器根据挂起操作主机的优先级决定何时再次分配总线使用权。当主机获得总线使用权后,重新发送地址、控制等信息,继续刚才挂起的传输操作HMASTER[3:0]
,用来指示哪个主机正在使用总线。任何一个从机如果要发出SPLIT信号,需要根据HMASTER[3:0]
信号决定HSPLITx[15:0]
中哪个位要置1.HSPLITx
有16耕信号线,意味着最多支持16个不同主机来源的传输采用SPLIT分离机制从设计思想上看,ASB、APB可视为AHB功能的一个子集;AXI可视为AHB的升级版本;AXI之后的其他版本针对高性能、智能手机等不同场景改进设计
AHB总线分离了一个总线周期的地址阶段和数据阶段,更便于实现在现代总线中常用的Pipelining和Split技术
AXI总线则进一步分离了总线的通道,将AHB的单通道分解为5个独立的通道:读地址通道(Read Address)、读数据通道(Read Data)、写地址(Write Address)通道、写数据(Write Data)通道、写响应(Write Response)通道,进一步加速了对存储器的读写访问
AXI、AHB和APB的对比:
总线 | AXI | AHB | APB |
---|---|---|---|
总线宽度 | 8,16,...,1024 | 32,64,128,256 | 8,16,32 |
地址宽度 | 32 | 32 | 32 |
通道特性 | 读写地址通道 读写通道均独立 | 读写地址通道共用 读写数据通道独立 | 读写地址通道共用 读写数据通道独立 不支持读写并行操作 |
体系结构 | 多主/从设备 仲裁机制 | 多主/从设备 仲裁机制 | 单主设备(桥)/多从设备 无仲裁 |
数据协议 | 支持流水线 支持分裂式操作 支持突发传输 支持乱序访问 字节/半字/字 大小端对齐 非对齐操作 | 支持流水线 支持分裂式操作 支持突发传输 支持乱序访问 字节/半字/字 大小端对齐 不支持非对齐操作 | 一次读/写传输占两个时钟周期 不支持突发传输 |
传输方式 | 支持读写并行操作 | 支持读写并行操作 | 不支持读写并行操作 |
时序 | 同步 | 同步 | 同步 |
互联 | 多路 | 多路 | 无定义 |
PCI总线
PCI(Peripheral Component Interconnect)外部设备互连总线,是一种高性能的局部总线
PCI最早由Intel的IAL实验室提出,在IBM兼容PC上得到应用,后得到Compaq、HP和DEC等公司的响应,成立PCI-SIG
PC领域:逐渐被PCI Express总线替代;工业控制计算机领域:Compact PCI仍在广泛使用
PCI → PCI-X
最初的PCI标准中总线时钟(总线频率)为33MHz,数据线宽度为32位,可扩充到64位,数据传输速率可达132MB/s~264MB/s。后期的PCI版本64位并行数据传送,总线时钟支持33/66MHz,能够达到最高528MB/s的数据传输速率
在PCI的基础上,进一步提出PCI-X规范。PCI-X 553峰值速率是4.2GB/s
PCI总线结构
PCI总线的三类设备:PCI主设备、PCI从设备和桥设备
PCI总线在高速处理器与其他低速设备之间架起了一座“桥梁”。使计算机结构成为基于PCI总线的三级总线结构
PCI总线是一种树型结构,PCI总线上可以挂接PCI设备和PCI桥片,PCI总线上只允许有一个PCI主设备,其他的均为PCI从设备,而且读写操作只能在主从设备之间进行,从设备之间的数据交换需要通过主设备中转
PCI系统框图
#0总线挂接了主存储器、辅助存储器、多媒体设备等不同外设
#1总线通过PCI-to-PCI桥设备挂接到#0总线
PCI Express(简称PCI-E或PCIe)
Intel公司提出用新一代的技术取代PCI总线和多种芯片的内部连接,称之为第三代I/O总线
包括Intel、AMD、DELL、IBM在内的20多家业界主导公司开始起草新技术的规范,并在2002年完成,对其正式命名为PCI Express
标准由PCI特别兴趣工作组(PCI Special Interest Group,PCI-SIG)维护和升级
相比于PCI,PCI-E最大的改变是由并行改为串行,使用差分信号传输
PCI-E的通道
目前高速接口均为串行标准
并行数据线多,CLK不能高
PCI-E点对点串行连接拓扑结构
PCI Express总线是一种点对点串行连接的设备连接方式,各个设备之间并发的数据传输互不影响。PCIe系统包括Root complex、Switch、PCIebrige、Endpoint四大类设备
PCI-E不同版本的传输速率
USB
USB(universal serial bus),通用串行总线,是一种外部总线标准。用于规范电脑与外部设备的连接和通讯,是应用在PC领域的接口技术
USB接口支持设备的即插即用和热插拔功能
USB是在1994年底由由Compaq、Digital、BM、Intel,Microsoft、NEC和NothernTelecom7家公司联合提出的
在USB1.0/USB2.0中,“D+”和“D-”组成一对差分信号线用于数据传输,VBUS和GND对应5V电源和地
USB3.0后,又增加了两对差分信号线以提供更高速的数据传输
USB的机械接口
USB不同版本
以8051为核心的嵌入式控制器的总线
8051是一种八位单芯片微控制器,属于MCS-51单芯片的一种,由Intel于1981年设计
以Cortex-M3为核心的嵌入式控制器的总线
基于8086的初期PC系统总线
x86架构PC早期基于前端总线的多总线结构
CPU通过前端总线FSB(F ro n tSideBus)与存储器和外设进行数据交互,计算机主板上的北桥(Northbridge)芯片负责联系内存、显卡等数据吞吐量最大的部件,并和南桥芯片(S o u t hbridge)连接。CPU就是通过前端总线FSB连接到北桥芯片,进而通过北桥芯片和内存、显卡交换数据
如今x86架构PC的PCH控制总线结构
2009年,Intel推出的单芯片设计的南北桥芯片整合方案。这颗主控芯片既不叫北桥,也不叫南桥,而是称作“Platform Controller Hub”芯片。PCH主要负责PCI-E和I/O设备的管理,它实际上仅提供南桥的功能(此时处理器已经整合北桥功能)
第十代智能英特尔® 酷睿™
CPU与存储器交换信息——数据格式和存取速度基本匹配
CPU与外设交换信息——由于外设的多样性
因此CPU必须经过中间电路再与外设相连,这部分电路被称为I/O接口电路
完整的I/O接口不仅包括外部设备与CPU或计算机之间的硬件电路,也包括相应的驱动程序
PC机系统板的可编程接口芯片、I/O总线槽的电路板、适配器/连接器都是接口电路
设置数据缓冲解决速度不匹配问题
设置电平转换电路解决电平不一致问题
设置信息转换逻辑满足各自格式要求
设置时序控制电路同步CPU和外设的工作
提供地址译码电路
提供I/O控制、读/写控制及中断控制等逻辑
按数据传输方式
可分为串行接口和并行接口
串行接口 vs 并行接口
按时序控制方式分类
同步接口
异步接口
按主机访问I/O设备的控制方式分类
程序查询接口
中断接口
DMA接口
其他分类
如按数据流方向可分为单工、半双工、全双工
接口设计的目的是为了协调上述微处理器与外设之间的不一致,用来实现速率匹配、缓冲、数据格式的转换和电平的转换等功能
依据不同外设的特点,形成了很多典型的接口设计,这些全球通用的接口设计方案往往以工业界公认的规范(Specification)形式出现
输入/输出接口电路
输入/输出接口电路的功能隶属于通常意义的物理层功能。规定了为传输数据所需要的物理链路创建、维持、拆除,而提供具有机械的、电子的、功能的和规范的特性
I/O接口标准的链路层功能
在一些输入/输出接口的标准定义中,除了物理层功能,也纳入了数据块格式、数据块检验方式等链路层功能(OSI模型的第二层)
I/O端口
I/O端口指I/O接口电路中的各类寄存器
CPU与外设通信时,主要传送数据信息、状态信息和控制信息
在接口电路中,这些信息分别进入不同寄存器,CPU也是通过地址对这些寄存器进行寻址。为了与内存单元及CPU内部寄存器相区别,通常将这些寄存器和它们的控制逻辑统称为I/O端口
在一般接口电路中都要设置以下几种端口:数据端口、状态端口、命令/控制端口。此外还有中断控制逻辑,负责中断请求信号的建立与撤销
端口寄存器
读信号用以指示数据从I/O传输到CPU
写信号用以指示数据从CPU传输到I/O接口
高位地址生成片选信号,选择当前接口
低位地址连接外设片内地址线,选择内部端口
数据端口
状态端口
指示外设的当前状态。状态口通常具有以下几个常见的状态位,以反映外设的工作状态
准备就绪位(Ready)
忙碌位(Busy)
错误位(Error)
命令端口
I/O端口的编址方法
为了让CPU能够访问这些I/O端口,每个I/O端口都需要有自己的端口地址(或端口号)
处理器通过端口地址可对各个端口寻址访问
I/O端口有两种编址方式:独立编址和统一编址
I/O端口统一编址
I/O端口统一编址也称为内存映像编址(memory mapped I/O addressing)方式
将外设接口中的I/O寄存器(即I/O端口)视为主存的存储单元,每个端口占用一个存储单元的地址,把主存地址的一部分划出来用作I/O地址空间
所有访存指令均可用来访问I/O端口,不用设置专门的I/O指令
I/O端口独立编址
I/O端口独立编址又称分离编址(Isolated I/O Addressing)
存储器和I/O端口分开编址,即存储器和I/O端口的地址空间相互独立,I/O端口编址不占用存储空间,使用专门的IN/OUT
指令来访问I/O端口
统一编址 vs 独立编址
独立编址:
优点:
缺点:
统一编址:
优点:
缺点:
外设的多样性使外设极其接口电路的差异极大,故而需要多种CPU与外设接口交换信息的方式。常用的数据传送方式包括:
程序控制方式(软件),数据传送在程序控制下完成
中断方式(软件)
DMA方式(硬件)
通道处理机方式(I/O Processor),专用I/O处理器,如Intel 8089
也称为同步传送方式,主要用于对简单外设进行操作,所需的硬件和软件都较少
特点
I/O接口电路
三态缓冲器:
三态输出受使能输出端的控制,当使能输出有效时,器件实现正常逻辑状态输出;当使能输入无效时,输出处于高阻状态,相当于与所连电路断开
作用:
输出使用一个锁存器
也称为异步查询传送方式
有一些外设,处理器访问时需要关心外设的状态,只有状态许可方可访问外设:
特点:
输出:CPU对外设查询“BUSY?”,不忙才输出,否则继续查询
输入:CPU对外设查询“READY?”,准备好才读入,否则继续查询
接口特点:
对外设的要求:提供状态口和数据口
在有多个外设的系统中,CPU的查询顺序由外设的优先级确定
查询流程
I/O接口电路
为了实现状态的查询,接口电路中既要有数据端口,又要有状态端口
特点
优点:
采用中断方式后,仅在需要进行I/O传送时外设才向CPU发中断请求
CPU在中断服务程序中完成CPU和外设之间的数据交换
I/O接口电路
中断的概念
定义
中断源
为了区分源自CPU的内、外的中断源,早期的资料中习惯上把来自CPU外部的外中断称作中断(Interrupt),而把来自CPU内部的内中断称作陷阱(Trap)
如今的微处理器芯片则习惯用异常处理(Exception Handling)机制来描述过去CPU设计中的中断技术
典型计算机系统中的中断源
通常计算机系统的中断处理模块可以管理多个中断源并处理多种不同类型的中断。为了能够识别不同的中断源,会对中断源进行命名或编号,这个编号被称为中断类型码或中断类型号
中断向量
断点和现场
断点:指被中断的主程序下一条待执行指令在存储器中的地址,也就是中断返回时的程序地址
现场:指中断发生时原主程序的运行状态,一般指系统标志(状态)寄存器和其他相关寄存器中的内容
中断处理过程
计算机系统中,中断的整个过程分为:中断响应、中断处理和中断返回等三个阶段
上图位8086 CPU的中断处理过程
注意:
优先级、嵌套
中断优先级
中断嵌套
中断屏蔽
CPU通过硬件电路和软件设置,对中断源产生的中断请求能否到达CPU的硬件引脚进行控制
中断优先级管理
软件管理(软件查询)
中断优先权编码电路(硬件排序)
任一外设对应的中断请求位和中断允许位同时为“1”时,即可产生中断请求信号
在两种情况下该中断请求信号能传送至INTR引脚:
编码器每位输入线的有效电平都对应一个编码,在多位输入线有效时编码器只输出优先权最高的编码
优先权寄存器中记录的是CPU当前正在处理的中断的编码
若A>B,比较器输出“1”,可以产生中断嵌套
“优先权失效”信号用于一种名为特殊屏蔽中断方式,该方式所有中断源没有优先级之分
菊花链式优先权排队电路(硬件排序)
每个中断源接口电路中设置一个逻辑电路,组成一个daisy chain,菊花链
CPU送出中断响应信号后,若设备1无中断请求,则与门A1关门,A2开门,中断响应信号继续向下一级传送
若设备2有中断请求,则与门B1开门,中断响应信号送至设备2,同时B2关门,中断响应信号不再向下传送
设备接入菊花链的顺序就确定了设备的中断优先级别
对链的长度有限制
中断控制方式的接口电路(以输入为例)
当外设准备好输入数据后发出选通信号,数据进入锁存器中,并同时将中断请求触发器置“1”。如果中断屏蔽触发器允许中断(Q1输出为“1”),与门被打开,因而可以产生中断请求信号INT
INTA#为中断响应信号,INTA#到达后将撤销INT请求
问题的提出
基本思路
DMA传送形式
DMA又分为DMA写(I/O接口 → 内存)和DMA读(内存 → I/O接口)。下图是几种DMA传送形式的示意:
基本步骤
基本工作方式
单次传输方式
假设从Memory → 外设
DMA控制器每次请求总线只传送一次数据,每次传送的数据大小取决于总线宽度
传送完后即释放总线控制权,如果还有数据需要传送,继续申请
块传输方式
请求传输
此方式与块传输方式基本类似,不同的是每传输一次,DMA控制器都要检测DREQ信号是否仍然有效,如果该信号仍有效,则继续进行DMA传输;否则,就暂停传输,交还总线控制权给CPU,直至DMA请求信号再次变为有效,数据块传输则从刚才暂停的那一点继续(称为“断点续传”)
随机请求:
与成组传送区别:在传送期间,若DMA请求信号无效,DMAC暂停传送并放弃总线。当DMA请求信号重新有效,DMAC再次申请总线使用权,获准之后从断点处续传
在询问方式中,DMA请求信号的作用类似于“PAUSE”
DMA传送方式的特点
依靠硬件实现数据传送
DMAC本身也是接口芯片
串行与并行
串行传输
并行传输
无握手信号的并行接口典型电路
采用无握手信号接口连接的外设一般是功能简单的电路模块,如按键,数码显示管等。CPU与这些无握手信号的外设接口传输数据时,总是假定外设总是处于准备好的状态
输入接口示例:线性键盘
键盘分类:按压式、常开式、开关阵列
按压式开关存在的问题:抖动、串键(2个或2个以上的键被同时按下,又称重键)
依据按键状态获取方式的不同,可以将键盘分为线性键盘和矩阵键盘,矩阵键盘又可分为非编码键盘和编码键盘
线性键盘:每一个案件需要占用I/O端口的一根口线
矩阵键盘:可分为非编码键盘和编码键盘
输入接口示例:矩阵键盘
输出接口示例:LED显示
码显示管是一种半导体发光器件,简称数码管,分为点阵式和段式。常见的段式有7段或8段(多一个小数点)
按照连接方式分为共阳极和共阴极两种结构
按照显示特性又分为静态显示和动态显示
静态显示方式
动态显示方式
输出接口示例:数码管的显示接口电路
带握手信号的输入接口电路
带握手信号的输出接口电路
GPIO模块电路
可编程通用并行接口是计算机及其他数字电路系统中最常使用的一种简单外部设备接口电路。其结构简单、应用途广泛,且可以通过编程控制字来实现控制,故得名“通用可编程I/O接口”,即GPIO(General-Purpose IO ports)
可编程并行接口芯片:Intel 8255A
早期的计算机使用单独的可编程芯片来控制I/O,如英特尔的8255芯片有3个8位并行I/O口,具有3个通道、3种工作方式:
典型嵌入式控制器的I/O端口位接口
微控制器芯片(单片机)往往会集成GPIO接口。一般来说,GPIO接口至少有两个寄存器,即“通用I/O控制寄存器”与“通用I/O数据寄存器”
概述
串行通信——数据在单条一位宽的传输信道上按时间先后一位一位地进行传送。与并行通信相比,串行通信具有以下特点:
优点:
缺点:需要串/并转换,对数据格式有要求
通过Modem实现远程数据通信
串行通信常用于需要远距离传输的情形,然而受限于传输线的特性,数字信号无法在传输线上直接进行远距离传输。一般发送方需要使用调制器(Modulator),把要传送的数字信号调制为适合在线路上传输的信号;接收方则使用解调器(Demodulator),将从线路上接收到的调制信号进行解调,还原成数字信号。调制器和解调器两者通常集成在一起作为一个设备,称为调制解调器(Modem)
调制解调器被称为DCE(Data Communication Equipment,数据通信设备)数据终端被称为DTE(Data Terminal Equipment,数据终端设备)
串行通信的性能参数
衡量数据传输速率有两个单位:
计算机普遍采用二进制,一个“符号”仅有高、低两种电平,分别代表逻辑值“1”和“0”,所以每个符号的信息量为1比特,此时波特率等于比特率。但在其它一些应用场合,一个“符号”的信息含量可能超过一个比特,此时波特率小于比特率
串行通信的同步方式
同步技术——能够检测和识别所传送的数据单元(位、字符或字节、帧、数据块等)的起止的技术
根据同步方式,串行通信又分为:
同步通信方式
异步通信方式
概述
如果采用相同的接口时钟频率,串行数据传输的速度要比并行传输慢得多,但对于覆盖面极其广阔的公用电话系统来说具有更大的现实意义
另外,并行接口时钟频率提升会遇到瓶颈,近年来出现了很多高速的串行接口标准
“异步串行接口”包括了两方面的内容:
异步串行数据帧格式
拟传输的数据以字符(一个字符通常含五至八位)为单位进行传送。考虑到传送发生的相对时间是随机的,为了确保整个通信过程的正确性,需要找一种合适的方法,使发送方和接收方在所传送的字符与字符间实现同步。常用的方法:在字符数据格式中设置起始位和停止位
如图。每个字符传输包括:一个起始位(低电平,逻辑“0”)、五至八位有效数据位、一位奇偶校验位、一位(或1.5位,或2位)停止位,停止位(高电平)之后是不定长度的空闲位(高电平)
异步传输信号波形的检测
问题:难以保证收发双方时钟的频率完全相等、相位严格对齐 → 检测困难
解决办法:设约定的波特率为,接收方用频率为的时钟对接收信号进行检测,,称为波特率因子,。有些芯片可编程设置,有些固定,如
设,接收端检测到一个低电平时,须证实是否的确是起始位。不同的芯片可能采用不同的方法,如:隔八个再检测一次,若仍为低电平则确认是起始位。或连续检测八个,若有五次以上是低电平则确认是起始位而不是干扰
确认了起始位后,从第九个检测脉冲(起始位中间位置)开始,接收端每隔16个脉冲采样一次输入信号,顺序接收各个数据位
异步串行接口电路
异步串行接口电路需要完成的基本功能包括:
发送过程:从数据总线上接收来自CPU的并行数据 → 基于移位寄存器进行并/串转换 → 入起始位、停止位等 → 按特定波特率由TXD发送
接收过程:RXD输入的数据 → 在本地时钟和波特率发生器的控制下,经同步控制器送给移位寄存器 → 串/并转换后进入接收缓存器 → 同时进行错误检测、帧解析并把相关信息写入状态寄存器 → 通过中断告知CPU接收完毕
异步串行接口信号定义
异步串行接口协议
最常见的串行通信标准:RS-232C接口
S-232是由EIA(Electronic Industry Association,美国电子工业协会)1970年制定的串行二进制数据交换接口技术标准。先后出现了多个版本,其中应用最广的是修订版C,即RS-232C
RS-232C标准最初是为远程通信连接数据终端设备(DTE)与数据通信设备(DCE)而制定的。虽然该标准并未考虑计算机系统的要求,但后来它被广泛应用于计算机系统
RS-232C定义了DTE与DCE之间的物理接口标准。数据通信设备可以是传真机、电话机、智能终端等
信号线定义——机械特性、功能特性
标准串口的设置——规程特性
电气特性——负载电容与传输距离
电气特性——PC与一般单片机的串口逻辑电平
电脑上的RS-232接口采用的是负逻辑电平
单片机的串口输出电路采用的逻辑电平是TTL电平。这种电平信号由TTL器件产生的,一般的芯片,如运放,数字器件等...
TTL:三极管结构
RS-422/432标准
RS-485标准
RS232/RS485/RS422对比
NXP(Philips) Inter-Integrated Circuit (I2C)
PHILIPS公司开发的两线式串行总线(一条串行数据线SDA,一条串行时钟线SCL),用于连接微控制器及其外围设备
标准模式下:100Kbps;快速模式下:400Kbps;高速模式下:3.4Mbps
示例:2块芯片通过I2C连接
驱动SDA和SCL线的器件的输出级必须漏极开路(OD门),以实现总线的“线与”功能。使用外部上拉电阻(接电源),以确保当没有器件将线拉低时能保持高电平
I2C接口典型电路
I2C的接口电路一般包括数据寄存器、控制寄存器、状态寄存器、地址寄存器,有些还包括和时钟有关的分频寄存器等
主从式通信方式
多主机总线
I2C的地址
I2C总线采用两线制总线,不具备微机系统所具有的由多位地址线所组成的并行地址总线,通过串行发送地址实现
总线上每一个器件的地址必须是唯一的
I2C标准中有7位地址和10位地址两种
I2C总线协议状态
I2C数据传输过程
主设备向从设备发送信息
主设备读取从设备信息
I2C电气特性
I2C支持的节点数
I2C操作示例:读取串行EEPROM
SPI是一种高速、全双工、同步的通信总线,通信过程使用四根信号线
SPI概述
同步串行外设接口,它可以使MCU与各种外围设备以串行方式进行通信以交换信息。是Motorola首先在其MC68HCXX系列处理器上定义的。SPI接口主要应用在EEPROM,FLASH,实时时钟,AD转换器,还有数字信号处理器和数字信号解码器之间
需要至少4根线,事实上3根也可以(单向传输时)
SPI中主设备与从设备的连接
SPI典型接口电路
SPI数据传输过程
通信过程由主设备发起,从设备参与
当一个主设备需要向从设备发送数据,或者希望读取从设备数据的时候,主设备通过拉低对应从设备的CS#来告知从设备
对于主设备来说,发送数据就是把比特逐个放到MOSI信号线上,而读取数据就是在MISO信号线上进行采样
SPI的四种工作模式
SPI工作状态简单,只有工作和空闲两个状态
根据空闲状态对应时钟的高电平还是低电平,以及时钟上升沿和下降沿的动作,可以形成不同四种工作方式
CA(Computer Architecture):计算机体系结构
CA是堆计算机系统的设计思想、逻辑特征、原理特征、结构特征和功能特征的一种抽象
广义CA=指令集系统结构ISA+微架构μarch+硬件实现
狭义CA=指令集系统结构ISA
指令集体系结构ISA
描述软件如何使用硬件的一种规范和约定,是程序员眼中的概念结构和功能特征,具体地就是程序员编程时能看到或者能用到的资源以及使用方式,包括:
微架构μarch
ISA的硬件实现方式。亦即以何种方式来实现处理器的各种功能,包括运算器、控制器、流水线、超标量和存储系统结构等,属于计算机的组织和实现技术
相同ISA的处理器可以有不同的微架构,如:
ARM9T和ARM7Y
AMD和Intel
只要ISA相同,则软件兼容
处理器体系结构的分类
ISA偏于处理器的软件层面,微架构偏于处理器的硬件层面
基于ISA分类:CISC、RISC
基于微架构分类:冯诺依曼结构、哈佛结构
哈佛结构:
简化哈佛结构:
Intel MCS-51单片机,指令和数据分别存储两个独立的存储模块,但仍共用一条公共总线,仍须分时访问
有些内部使用两条独立总线分别访问指令和数据(如Cortex-M系列处理器),有些内部分别配置指令和数据Cache或者TCM。但对外只有一条总线,外部指令和数据仍然存储在一个存储器中,旨在减少硬件复杂性
ARM体系结构版本特性简介
v1版
与ARM1原型机同时诞生,仅用于ARM1原型机
32位处理器,地址总线只有26条,内存寻址空间64MB,只提供了一些基本指令,如:
基本数据处理指令,没有乘法运算指令
数据存取指令,可以对字节、半字和字数据进行存取
控制转移指令,包括子程序调用及链接指令
供操作系统使用的软件中断SWI指令
v2版
ARM 2的内存寻址空间仍然只有64MB,为了提高数据处理能力,v2版增加了:
基于ARMv2版架构的处理器有ARM2、ARM2aS和ARM39
v3架构
有较大改进和完善,32位地址,内存寻址空间扩展到4GB,增加了Cache、新的寄存器和新的指令:
增加了CPSR,不再使用R15寄存器保存程序执行状态
增加了SPSR,用于异常处理时保存CPSR,以便恢复
增加了访问CPSR等特殊寄存器的MRS和MSR指令
增加了从异常处理返回指令的功能
新定义了abort和Undefined两种异常及相应的工作模式
将乘法和乘加运算指令扩展为32位
v4架构
基于ARMv4的处理器主要是ARM8和Strong ARM
ARMv4T版本——ARM体系架构的一个里程碑
v4T版在v3版的基础上所做的完善和扩展:
ARM7T和ARM9T产品系列都基于v4T版
v5架构
微架构方面
ISA方面的改进和完善
基于ARMv5版架构的ARM处理器包含ARM7EJ、ARM9E和ARM10E三个系列产品
v6版
发布于2001年,ARM体系结构又一个重要里程碑
支持ARMv5TEJ所有指令,在多媒体处理、存储器管理、多处理器支持和异常响应等方面引入许多新技术
微架构实现:流水线级数增至8或9级(v6T2),采用动态和静态组合的转移预测方式,准确率可达85%
内核与Cache以及与协处理器之间的数据通路为64位,每个流水线周期可读入2条指令或存放2个连续字数据
增加了增强型的数字信号处理器以及用于功耗管理的IEM(Intelligent Energy Management)部件,在性能和功耗两个方面又有新的突破
在ISA方面,ARMv6版架构增加了以下功能和指令:
v7版
发布于2004年,ARM体系结构的分水岭
v8版
首款支持64位指令集的处理器架构
继续分为ARMv8-A、ARMv8-R和ARMv8-M三种类型
ARM体系结构的增强型版本
每个基础版还有增强版,支持的指令有区别。在v7版之前,增强版用版本号的字母后缀表示,如:
T增强版:表示该版本支持Thumb指令集
E增强版:支持增强的DSP算法
J增强版:支持Java加速
S增强版:提供用于多媒体信号处理的SIMD指令
F增强版:支持矢量浮点处理单元
V6版还有:
v7版本之后,不再使用
小结
从内到外分为:ARM内核、ARM处理器、MCU或者SOC、以及嵌入式系统四个层级
ARM内核
必备部件
可选部件
ARM处理器
ARM内核的基础上,通过系统总线连接了:
通过外设总线连接
MCU和SoC
以ARM处理器为核心,增加了
体系结构版本与处理器采用两种标识方式,对应关系开始变得较为复杂
常见以及仍在使用的产品与ISA的对应关系:
v7版之前的产品命名规则
处理器名称后缀中的英文字母含义
第一个数字的舍义
表示产品系列,如ARM7TDMI和ARM920T分别对应ARM7系列和ARM9系列
第二个数字的含义
2:表示带有MMU,如ARM720T和ARM920T
3:改良型MMU
4:表示带有MPU,如ARM946ES
6:无MMU和MPU,如ARM966E-S和ARM968EJ-S
第三个数字的含义
名称最后的“-S”表示软核(HDL描述的产品)
分为ARM7(基于v3)和ARM7T(基于v4)两个子系列,获得广泛应用的是ARM7T
ARM7T系列基本型产品是ARM7TDMI(-S),同系列其他产品都是在其基础上增加了Cache、MMU或者MPU、以及ASB总线接口
MMU和MPU都是用于内存管理,两者的功能和主要区别如下:
分为ARM9T和ARM9E两个子系列
ARM9T基于v4T版本架构(与ARM7T相同),但是微架构有不一样,采用的是哈佛结构,流水线为5级
ARM9E采用的也是哈佛结构,分为v5TE和v5TEJ两个子版本,从版本号后缀可以看出:
从ARM9E开始增加TCM,性能与Cache相当,可以对TCM进行寻址访问
ISA大版本都是v6,有四款处理器产品(全是软核),每款处理器的ISA小版本各不相同
ARM1136J(F)-S,基于ARMv6版本,主要特性:
ARM1156T2(F)-S,基于ARMv6T2版本,主要特性:
ARM1176JZ(F)-S,基于ARMv6Z版本,主要特性:
ARM11MPCore,主要特性:
ARM 11流水线仍属于单发射标量流水线,但是:
设计理念:在性能、功耗、芯片面积和成本之间进行均衡,支持休眠模式、待机模式和关机模式
ARM11流水线结构:
Cortex-A系列处理器应用场景:
主要特性:
产品:从A5~A77共计20款,其中A5~A17为基于v7-A版本的32位处理器;A32虽然基于v8-A,但只有AArch32运行状态;A34以后产品基于64位v8-A版本结构,同时支持AArch32和AArch64两种运行模式
big.LITTLE(bL) 技术
允许拥有两种不同类型的内核,相同类型的内核组成一个簇(cluster),轻负载时运行低功耗内核,高负载时运行高性能内核,在性能和节能之间寻求平衡
采用bL结构的SOC芯片案例:
DynamIQ大小核技术
bL技术升级版,允许最多8个内核构成一个簇,单个处理器最多可实现32个簇和256个内核
Cortex-A55(2017年),第一款采用DynamIQ技术的小核,基于ARMv8.2架构,“具有深远影响的产品”
可作为高性能低功耗的64位处理器单独使用,应用于数字电视、VR和AR
但A55的设计目标是作为DynamIQ结构中的小核,目前许多高端手机处理器中,有些虽然采用了自研的大核,但小核几乎都毫无例外地选用了A55
A76(2018年)和A77(2019年),基于DynamIQ技术的“大核”,设计目标是利用DynamIQ技术与更多的同构或者异构内核集成,提供更强大的计算能力和实现更高效的能源利用效率
A76应用举例:华为海思麒麟980/990手机处理器
聚焦于高性能实时应用,设计目标包括:高性能、低延时、高可靠、可信赖、安全性和容错性,以确保嵌入式系统的时间确定性和行为确定性
Cortex-R应用领域:
目前Cortex-R系列处理器共有5款:
容错设计:多处理器锁步(lock-step)技术
双处理器锁步:主处理器和监控处理器在时间上严格同步地执行相同的指令。主处理器承担系统处理任务并负责驱动输出,监控处理器连续监控主处理器总线上的数据、地址和状态等信息
多处理器锁步:单颗处理器出现故障时,可通过硬件表决方式判断出现故障的处理器并将其屏蔽,由其他处理器负责任务执行,可实现故障的实时恢复
所有Cortex-R处理器都支持锁步技术
数据纠错/检错:ECC和奇偶校验
R系列处理器的Cache或TCM都支持ECC和或奇偶校验,可实现2bit的检错和1bit的纠错
除R4外,R5~R52还支持对总线接口的ECC纠错和检错,R52增加了对互连交叉总线的错误防护功能
为满足实时性要求,Cortex-R处理器都采用指令和数据分离的哈佛结构,都带有指令和数据Cache、TCM存储器、硬件除法器、双精度FPU、MPU、内存和中断控制器,此外:
面向实时应用的处理器一般不采用虚拟地址,R系列处理器都没有配置MMU,但是都带有MPU
ISR一般都存在私有TCM中,以减少中断响应延迟
面向低成本、低功耗和高性能应用领域,虽然在性能、可靠性和实时性方面不如Cortex-A和Cortex-R系列,但目前是ARM公司销售量最大的产品
2019年第4季度ARM处理器的总出货量为64亿片,其中有42亿片属于Cortex-M系列,占比达66%
Cortex-M系列第一款产品是基于v7-M版本架构的Cortex-M3(2005年)。为减小功耗,流水线只有三级(取指、译码、执行),但带有NVIC、硬件除法器、支持Thumb-2指令集、丰富的调试和跟踪功能
2010年发布的Cortex-M4与Cortex-M3基本相似,但增加了DSP,并且可选配FPU
v7-M出现3年后,ARM继续推出v6-M架构,相关产品有Cortex-M1(面向FPGA设计)、M0和M0+,目标市场是低功耗、小体积和高性价比应用,例如:
Cortex-M7(2014年9月),基于v7-M,6级流水线,带有双精度浮点单元、可选Cache或者TCM,以迎合高端微控制器和密集型数据处理的需求
基于v8-M的M系列处理器:M23、M33和M35P,支持新的增强指令集,增加了Trust Zone安全扩展
面向未来的物联网中的高端应用,2020年2月10日,ARM公司正式发布了基于ARMv8.1-M版本架构的Cortex-M55处理器(预计2021年才有产品问世),可看作Cortex-M33的下一代产品
M55首次使用了基于MVE(M-Profile Vector Extension,矢量扩展)技术的Helium引擎,将执行SIMD指令和DSP处理能力提升了5倍,机器学习能力提升了15倍
同时,ARM还发布了一款与Cortex-M55配套使用的嵌入式NPU,Ethos-U55(此前已有Ethos-N37、N57和N77),Ethos-U55是专为下一代Cortex-M处理器定制的,具有低功耗和低成本的特性
M55+U55,未来物联网应用领域的利器
基于v7M版本架构,三级流水线(取指、译码和执行),哈佛结构。主要特性如下:
带有系统节拍定时器Systick,可为操作系统所需的定时提供周期性的定时中断
双堆栈指针,操作系统和应用任务使用不同的堆栈
特权和非特权访问等级
Cortex-M4可以选配单精度FPU,其功能主要包括:
Cortex-M4指令集增加了DSP扩展,例如:
Cortex-M3也有几条MAC指令,但不是单周期的
Cortex-M4可看作Cortex-M3的增强版,两者都支持Thumb-2技术,但所支持的指令集有差异
按各部件作用以及与总线系统的连接关系,整个处理器系统可以分为内核、处理器和系统三个层级
包括CPU、NVIC、Systick以及可选的指令跟踪接口
Cortex-M4内核可选配FPU
CPU
NVIC和Systick
FPU
Cortex-M4可选配FPU,支持符合IEEE 754-2008标准的单精度浮点运算,该浮点单元主要特性包括:
Cortex-M4的FPU不支持双精度浮点运算、浮点余数以及二进制与十进制之间的转换,如若需要只能另外编写程序实现
Cortex-M4的浮点运算指令的助记符都是以v开头
FPU一般位于处理器内核与协处理器之间,带有状态控制寄存器,用以标明FPU当前运行状态,并可通过编程对其进行控制
为了与其他协处理器的管控方式一致,FPU被看作协处理器,并通过协处理器访问控制寄存器CPACR(Co-processor Access Control Register)对其进行管理和控制
CPACR寄存器中CP10和CP11两位负责对FPU进行管理,所以有时也将FPU看作协处理器CP10和CP11
通过对CPACR寄存器中CP10和CP11两位的置位或者复位操作,可以使能或禁用FPU
经典ARM处理器有单独的特殊寄存器访问指令MCR和MRC,实现对协处理器的操作控制和数据交换
与经典ARM处理器不同,Cortex-M4拥有专门的浮点运算和数据传送指令,实现浮点的读取、运算和写回
在Cortex-M4的三级流水线中,FPU和CPU共用取指阶段,在译码和执行阶段则二者并行执行
总线交换矩阵
MPU
在处理器基础上,再选配唤醒中断控制器WIC以及若干调试组件之后,就构成Cortex-M3/M4处理器系统
WIC
为了减少功耗,Cortex-M处理器引入“睡眠”和“深度睡眠”两种模式
不同工作状态下的电流消耗
WIC的电路非常小巧,通过专有接口与NVIC以及电源管理单元PMU(Power Management Unit)相连
只有在处理器处于深度睡眠模式时,WIC才会使能,此时,如果出现NMI或者未被屏蔽的IRQ时,WIC触发PMU单元,将整个系统唤醒
调试组件
经典ARM处理器也有多种调试组件,大都带有JTAG接口,并通过JTAG接口实现对寄存器和存储器的访问
从v7开始,ARM处理器采用了一种命名为Core Sight全新的调试架构。Core Sight调试架构涵盖了调试接口协议、调试总线协议、调试部件控制、安全特性以及跟踪接口等
在Cortex-M3/M4处理器中,调试过程是由NVIC和若干调试组件协作完成的。NVIC中有一些用于调试的寄存器,通过这些寄存器对处理器的调试动作进行控制,如停机(halting)和单步执行(stepping)等
Cortex-M3/M4可以选配多种调试组件,这些调试组件提供了指令断点、数据观察点、寄存器和存储器访问、性能分析(profiling)以及各种跟踪机制,如:
Cortex-M3/M4处理器中的调试组件
调试(Debug):是指通过调试接口读取或修改处理器内部的寄存器或存储器的内容,或者发布一些调试命令,让处理器执行某些调试动作,如暂停、单步执行或者断点执行等
跟踪(Trace):是指在程序运行期间,无需停止处理器正常的指令执行流程,由相关的跟踪组件实时收集处理器在指令执行过程中产生的各种运行信息,并通过跟踪接口实时输出到外部调试主机中,再由调试分析软件(如Keil)对这些信息进行分析
在Core Sight的调试架构中,ETM、DWT和ITM等调试组件都属于跟踪数据源(Trace Source),负责收集处理器运行过程中产生的各种调试信息
TPIU属于调试信号汇集点部件,负责将汇集的调试信息进行格式转换和打包之后,再通过跟踪端口输出到外部的调试主机(PC机)
Cortex-M3/M4处理器中的调试信息流向图:
DAP(Debug Access Port)
SWJ-DP和SW-DP
Cortex-M3/M4没有Cache或者TCM,而是通过多条总线连接片上各种不同类型和容量的存储器件
如果需要进一步扩展存储容量,还可以通过存储器接口控制器,连接片外大容量存储器
4GB线性地址空间,可通过存储器接口控制器连接32位、16位和8位的存储器件
定义了明确的存储器映射关系,4GB存储空间被划分为多个区域,分别用于不同的存储器和外设
支持小端和大端,但芯片制造商只能选择一种类型
可选位带(Bit-Band Operations)操作,也称为位段或者位域操作
内置写缓冲,可以提高程序的执行速度
可选MPU,支持8个可编程区域,可提高系统健壮性
所有基于ARNv7M的Cortex-M系列处理器都支持非对准传送,但是非对准传送将增加总线传送次数
所有基于ARMv7M的Cortex-M系列处理器,都采用相同的存储器映射关系方式(存储区域划分)
CODE区
SRAM区
外设区
外部RAM区
内核私有区域
内部私有外设,包括调试组件ITM、DWT和FPB,以及系统控制区SCS
系统控制空间SCS
外部私有外设,包括调试组件ETM、TPIU和ROM表,以及外部PPB总线
芯片厂商定义的存储区
Cortex M系列处理器采用这种统一的地址映射方案,有助于提高设备之间的软件可移植性和代码可重用性
虽然有明确的存储区域划分,但仍具灵活性,例如:
Cortex-M3/M4总线结构
核心:基于AHB总线协议的内部总线互连矩阵。其所连接的各类总线的作用以及主要特性简介如下
System,基于AHB-Lite规范的32位系统总线
访问区域
包括:
APB/PPB总线,32位APB总线
访问区域
四条总线各自管理的区域
CPU通过内部总线互连矩阵直接访问内核私有外设,不经过四条总线
调试访问端口DAP
AHB总线互联矩阵属于处理器内核设备
CODE区的总线矩阵或者总线复用器是ARM公司提供的两种不同的选件,其作用是让I-Code和D-Code都能够访问CODE区的flash和SRAM
片上SRAM也称为主SRAM,应该连接到系统总线上,使其位于SRAM区,以便可以使用位带操作
Cortex-M3/M4处理器集成了一个与CPU紧耦合的嵌套中断控制器NVIC总共可以管理:
支持的异常与中断处理种类
异常与中断处理
注意:CMSIS的中断编号0对应的是IRQ#0,中断编号239对应的是IRQ#239;而编号为负数的-15到-1依次对应的是复位到SYSTICK等系统异常
配置了NVIC之后,Cortex-M3/M4具有以下异常处理特性:
除了复位和NMI之外,所有异常都可以被屏蔽
除了复位、NMI和硬件错误之外,所有异常都可单独使能或禁止
除复位、NMI和硬件错误具有固定的(高)优先级之外,所有异常/中断都具有多达256级可编程优先级,以及最多128个可抢占(嵌套)优先级
支持优先级的动态修改(Cortex-M0/M0+无此特性)
向量中断方式,中断响应时自动从中断向量表中获取中断处理程序(ISR)入口地址
向量表可以重定位在存储器中的其他区域
低中断处理延迟,对于零等待的存储器系统,中断处理延迟仅为12个时钟周期
中断和多个异常可由软件触发
可以按照优先级对中断进行屏蔽
进入中断/异常服务程序时,自动保存包括PSR在内的多个寄存器;异常返回时自动恢复,无需另外编程
可选配唤醒中断控制器WIC,支持睡眠以及深度睡眠模式
硬件自动抢占管理
Cortex-M3/M4 和NVIC使用了多个可编程寄存器
关于中断嵌套
经典ARM处理器的中断向量表中还包含了跳转到中断服务程序入口的转移指令,而Cortex-M3/M4处理器的中断向量表只有异常/中断服务程序的入口地址
Cortex-M3/M4处理器的每个异常服务程序的入口地址为32位,占用4个字节
Cortex-M3/M4处理器总共有256个异常/中断异常类型,所以中断向量表的容量为4x256=1024个字节(1 KB)
中断向量表作为一类系统表,起始地址默认位于存储器空间最开始位置(地址0x0)
Cortex-M3/M4支持中断向量表
在中断响应时,若中断类型号为n,只需计算n×4(左移两位),立刻得到对应的中断向量在中断向量表中存放地址,可以快速获取中断服务程序的入口地址
中断响应时,读取中断向量以及ISR的取指操作可以与寄存器压栈操作同时进行;前者由I-Code完成,后者交由D-Code或者系统总线实现,以充分发挥哈佛结构的优势
由于中断向量表位于存储空间最开始的位置,而这片区域属于CODE区,由I-Code总线负责管理
理论上中断响应时的压栈操作可由D-Code或者系统总线完成,但是有些芯片制造商为了减少一片CODE区的SRAM,把数据都存放在由系统总线负责管理的SRAM区,这种情况下压栈操作只能由系统总线完成
在多任务系统中,CPU在不同的时间片为不同的任务进行进行服务,因此需要一个定时器来产生周期性的定时信号,“提醒”操作系统对任务进行切换
计算机中还有其他系统事务也需要定时信号,例如DRAM的定时刷新操作
为了支持多任务操作系统,Cortex-M系列处理器集成了一个系统节拍定时器SysTick,其作用是产生周期性的SYSTICK中断(异常号#15)
如果没有使用操作系统,SysTick定时器可以作为普通定时器使用,用于产生定时信号和进行时间测量
SysTick定时器是和NVIC捆绑在一起的,可认为是NVIC的一部分,都属于内核设备,非特权用户程序不能访问
内部有一个24位递减计数器和4个寄存器:
所谓处理器的编程模型(Programmer’s model),就是程序员所看到的处理器的工作状态、操作模式以及以寄存器为主的各种资源
Cortex-M3/M4处理器的编程模型与经典ARM处理器有较大差别,例如:
经典ARM处理器支持以下7种运行模式:
Cortex-M3/M4对这些模式进行了化简与合并
Cortex-M3/M4有两种操作状态,分别是:
调试状态仅用于调试操作,可以通过两种方式进入调试状态:
在调试状态下,调试器可以访问或修改处理器中寄存器的数值
无论在Thumb状态还是调试状态下,调试器都可以访问系统存储器,包括位于处理器片内和片外的各种外设
操作模式也称为处理器工作模式或者运行模式,Cortex-M3/M4把经典处理器的7种运行模式归并为两种:
关于特权访问等级和非特权访问等级
一种最基本的安全模型,对关键区域提供必要的保护
例如:为了防止不可靠的应用任务破坏操作系统内核以及其他任务使用的存储器和外设,可以通过特权等级划分限制应用程序可访问的区域;即使是某个应用程序出现了崩溃,也不至于影响到操作系统内核和其他应用任务的继续运行
非特权与特权访问等级在编程模型方面的差异:
系统启动后处于特权线程模式,在此模式下,可以对特殊寄存器CONTRL的写操作,将处理器从特权线程模式切换到非特权线程模式
但是非特权线程模式不能访问CONTRL寄存器,因此不能采用类似方式回到特权线程模式
处理模式和线程模式的编程模型也很类似,不过线程模式可以切换使用独立的进程栈指针PSP,使应用任务的栈空间和操作系统的主栈空间相互独立,可提高系统的健壮性和可靠性
Cortex-M系列处理器启动后默认处于特权线程模式以及Thumb状态
对于简单应用,一般都使用特权线程模式和主栈指针
基于ARMv6-M版本架构的Cortex-M0处理器不支持非特权线程模式,Cortex-M0+处理器只是将其作为一个可选项
Cortex-M3/M4处理器种常规寄存器共有16个,其中13个为32位通用寄存器,其他3个为堆栈指针、链接寄存器和程序计数器
经典ARM处理器的寄存器:
Cortex-M3/M4处理器中常规寄存器的分组
分为2组:
系统复位后,R0~R12的初始值均未定义
为实现汇编程序与C语言程序的相互调用,AAPCS(ARM Architecture Procedure Call Standard)规定:
Cortex-M3/M4处理器采用双堆栈设计,有两个物理上的栈指针,也就是有两个R13寄存器,一个是主栈指针MSP,另一个是进程栈指针PSP,对于一般程序而言,两个栈指针只有一个可见
MSP为默认栈指针,在系统复位后或处理器处于处理模式时,处理器使用MSP;PSP只能用于线程模式,栈指针的选择是通过特殊寄存器CONTROL设定的
在大多情况下,对于不使用操作系统的许多简单而言,没有必要使用PSP,只需使用MSP即可
系统复位之后,PSP的初值未定义,而MSP的初值存放在整个存储空间最开始(中断向量表)处第一个字中,在系统初始化时,需要将其取出并对MSP进行赋值
尽管v8版架构之前的ARM处理器都是32位的,PUSH和POP操作也是以字为单位进行的,堆栈采用字(4字节)对齐方式即可
考虑到64位双精度浮点数的压栈问题,AAPCS规范要求堆栈应该采用双字(8字节)对齐方式
在Cortex-M3/M4处理器中,通过对系统控制块SCB(System Control Block)中的配置控制寄存器CCR(Configuration Control Register)进行操作,可以使能或禁止双字栈对齐特性
无论是采用字对齐还是双字对齐,MSP和PSP的最低两位总是为00,对这两位的写操作不起作用
用于保存函数或子程序调用时的返回地址,在函数或子程序结束时,LR中的数值用于调用返回
在异常处理时,LR中将自动保存返回地址EXC_ RETURN,异常处理结束用于异常/中断返回
如果是嵌套调用,调用时需将LR中的数值压栈保存
由于Cortex-M3/M4中有16位指令,指令有时会对齐到半字地址,即便如此,返回地址总是偶数,LR的最低位默认为是0
在基于x86处理器的PC机中,不允许对代码段寄存器CS以及指令指针IP进行写操作,CS和IP不能作为数据传送和数据处理指令的目的操作数,程序转移或者过程调用只能通过专门的指令来实现
但是在ARM处理器中,PC不仅可读而且可写
在Cortex-M3/M4中,由于指令必须对齐半字或字,作为代码地址,PC的最低位总是认为是“0”
需要注意的是,无论使用跳转指令还是直接写PC寄存器,写入值必须是奇数,确保其最低位是“1”,以表示其处于Thumb状态,否则将被认为试图转入ARM模式,从而导致出现错误异常
当使用高级编程语言(包括C和C++)时,编译器会自动将跳转目标的最低位置“1”,无需担心出错
再次强调:PC最低位为“1”,只是表示处于Thumb状态,作为指令地址,PC最低位始终被认为是“0”
关于寄存器的名称
使用ARM汇编指令编程时,在汇编代码中出现的上述寄存器可以使用不同的名称,如大写、小写或者大小写混用,常用的汇编工具(如Keil MDK-ARM和ARM ADS)都能对其进行识别
除了常规寄存器,Cortex-M3/M4处理器中,还有多个特殊寄存器,分别是:
xPSR:程序状态寄存器,包括:
PRIMASK
FAULTMASK
BASEPRI(以上三个均为中断屏蔽设置寄存器)
CONTROL 控制寄存器,定义处理器的操作状态
特殊寄存器没有映射到内存空间,只能利用MSR/MRS指令通过名字对其进行访问,例如:
xxxxxxxxxx
MRS <reg>, <special_reg> ;读special_reg到通用寄存器reg
MSR <special_reg>, <reg> ;将reg内容写入special_reg
注意特殊寄存器与“特殊功能寄存器(SFR)”的区别,后者一般用于I/O控制的寄存器
CMSIS-core也提供了用于访问特殊寄存器的函数。在使用C或C++等高级开发简单应用时,可能不太需要这些特殊寄存器;如果开发需要在嵌入式操作系统环境下运行的应用程序,并且需要高级中断屏蔽特性时,就需要访问这些特殊寄存器
在ARM7TDMI为代表的经典ARM处理器中,采用了CPSR和SPSR两个程序状态控制器。CPSR保存当前程序状态,SPSR用于在异常/中断处理时保存CPSR的状态,以便异常返回后能够恢复处理器的工作状态
从ARMv7版架构开始,ARM采用了新的程序状态寄存器PSR,读取PSR的结果实际包含了APSR、EPSR和IPSR三个状态寄存器内容,因此,有时也将PSR称为xPSR(表中GE[3:0]只有Cortex-M4中有)
PSR中各个标志位的含义如下:
Cortex-M3/M4的PSR与经典ARM处理器的CPSR有较大差异,下图给出几种ARM处理器PSR的对比:
与ARM7TDMI的CPSR相比:
PRIMASK、FAULTMASK和BASEPRI三个寄存器的用途是为了实现基于优先权等级的异常/中断屏蔽
关于Cortex-M3/M4处理器的异常优先级:
下图为三个中断屏蔽寄存器的编程模型,可以看出PRIMASK和FAULTMASK都只有一位
PRIMASK
FAULTMASK
BASEPRI
也是ARMv7-M版架构新增的,可以按照具体优先数值对中断屏蔽进行管理
BASEPRI寄存器的最低8位采用了“可伸缩”设计,具体宽度取决于芯片制造商实际设计的中断优先级数量
一般而言,芯片制造商设计的中断优先级不少于8级,此时BASEPRI中7:5这3位用于设置中断屏蔽
如果设计了32级中断,BASEPRI的宽度为7:3共5位,假如7:3这5位的数值是0b1 0000,将屏蔽优先级数值大于等于0b1 0000的所有中断
如果7:3这5位的数值是0 0000,其含义则是对所有中断都不屏蔽
中断屏蔽寄存器属于特殊寄存器,只有特权访问等级才可以进行读写访问。非特权状态下的写操作会被忽略,而读操作返回数值为0
使用汇编指令访问三个中断屏蔽寄存器示例:
xxxxxxxxxx
MRS r0, BASEPRI; 将BASEPRI寄存器读入R0
MRS r0, PRIMASK; 将PRIMASK寄存器读入R0
MRS r0, FAULTMASK; 将FAULTMASK寄存器读入R0
MSR BASEPRI, r0; 将R0写入BASEPRI寄存器
MSR PRIMASK, r0; 将R0写入PRIMASK寄存器
MSR FAULTMASK, r0; 将RO写人FAULTMASK寄存器
中断设置示例:
x;关中断命令
MOV R0, #1
MSR PRIMASK, R0
;开中断命令
MOV R0, #0
MSR PRIMASK, R0
;假设系统中共有16级中断,BASEPRI寄存器的宽度
;为7:4共4位,现在需要屏蔽优先级大于等于4的所有中断
MOV R0, #0b100
MSR BASEPRI, R0
;取消BASEPRI寄存器的中断屏蔽设置
MOV R0, #0
MSR BASEPRI, R0
CMSIS-Core提供的访问函数:
xxxxxxxxxx
x = _get_BASEPRI(); //读BASEPRI寄存器
x =_get_PRIMARK(); //读PRIMASK寄存器
x =_get_FAULTMASK(); //读EAULTMASK寄存器
_set_BASEPRI(x); //设置BASEPRI的新数值
_set_PRIMASK(x); //置位PRIMASK
_set_FAULTMASK(x); //置位FAULTMASK
_disable_irq(); //置位PRIMASK,禁止异常,
//相当于_set_PRIMASK(1)
_enable_irq(); //清除PRIMASK,使能异常,
//相当于_set_PRIMASK(0)
利用修改处理器状态CPS指令,也可以方便地设置或清除PRIMASK和FAULTMASK的数值,例如:
xxxxxxxxxx
CPSIE I; 使能异常(清除PRIMASK位)
CPSID I; 禁止异常(置位PRIMASK位)
PSIE f; 使能异常(清除FAULTMASK位)
CPSID f; 禁止异常(置位FAULTMASK位)
对比上述指令,可以看出来
用于选择线程模式的特权访问等级以及栈指针
Cortex-M3/M4和Cortex-M0/M0+的CONTROL寄存器的编程模型如下图所示
CONTROL寄存器各位的含义:
nPRIV:设置线程模式的特权访问等级,该位为0/1,处理器进入特权线程模式/非特权线程模式
SPSEL:选择线程模式中的堆栈指针
FPCA:配置FPU的Cortex-M4才有此位。当发生异常时,若该位为1,浮点单元中的寄存器内容被压栈保存。执行浮点指令时FPCA位自动置位,在异常处理程序入口处该位被硬件自动清除
复位后,CONTROL寄存器被恢复成默认值0
特权线程模式与非特权线程模式的切换过程:
对于简单应用,可以一直运行在特权线程模式下,无须修改CONTROL寄存器的数值,并且只使用MSP
系统控制块SCB是由多个寄存器组成的一个数据结构,属于Cortex-M3/M4内核的一部分并被综合到NVIC中
SCB中各类寄存器的作用包括:
SCB的各类寄存器被映射到SCS中,地址范围:0xE000 ED00 ~ 0xE000 ED88
如果使用汇编语言,只能通过地址访问这些寄存器
但是CMSIS-Core为每个寄存器分配了一个符号,类似给这些寄存器赋予一个名称,例如:
使用C语言并利用CMSIS-Core定义的这些符号,可以更方便地对SCB中的各个寄存器进行访问
堆栈简介
堆栈的作用
在异常/中断响应时,保存被中断程序的下一条指令的地址,以及处理器状态寄存器的内容(保护断点),以便在异常/中断返回后,处理器能够从断点处继续运行
异常/中断服务程序,或者正在执行的函数或者子程序如果需要使用某些寄存器,可以使用堆栈保存这些原来的内容(保存现场),以便异常返回或者函数或子程序处理结束时可以恢复现场
实现主程序与函数或者子程序之间的参数传递
用于存储局部变量
堆栈的类型
按照堆栈区在存储器中的地址增长方向,可分为:
按照堆栈指针SP所指示的位置,又分为:
组合上述两种地址增长方向和两种堆栈指针指示位置,可以得到4种基本堆栈类型:
许多经典ARM处理器及ARM T32指令集可支持四种堆栈类型,但是,Cortex-M系列处理器只能使用满递减(FD)类型
处理器在启动或者复位后,系统初始化程序从位于内存最开始处的flash中,取出地址为0x0000 0000的第一个字,作为主栈指针MSP的初始值
每次PUSH操作时,处理器将SP的值减去4,然后将需要压栈保存的数据存储在SP指向的位置
每次POP操作,SP所指向的存储器数据被读出,然后SP的数值自动加4,指向POP之后新的栈顶位置
PUSH和POP操作应“匹配”,防止“张冠李戴”导致系统混乱甚至崩溃
如果Cortex-M3/M4处理器使能了双字栈对齐模式,当出现异常时,假如压栈操作之后堆栈指针没有对齐到双字边界,将如何处理?
Cortex-M3/M4的双堆栈设计有MSP和PSP两个堆栈指针,分别服务于不同的操作模式和特权访问等级
CONTROL寄存器中nPRIV和SPSEL的不同组合,两个堆栈共有4种场景,其中前三种比较常见
如果使用双堆栈,应通过MPU在SRAM中建两个区域
Cortex-M3/M4的堆栈是满递减类型,因此两个栈指针的初始值应该是两个区域的最大地址
如果采用双字对齐,栈顶应位于双字边界上,MSP和PSP最低3位为000
Cortex-M系列处理器的堆栈空间一般位于系统主存储器SRAM区(也可以放置在CODE区中通过D-Code总线的连接的SRAM中)
用于堆栈的存储区需要事先做好规划,预留足够的空间,以防出现堆栈溢出
MSP的初始值事先存放在0x0000 0000处,该位置通常位于I-Code总线所连接的flash中,系统上电或者复位之后,系统初始化程序完成MSP的初始化
PSP的初始化需要另外编程实现,PSP的初始化宜使用汇编指令代码,简单高效而且不易出错
示例:
xxxxxxxxxx
BL Mpusetup ;调用MPU设置子程序,建立region,并使
;能存储器保护
LDR r0, =PSP_TOP ;读取进程栈栈顶
MSR PSP, r0 ;初始化进程栈指针
MOV r0,#0x3 ;准备置位CONTROL寄存器的SPSEL和
;nPRIV
MSR CONTROL, r0 ;完成CONTROL寄存器的更改,切换到
;非特权线程模式
B UserAppStart ;已进入非特权线程模式,跳转到用户
;程序入口
所有基于ARMv7M的Cortex-M系列处理器,都采用相同的存储器映射关系方式(存储区域划分)
位段区
Cortex-M3/M4在SRAM区和片上外设区,各有一个位段区和位段别名区
系统控制区SCS
4KB,早期归属于NVIC,所以也称为NVIC区
除NVIC以外,SCS还映射了SysTick、MPU、SCB和FPU等部件的寄存器
不同存储器区域的用途
为提高性能,CODE区使用专门的I-Code和D-Code总线,I-Code、D-Code和系统总线可以并行执行
该结构也会加快中断响应速度,中断响应时,读取中断向量、取指和压栈操作可以同时执行
此外,一些芯片制造商也会在MCU中增加自行设计的Flash访问加速器
示例:Flash访问加速器
意法半导体(ST Microelectronics)的STM32F2(基于Cortex-M3的微控制器)和STM32F4(基于Cortex-M4的微控制器),在I-Code和D-Code总线接口处实现了Flash访问加速器
总线矩阵示例:NXP公司LPC1700
AHB Lite协议仅适用于单主控设备的情形,有些产品用“总线矩阵”或“多层AHB”等术语来描述芯片内部支持多主控设备总线系统。对多主控设备的支持未在AHB Lite协议中定义
网路传输、文件存储均有大端小端问题
在C语言下如果使用指针也需要注意大小端的问题
Cortex-M3/M4支持两种端模式
大端:字节不变大端和字不变大端
区别:数据传输时字节通道不同。字节通道指高低字节与总线上高低位数据线的映射关系,字节通道与存储系统设计相关
Cortex-M缺省支持小端模式
小端模式下,Cortex-M3/M4和经典ARM处理器的字节通道都是相同的
Cortex-M处理器中:
Cortex-M的存储器系统是32位的,但处理器访问或处理的数据大小可能是32位(字)、16位(半字)或者8位(字节)的
大部分经典ARM处理器只允许对齐传输
Cortex-M3和Cortex-M4处理器中,大部分存储器访问指令还支持非对其数据传输
非对齐的注意事项:
非对齐的问题:非对齐传输会被拆分为两个对齐传输,导致数据访问花费更多的时间,降低了存储器的访问效率。在高性能应用中,确保数据的对齐存放是必要的
并非所有Cortex-M3和Cortex-M4的存储器访问指令都支持非对齐的数据传输。例如,多加载/存储指令、栈操作指令、排他访问指令必须是对齐的;位段操作也不支持非对齐传输
可设置Cortex-M3或Cortex-M4处理器在非对齐传输出现时触发异常
位段(也称作位带)操作:一次存储器操作只访问一个位
Cortex-M3/M4处理器中,有两个位段区域:
位段别名& 位段别名区域
位段别名地址数据的LSB位段区存储单元的某一个位
位段区域的存储单元可以像普通存储器一样访问,还可以通过名为位段别名的一块独立的存储器区域进行位段访问
使用位段别名地址访问存储器时,所得到字数据的最低位LSB即对应位段区域中某个特定的位
1 MB位段区映射为32 MB位段别名区域。如0x2000 0000地址的字节数据的8个比特被映射到0x2200 0000 ~ 0x2200 001C处的别名区域
外设区域的位段别名地址如图所示,若读取别名地址0x4200002C,则返回结果可能是0x00000000或0x0000 0001,分别代表0x4000 0000位置字数据的第11位取值为“0”和“1”
修改某一位
没有位段特性时,只能”读 → 改 → 写“
位段操作可以帮助用户完成“读改写”
示例:将地址为0x2000 0000的字数据的第2位置1
读取特定位
没有位段特性时,只能先读取字节/半字/字数据,再使用其他指令提取某一位,至少需要两次操作
位段操作可以简化程序
例:读取地址为0x2000 0000字数据的第2位
操作的原子性:操作过程不会被其它事务打断
简化转移决断过程
C编译器本身不支持位段操作,其原因是:
但是可以编程实现位段操作
可以在C程序中声明存储器位置的地址和位段别名
xxxxxxxxxx
...
DEVICE_REG0 = DEVICE_REG0 | 0x2;//未使用位段特性设置bit[1]
...
DEVICE_REG0_BIT1 = 0x1;//利用位段特性通过位段别名地址设置bit[1]
Cortex-M3/M4默认的存储器访问权限
Cortex-M3/M4处理器的存储器访问属性:
可缓冲
Cortex-M3/M4支持总线接口的写缓冲
即使总线接口上的实际传输需要多个时钟周期才能完成,对可缓冲存储器区域的写操作可在单个时钟周期内执行,处理器可继续执行后续指令
代价:
可缓存与可共享
存储器按访问属性分类
按照可缓冲和可缓存属性,存储器分为以下三类:
现有多数基于Cortex-M3/M4的微控制器,只有可执行和可缓冲属性会影响到应用程序的执行
代码顺序存储器操作完成顺序
A1和A2是两条前后相连的存储器访问指令,A1指令在前,A2指令在后,当A1、A2指令所访问的存储器类型不同时,这两条指令实际存储器访问的先后顺序如表所示
存储器系统会确保”强序“类型存储器和”器件“类型存储器的访问顺序
各存储器区域的默认访问属性
在多用户操作系统中,当多个用户共享某个特定资源时,常利用信号量(semaphore)进行协调。若某共享资源只能满足一个用户使用时,被称为互斥体(Mutex)
排他写过程
排他访问需要软硬件配合才能完成,一次排他写过程需要先用排他读指令获取拟访问地址是否被锁定的信息;未被锁定时才可进行排他写并设置锁定状态
利用存储器屏障指令,程序员可以控制不同指令存储器访问的先后顺序
Cortex-M处理器不会调整程序中指令执行的顺序(在超标量处理或支持乱序执行的高性能处理器中可能会出现调整),同时,AHB Lite和APB协议较为简单,不允许在前面的传输还未完成时就开始新的传输
但是,为提高处理器性能,Cortex-M3/M4增加了写缓冲,写操作可能会和下一条指令的操作同步执行
存储器屏障指令可以用于:
Cortex-M3/M4支持三种存储器屏障指令:
在许多MCU中,芯片制造商还集成了其他一些存储器特性,以提高存储器映射的灵活性,例如:
很多情况下,MCU中除了CODE区的Flash之外,还有一个单独的ROM(也可能是Flash),其中包含了Bootloader,其功能包括:
对于具有Bootloader ROM的芯片,系统上电时执行的是Bootloader ROM中的引导程序,因此Bootloader ROM应该位于地址0x0
但是,系统再次启动时,可能不再运行Bootloader ROM中的程序,而是运行Flash中的程序。因此,可以使用下图所示电路修改存储器的映射关系
以上切换操作称为存储器重映射(Memory Remap),由Bootloader实现。但是,在重映射切换的同时无法跳到Bootloader新地址。因此,可采用一种名为“存储器别名”的方法,从两个不同的位置访问Bootloader
有多种存储器配置方法,下图只是其中的一种
当Cortex-M处理器接受了某异常请求后,处理器需要确定该异常对应的异常处理程序的起始地址。该信息位于存储器内的异常向量表中,向量表默认从地址0x0000 0000开始,按照异常类型号依次存放各个异常的入口地址
Cortex-M3/M4中,每一个中断都有一个8位的中断优先级(配置)寄存器(0xE000E400~ 0xE000E4EF,位于NVIC中),实际使用位数3~8位,取决于MCU设计的中断数量
优先级的减少通过去除优先级配置寄存器的最低位(LSB)实现,有两种不同的移除方法:
每一个中断的优先级由各自的中断优先级寄存器定义,中断优先级寄存器可以按照字节/半字/字进行访问
若设计中实现了4位优先级,优先级配置寄存器如下,会得到16个可编程优先级
实际使用的位数越多,可用的优先级越多
若出现优先级相同的异常同时发生,处理器将优先处理异常类型号低的,称之为”自然顺序优先级“
复位后的初识状态:
优先级寄存器3~8位又分为两部分(以8位为例)
分组优先级(group priority),过去称为抢占优先级(preempt priority)
子优先级(subpriority)
AIRCR(0xE000 ED0C)的PRIGROUP位域(AIRCR[10:8]),使用3位定义优先级分组的8种配置方案
若优先级配置寄存器的宽度不同,设置优先级分组的方法:
优先级配置寄存器的宽度为8,优先级分组为配置0
优先级配置寄存器的宽度为3,优先级分组为配置1
优先级配置寄存器的宽度为3,优先级分组为配置5
异常处理的过程包括:中断响应、中断处理和中断返回
异常请求的接受
处理器接受请求的条件:
注意:若异常处理程序中出现了SVC指令,而该异常的优先级不低于SVC的优先级,就会发出硬件错误,从而进入硬件错误的处理程序
异常进入流程
异常进入流程包括如下操作:
多个寄存器的值和返回地址被压入当前使用的栈
从向量表中取出异常向量
取出异常处理程序中的指令
更新多个NVIC寄存器(后续介绍)和内核寄存器(PSR、LR、PC及SP)
根据压栈时实际使用的栈,MSP或PSP的数值会在异常处理开始前自动调整。PC也会被更新为异常处理的起始地址,而LR则会被更新为名为EXC_RETURN的特殊值
EXC_RETURN服务于异常返回,其数值为32位,高28位为1,低4位用于指示进入异常是保存的状态信息(即指示使用的是MSP还是PSP,哪些寄存器被压入栈),其可能的数值如下所示
在异常进入过程中,硬件自动完成的处理有:
为加快中断执行速度,需要调整压栈顺序:
压栈时为了尽快更新PC,首先压栈的是PC(返回地址)和PSR,出栈时为了尽快恢复处理器状态和返回主程序,出栈时也应先出栈PSR和PC,这时需要根据压栈时实际使用的栈,MSP或PSP的数值会在异常处理开始前自动调整
此外,如果中断向量位于CODE区,压栈的同时可以使用I-Code总线取中断向量,以充分利用哈佛结构的优点;如果中断向量位于SRAM区或者RAM区,压栈和取向量只能都是用系统总线,会略微增加中断响应延迟
执行异常处理程序
在异常处理的结尾,程序代码执行的返回会引起EXC_RETURN数值被加载到程序计数器PC中,并触发异常返回机制
异常返回
Cortex-M处理器的异常返回机制由EXC_RETURN触发,该数值在异常入口处产生且被存储在LR中
EXC_RETURN写入PC时,就会触发异常返回流程
异常返回可由表中所示的指令产生。异常返回机制被触发后,进入异常期间被压入栈中的寄存器数值会被恢复到寄存器组中,因而多个NVIC寄存器和处理器内核中的寄存器(如PSR、SP和CONTROL)都会被更新
加速中断处理速度——咬尾中断
情形描述:
咬尾中断:
加速中断处理速度——晚到中断
情形描述:
晚到中断:
向量表重定位简介
向量表重定位的实现
在Cortex-M3/M4 处理器所集成的NVIC中,有一个名为VTOR(Vector Table Offset Register,地址为0x0E000 ED08)的寄存器,修改VTOR的值就能实现中断向量表的重定位
对中断向量起始地址的要求:
VTOR的格式
r2p0版本之前的Cortex-M3,向量表只能“迁移”CODE区或者SRAM区;而新版Cortex-M3和所有Cortex-M4取消了上述限制
应用示例:
具有Bootloader的设备
应用程序是从外部加载到RAM中执行
在传统ARM处理器中,若设备产生了中断请求,在得到处理前需要一直保持中断请求信号。在NVIC中设计了用于保存中断请求的挂起请求寄存器,即使请求中断的源设备取消了请求信号,已产生的中断仍会被处理
如果处理器空闲,处于挂起状态的中断请求会马上得到处理,此时,中断的挂起状态被自动清除。但如果处理器正在处理另外一个更高优先级或同等优先级的中断,或者产生请求的中断源被屏蔽了(通过设置中断屏蔽寄存器),那么在其他中断处理结束前或中断屏蔽被清除前,该中断会一直保持在挂起状态
某个中断被处理时就会进入激活状态。在NVIC中,中断激活状态寄存器保存每个中断的激活状态,只有在中断服务完成,处理器执行了异常返回后,中断激活状态寄存器中对应已完成服务中断的位才会被清除(自动完成)
中断的状态:请求挂起激活
挂起状态、挂起状态清楚、进入激活状态、清除激活状态
线程模式处理模式线程模式
在Cortex-M3/M4中,出现中断请求之后,如果没有得到服务,就一直被挂起。即使中断源因某种原因撤销了请求,仍然会被处理——在编写ISR时,应先读取中断源相关状态,若的确需要服务,继续执行ISR;否则退出
一般而言,需要中断服务的外设,应该设置专门的“中断请求触发器”,在得到服务前,一直维持请求信号有效,在中断响应之后再撤销
NVIC中的寄存器组只能管理类型16~255的外部中断,管理NMI和Systick等系统异常需要SCB中的寄存器
中断使能和禁止是通过对2个寄存器(中断设置使能寄存器Interrupt Set-enable Registers和中断清除使能寄存器Interrupt Clear-enable Registers)进行写操作,实际是对一个物理寄存器进行配置
注意:中断使能和禁止使用两个地址,操作的是同一个物理寄存器
清除使能(禁止中断)需要写入NVIC_ICERn寄存器的相应位
若中断请求产生但没有立即执行,就会进入挂起状态
设置中断挂起状态或者读取中断挂起状态,可以通过访问中断设置挂起寄存器(Interrupt Set-pending Registers,NVIC_ISPRn)实现
通过写ISPR将某个中断设置为挂起状态,该中断就进入了等待中断服务的队伍中
清除中断挂起状态可以通过中断清除挂起(Interrupt Clear-pending Registers,NVIC_ICPRn)寄存器实现
每个ISPR/ICPR寄存器也是32位,每位对应一个中断输入,若外部中断源超过32个,ISPR和ICPR寄存器也不止一个
中断的激活状态
中断优先级配置寄存器
软件触发中断寄存器
除了写ISPR以外,还可以向软件触发中断寄存器(Software Trigger Interrupt Register,STIR)写类型号来触发相应中断(写ISPR是置位对应位)
中断控制和状态寄存器
ICSR: Interrupt Control and State Register
用于设置和清除系统异常的挂起状态,包括NMI、SysTick和PendSV
通过ICSR可以获知当前正在处理的异常的类型号、当前挂起异常中优先级最高者的类型号、是否发生了抢占信号等信息
应用中断和复位控制寄存器
AIRCR: Application Interrupt and Reset Control Register
用于控制异常/中断优先级管理中的优先级分组,指示系统的端配置信息,提供自复位特性
VECTRESET和VECTCLRACTIVE位域是为调试器设计的。软件可利用VECTRESET触发处理器复位,但它不会复位外设,若需要产生系统复位,应该使用SYSRESETEREQ
系统处理优先级寄存器
SHPR: System Handler Priority Register
共3个,SHPR1到SHPR3,SHPR的位域定义与中断优先级寄存器定义相同,差别在于SHPR用于(除了复位、NMI和硬件错误以外的)系统异常
系统处理控制和状态寄存器
SHCSR: System Handler Control and State Register
可以使能的异常包括:使用错误、存储器管理错误和总线错误异常
上述异常和多数系统异常的激活状态也可从SHCSR获得
指令集体系架构:描述处理器指令及其功能、组织方式和规范
指令系统:计算机系统中所有机器指令的集合
机器指令:
ARM处理器的指令集
ARM Instruction Set Architecture
不同时期的ARM处理器指令集存在较大差异
目前,ARM公司将其不同系列处理器所支持的指令集架构ISA统一为三个
各个版本架构所支持的指令集
说明:
指令集扩展
除基本指令集以外,为满足具体应用需求,ARM处理器可选配一些功能部件,并增加与之“配套”的指令,构成扩展指令集(Arm Architecture Extensions)
例如:
ARM指令集的扩展过程
ARMv8-A的的指令集扩展过程:先后增加了Jazelle、VFP、TrustZone、SIMD 、NEON以及可选密码扩展
ARM的指令集扩展
DSP 扩展
浮点数运算扩展
多媒体SIMD 扩展
NEON 是SIMD的128 位升级版,具有32个64 位宽(也可以看作16个128位宽)寄存器
JAVA加速
安全计算的指令扩展
虚拟机有关的指令扩展
Cortex-M支持的指令集
部分Cortex-M系列处理器所支持的指令集以及扩展指令功能如下:
Cortex-M处理器的兼容性
Cortex-M处理器的适用场景
对于一般的数据处理和I/O控制,Cortex-M0/M0+完全可以胜任(性能达2.15 Core Mark/MHz)
如果需要进行复杂的数据处理和快速乘加运算,就应该升级到Cortex-M3/M4处理器
如果需要DSP功能,则应该选择Cortex-M4
如果还需要计算浮点数,Cortex-M4还应该选配FPU
需要特别指出的是:
T32的指令由半字对齐的序列构成
通过半字的最高5个比特来区分是16比特指令还是32比特指令。若一个半字的最高五个比特(bits[15:11])为如下三种情况则该半字为一个32位比特指令的第一个半字:
其他情况的半字均为16比特指令
16比特指令的二进制位串编码格式如下:
高六比特为操作码,操作码定义了不同的指令类别:
T32指令集中32比特指令的二进制编码格式如下:
操作码被分成三段:”op1“、”op2“、”op“
当”op1==0b00“时,表示是该指令T32指令集中的16比特指令
当”op1!=0b00“时,根据”op1“、”op2“、”op“可对32比特指令进行分类
在定义一条机器指令的时候,需要将指令的功能、源操作数、目标操作数、操作数地址等信息予以明确。ARM处理器中汇编指令的通用格式构成要素如下:
xxxxxxxxxx
<opcode> [cond] [q] [S] _<Rd>, _<Rn> [,_Oprand2]
其中,<>
内的参数是必选参数,而[]
内参数是可选参数
opcode
,操作码,也称为助记符。说明指令需要执行的操作类型
cond
,条件码(可选后缀),描述指令的执行条件
q
,可选后缀,指令宽度选择,“N”表示指令为16比特,“W”表示指令为32比特
S
,可选后缀,加上“S”,在指令执行完毕后自动更新APSR中的标志位的值
Rd
,ARM指令中的目标操作数,总是一个寄存器
Rn
,存放第一个源操作数寄存器,该操作数必须是寄存器
Oprand2
,第二源操作数,不仅可以是寄存器,还能是立即数,且能用经过偏移量计算的寄存器和立即数
T32中多数Thumb指令可以根据应用程序状态寄存器APSR中的标志位决定当前指令是否被执行
这种在特定条件满足时才执行的指令被称为条件执行指令
APSR寄存器的标志位定义为:
处理器执行指令的时候,其运算过程可能会改变APSR中的标志位
APSR寄存器的各标志位定义为:
N
bit[31] 负数标志位。N==1 表示上一次运算结果为负数,否则为正数或零Z
bit[30] 零标志位。Z==1 表示上一次运算结果为零C
bit[29] 进位标志位。C==1 表示上一次运算结果产生了进位V
bit[28] 溢出标志位。V==1 表示上一次运算结果产生了溢出Q
bit[27] 饱和标志位。Q==1 表示上一次运算结果产生了饱和操作GE[3:0]
bits[19:16],DSP扩展指令中SIMD类指令指示上一次运算结果信息在Thumb指令中,只要条件码不为“1110”,均为条件执行指令:
指令一般由操作码字段和操作数字段两部分组成
xxxxxxxxxx
操作码字段 操作数字段 ... 操作数字段
操作码字段:指示计算机要执行是什么操作
操作数字段:指令执行操作过程中所需要的操作数,该字段可以是:
ARM处理器绝大多数算逻运算指令支持3操作数,也有1~2个操作数,少数隐含多个操作数(如LDM指令),还有若干指令无操作数
寻址:根据指令内容确定操作数地址的过程
寻址方式:如何寻找操作数的方法。不同的寻址方式实质上是构成操作数地址的方法不同
立即数寻址也叫立即寻址,是一种特殊的寻址方式
操作数本身包含在指令中,只要取出指令也就取到了操作数
这个操作数叫做立即数,对应的寻址方式叫做立即寻址,如
xxxxxxxxxx
MOV R0, #66 ;将立即数66传送到寄存器R0
ADD R0, R0, #66 ;R0+66→R0
SUB R0, R0, #0x33 ;R0-0x33→R0
在立即数寻址中,要求立即数以“#”为前缀,对于以十六进制表示的立即数,要求在“#”后加上“0X”或“&”或“0x”
Cortex-M3/M4支持的T32指令集中,指令长度要么是16比特,要么是32比特,指令长度有限 → 立即数取值只能在一定范围内
对立即数的限制
在传统ARM处理器所使用的32位ARM指令中,要求32位立即数必须是一个“位图”数据
在16位Thumb指令集中,可以将任意8位立即数通过左移得到一个32位立即数
满足格式“0x00XY00XY”或“0xXY00XY00”或“0xXYXYXYXY”的数是合法的立即数,其中X和Y为16进制数
寄存器寻址(或称为寄存器直接寻址)就是利用寄存器中的数值作为操作数
在各类微处理器经常被采用,执行效率高
xxxxxxxxxx
ADD R0,R1,R2 ;将R1和R2相加结果送入R0
寄存器仅限于通用寄存器,不可以是PC
寄存器间接寻址就是把寄存器中存放的数值作为操作数,通过这个地址去取得操作数,操作数本身存放在存储器中
xxxxxxxxxx
LDR R0, [R1]
;以寄存器R1的值作为操作数地址,取得操作数后加载到R0
;常常记为[R1]→R0
ADD R0, R1, [R2]
;基于寄存器R2间接寻址取得操作数后与R1相加,结果存入R0
;常常记为R1+[R2]→R0
寄存器移位寻址是ARM指令集特有的寻址方式
寻址方式为:先由寄存器寻址得到操作数,对该操作数再进行移位操作后得到最终的操作数
xxxxxxxxxx
MOV R0, R2, LSL #3 ;R2<<3, → R0
MOV R0, R2, LSL R1 ;R2<<R1,→ R0
支持的移位方式:
LSL
:逻辑左移,寄存器中字的低端空出的位补零LSR
:逻辑右移,寄存器中字的高端空出的位补零ASR
:算术右移,移位过程中符号位不变,即如果源操作数是正数,则字的高端空出的位补零,否则补“1”ROR
:循环右移,由字的低端移出的位填入字的高端空出的位RRX
:带扩展的循环右移,操作数右移一位,高端空出的位用进位标志C的值来填充,低端移出的位填入进位标志位寄存器偏移寻址:操作数地址由一个寄存器中存放的数值与指令中给出的地址偏移量相加得到
寻址过程:将寄存器(基址寄存器)中的基址与指令中给出的地址偏移量相加,得到一个新的地址,通过这个地址取得操作数
汇编语法:
xxxxxxxxxx
opcode Rd [<Rn>,<offset>]
指令中给出的地址偏移量有三种形式:
LDR:从存储器特定位置读取32比特数值后存入指定的寄存器
STR:把指定寄存器的数值保存到存储器的特定位置
举例:
xxxxxxxxxx
LDR R0, [R1, #4] ;将R1中的值加4形成操作数的地址,取得的操作数送入R0,R1值不变
LDR R0, [R1, R2] ;R1中的值加上R2中的值形成操作数地址,取得的操作数送入R0,R1和R2值不变
STR R0, [R1, -R2, LSL #4]
;R1中的数值减去R2中的值x16,形成操作数地址,取得的操作数送入R0,执行后R1和R2的值不变
采用寄存器偏移寻址的LDR指令的典型汇编语法可存在如下三种形式:
LDR <Rt>, [<Rn> {,#<imm>}]
LDR <Rt>, [<Rn>, <Rm>]
LDR <Rt>, [<Rn>, <Rm> {,LSL #<shift>}]
其中,<Rn>
表示基址寄存器,而<offset>
表示偏移量,偏移量可以是:
<imm5>
或8位立即数<imm8>
或12位立即数<imm12>
<Rm>
#<shift>
前变址寻址方式:在执行指令的时候自动把基址与偏移加和形成的操作数地址写回到基址寄存器
前变址:基址寄存器中的数值和立即数偏移量的加和计算发生在寻址前
汇编语法:
xxxxxxxxxx
opcode Rd[<Rn>, <offset>]!
"!"后缀表示指令完成时更新存放基地址的基址寄存器(写回)
举例:
xxxxxxxxxx
LDR R0,[R1,#4] ;将R1中的值加4形成操作数的地址,取得的操作数送入R0,R1不变
LDR R0,[R1,#4]! ;与上一条指令的区别:执行后R1=R1+4
LDR R0,[R1,R2] ;R1中的值加上R2中的值形成操作数地址,取得的操作数送入R0
LDR R0,[R1,R2]! ;与上一条指令的区别:执行后R1=R1+R2
后变址寻址:在执行指令的时候,操作数地址从基址寄存器获取,指令执行后再将操作数地址加上偏移量生成一个新的地址,并将该新地址写入基址寄存器
后变址:指令中的偏移量在存储器访问期间不会用到,而是在数据传输后更新基址寄存器
汇编语法:
xxxxxxxxxx
opcode Rd [<Rn>],<offset>
示例:
xxxxxxxxxx
LDR R0,[R1,#4] ;将R1中的值加4形成操作数的地址,取得的操作数送入R0
LDR R0,[R1,#4]! ;与上一条指令的区别:“!”表示指令执行后操作数地址存入R1
LDR R0,[R1],#4 ;R1中的值做操作数地址,取得操作数送入R0,R1=R1+4
从一块连续的存储器区域装载多个数据到多个寄存器中
汇编语法:
xxxxxxxxxx
LDM/STM{addr_mode} <Rn>{!},<registers>
其中,<Rn>
为基址寄存器,<registers>
为需要载入数据的寄存器集合,可选项{!}
表示需要将修改后的地址写入基址寄存器<Rn>
。可选后缀{addr_mode}
可选择如下四种方式(Cortex-M3/M4只支持IA和DB方式)
LDM:可以从连续的存储区域转载多个数据
STM:将一组寄存器中的数值保存到连续的存储器区域
举例:
xxxxxxxxxx
LDMIA R0!,{R1,R2,R3,R4} ;将连续存储单元的32比特数值传送到R1~R4
LDMIA R0!,{R1-R4} ;与上一条指令功能完全相同
STMIA R0!,{R1-R7} ;R1~R7的数保存到R0指向的地址,每取一个数后R0递增4
STMIB R0!,{R1-R7} ;R1~R7的数保存到R0指向的地址,每取一个数前R0递增4
STMDA R0!,{R1-R7} ;R1~R7的数保存到R0指向的地址,每取一个数后R0递减4
STMDB R0!,{R1-R7} ;R1~R7的数保存到R0指向的地址,每取一个数前R0递减4
如果把前述多寄存器寻址方式中LDM和STM指令中的基址寄存器更换为堆栈指针寄存器SP,并添加{!}
(意为每次存/取操作数就更新一下SP),则寻址操作数为堆栈中存放的数值,寻址方式变成堆栈寻址
LDM:每次取操作数自动POP堆栈中的数据到指定寄存器
STM:每次将寄存器中的数自动PUSH到堆栈中
Cortex-M系列处理器支持满递减类型的堆栈,可以使用LDMFD指令从堆栈装载数据,使用STMFD指令保存数据到堆栈(如果堆栈类型是满增、空减或空增,则后缀应该为FA,ED或EA)
举例:
xxxxxxxxxx
STMFD SP!,{R1-R7} ;将R1~R7寄存器中的数压入堆栈
LDMFD SP!,{R1-R7} ;将堆栈中的数取出存入R1~R7寄存器
PC相对寻址是一种特殊的基址变址寻址,常简称为相对寻址
PC相对寻址以程序计数器PC寄存器的当前值作为基地址,指令中的地址标号作为偏移量,将两者相加获得操作数的地址
偏移量的表示方法:
示例1:
用BL指令跳转到“MY_SUB”标号对应的语句执行
xxxxxxxxxx
BL MY_SUB ;相对寻址,跳转到MY_SUB处执行
... ;其他指令
MY_SUB ADD R0,R0,R1 ;转移目标指令
... ;其他指令
示例2:
用ADR指令获取PC相对寻址结果
xxxxxxxxxx
start MOV R0,#10 ;start是标号
... ;其他指令
ADR R2,start ;将标号为“start”语句的地址送入R2
示例3:
利用LDR指令将相对当前代码位置后1-2字节位置的一个字数据(32位)传送到R0寄存器
xxxxxxxxxx
LDR R0,[PC,#0xC]
实现处理器内部不同电路单元之间的数据传送
MOVW:把16位任意立即数传送到目的寄存器的低16位,高16位清0
MOVT:把16位任意立即数传送到目的寄存器的高16位,低16位不变
使用MOVW和MOVT指令可以将任意的32位立即数传送到32位寄存器
有多条Load/Store指令用于存储器访问
寻址模式:立即数寻址、寄存器寻址、寄存器移位寻址、寄存器间接寻址、基址变址寻址、多寄存器寻址(块拷贝寻址)、堆栈寻址、PC相对寻址
安全性增强:即使是特权访问等级程序,如果使用非特权的LDRT或者STRT指令,也只能访问非特权访问等级才能访问的区域,否则将引起Fault异常
排他访问增强
操作数类型
操作数类型:
可存储的数据类型:字节、半字、字
读/写存储器操作支持的数据类型:
零扩展:在高位补零,如1000 1010 → 0000 0000 1000 1010
符号扩展:用于保护有符号数的符号位,如
使用LDRSB或LDRSH将一个字节或半字数据加载到32位寄存器,会对被加载数据自动执行符号位扩展,如
LDRSB R7, 0x83
,数据加载前会被转换为0xFFFF FF83LDRSB R7,0x03
,数据加载前会被转换为0x0000 0003不同的寻址方式——以LDRB为例
偏移寻址(Offsetaddressing)模式
xxxxxxxxxx
LDRBRd,[Rn,#offset]
;从存储器位置[Rn]+offset读取字节
前变址(Pre-indexedaddressing)寻址模式
xxxxxxxxxx
LDRBRd,[Rn,#offset]!
;从[Rn]+offset读取字节,然后更新Rn为Rn+offset
后变址(Post-indexedaddressing)寻址模式
xxxxxxxxxx
LDRBRd,[Rn],#offset
;读取[Rn]处的字节到Rd,然后更新Rn为Rn+offset
寄存器移位寻址(Shiftsappliedtoaregister)模式
xxxxxxxxxx
LDRBRd,[Rn,Rm,LSL#n)]
;从存储器位置Rn+(Rm<<n)处读取字节
多加载和多存储指令
ARM处理器的一个重要特性,可以读(LDM指令)或者写(STM指令)存储器中的多个连续数据
堆栈操作
对于FD型堆栈,以下两条指令等价(Equivalent)
xxxxxxxxxx
PUSH<cond><q><registers>
STMDB<cond><q>SP!,<registers>
例如:
xxxxxxxxxx
PUSH{R0,R4-R6,R8}
;将R0、R4、R5、R6和R8压入栈中
对于FD型堆栈,以下两条指令等价
xxxxxxxxxx
POP<cond><q><registers>
LDMIA<cond><q>SP!,<registers>
例如:
xxxxxxxxxx
POP{R1,R2}
;将栈中内容存入R1和R2
PC相对寻址模式
如果使用PC寄存器作为基地址,再加上偏移量形成待访问操作数地址。常用于将立即数加载到寄存器中,如前述的文本池(Literal Pool)访问
非特权等级加载和存储
ARM中提供了一组特殊的加载和存储指令,在特权访问等级程序中使用这些指令加载或保存的数据,如同非特权访问等级程序的访问效果
排他式访问
xxxxxxxxxx
LDREX Rx,[Ry]
;排他加载,[Ry]→Rx,同时对Ry指向的内存区域标记独占访问,如果执行时发现已被标记,对指令执行没有影响
xxxxxxxxxx
STRRx,Ry,[Rz]
;排他存储,Ry→[Rz],如果成功,则将Rx更新为0;若不成功,则将Rx置1
xxxxxxxxxx
ADD R0,R0,R1 ;R0=R0+R1,不修改APSR
ADDS R0,R0,0x12 ;R0=R0+0x12,更新APSR
ADC R0,R1,R2 ;R0=R1+R2+进位,不修改APSR
Cortex-M3/M4都支持具有32位和64位结果的32位乘法指令和乘加(MAC)指令,APSR标志不受这些指令的影响。Cortex-M4处理器还支持额外的快速MAC指令
BIC(位清除)指令的一般格式:
xxxxxxxxxx
BIC{条件}{S} Rd,Rn,Operand2
该指令将Rn与Operand2的反码按位相“与”,结果存入Rd,该指令常用于将Rn的某些位清零
BIC R1,R1,#0xF0000000 ;将R1高4位清零
BIC R2,R3,#0x0F;将R3低4位清0结果存入R2
说明:如果使用16位指令,只要2个操作数,目的操作数必须是源操作数之一,而且只能是低位寄存器(R0~R7)
ORN(按位或非)没有16位指令,该指令将源操作数按位取反后,再执行按位进行逻辑或运算
若使用S后缀,循环和移位指令也会更新APSR中的进位标志位;多位移位运算之后,进位位为最后移出寄存器的哪一位
只有循环右移而没有循环左移的原因:
除了RRX(包含进位位的循环右移)指令以外,移位与运算指令还有16位版本,但是16位版本只能使用低位寄存器(R0~R7)
符号扩展与无符号扩展
上述指令也有16位和32位两种形式,16位指令只能访问低位寄存器,32位可以访问高位寄存器
例:若R0为0x55AA8765,以下指令执行后R1的数值:
xxxxxxxxxx
SXTB Rl,R0`;R1=0x00000065,只转换R0中的0x65
SXTH R1,R0`;R1=0xFFFF8765,只转换R0中的0x8765
UXTB Rl,R0`;R1=0x00000065,只转换R0中的0x65
UXTH R1,R0`;R1=0x00008765,只转换R0中的0x8765
上述指令的32位形式还可以选择在有符号扩展运算之前将Rn循环右移
数据反转指令:常用于大小端数据转换
示例:
例:假设R0为0x12345678,则有:
xxxxxxxxxx
REV R1,R0 ;R1变为0x78563412
REVH R2,R0 ;R2则会变为0x34127856
REVSH R3,R0 ;R3则会变为0x0000785684
位域处理指令用于控制类用于
BFC(位域清除)指令:清除Rd中位置由<lsb>
指定的宽度位<width>
的相邻域
例:假设R0=0x1234FFFF
xxxxxxxxxx
BFC R0,#4,#8 ;执行后R0=0x1234F00F
BFI(位域插入)指令:将Rn中的1~31位(#width
)插入到Rd中由#lsb
(最低位)指定的位置
例:假设R0=0x24681357,R1=0x89ABCDEF
xxxxxxxxxx
BFI R0,R1,#8,#16 ;将R1的[15:0]插入R0[23:8]中
;执行后R0=0x24CDEF57
CLZ指令:计算Rn中前导零的个数,结果存入Rd
RBIT(反序)指令:将Rn中的字数根据反序后存入Rd
例如:假设R1=0b1100 0011 1010 0101 1011 1101 1000 0001
xxxxxxxxxx
RBIT R0,R1 ;R0=0b1000 0001 1011 1101 1010 0101 1100 0011
SBFX/UBFX指令:将Rn中从#lsb
起提取宽度为#width
的位域复制到Rd中,并进行符号展开/零展开
上述指令运行后将更新APSR而不保存运算结果
这些指令的后续指令往往是条件跳转和条件执行指令
包括无条件跳转和函数调用、条件跳转、比较和条件组合跳转、条件执行(IF-THEN)、以及表格跳转等
更新PC的数据处理指令(如MOV、ADD),或写入PC的加载指令(如LDR、LDM、POP)也可以引起跳转,但不常用
关于函数调用指令的说明
BLX<label>
指令,(不同于Cortex-M3/M4的BLX<Rm>
),该指令执行跳转并总是切换状态。由于Cortex-M3/M4只有Thumb状态,所以不支持BLX<label>
指令基于APSR当前的标志位决定是否跳转
cond
为以下14个可能的条件后缀之一
ARMv7架构增加了两条比较跳转指令
说明:相当于CMP和BEQ/BNE的组合。只能向前跳转,不能向后跳转,跳转范围为当前指令后的4~130字节,且只能使用R0~R7,常用于小范围的循环控制,如:
IT指令允许跟随其后的最多四条指令是条件执行的,IT指令后的几条指令被称作一个IT块
IT指令的汇编语法为:
xxxxxxxxxx
IT {x{y{z}}} cond
cond
为IT块中第1条指令使用的条件码x
指定IT块中第2条指令的是否执行的开关y
指定IT块中第3条指令的是否执行的开关z
指定IT块中第4条指令的是否执行的开关x
,y
和z
对应有两种开关:
增加不同位数后缀的IT指令(IT+T和E的各种组合)
示例:
例1
xxxxxxxxxx
IT EQ ;意为“If-Then”,下条指令条件执行
ADDEQ R0,R1,R2 ;若Z=1,则(R1+R2)→R0
例2
xxxxxxxxxx
ITETT NE ;“If-Then-Else-Then-Then”,随后四条指令条件执行
ADDNE R0,R0,R1 ;若Z=0(不等),则(R0+R1)→R0
ADDEQ R0,R0,R3 ;若Z=1,则(R0+R3)→R0
ADDNE R2,R4,#1 ;若Z=0,则(R4+1)→R0
MOVNE R5,R3 ;若Z=0,R3→R5
注意:
跳转表的意义:
Cortex-M3/M4支持两条表格跳转指令:
定点运算中经常遇到运算结果溢出的情况,有上溢和下溢两种
溢出运算:
Cortex-M3支持以下两条饱和运算指令:
SSAT和USAT的汇编格式:
xxxxxxxxxx
SSAT<Rd>,#<immed>,<Rn>,{,<shift>};有符号饱和
USAT<Rd>,#<immed>,<Rn>,{,<shift>};无符号饱和
其中:
<Rn>
为输入值<shift>
为饱和前可选的移位操作,可为LSL #n
或ASR #n
<Rn>
为目的寄存器#immed
为执行饱和的位的位置如果运算过程中出现了饱和,ASPR中的Q位置1
示例:
例1:如果需要将一个32位有符号数饱和为16位有符号数,可以使用如下指令
xxxxxxxxxx
SSAT R1,#16,R0
例2:如果需要将一个32位有符号数饱和为16位无符号数,可以使用如下指令
xxxxxxxxxx
USAT R2,#16,R0
当R0为不同数值时,SSAT和USAT指令执行后,R1和R2的值以及Q位如下表所示
管理调用(SVC)指令用于产生SVC异常(异常类型为11)。SVC一般用于嵌入式操作系统(OS),其中,非特权应用可以请求使用具有特权OS提供的服务(类似于x86系统中的系统功能调用)
SVC指令要求SVC的优先级高于当前优先级,并且没有被PRIMASK等寄存器屏蔽
SVC指令格式:SVC #<immed>
immed
为8位立即数,是OS定义的系统功能调用号另一个和异常相关的指令是CPS指令,用于改变处理器状态。使用这条指令可以设置或清除PRIMASK和FAULTMASK等中断屏蔽寄存器
Cortex-M支持NOP指令,用于产生指令对齐或延时
在软件开发/调试过程中,断点(BKPT:Breakpoint)指令用于实现应用程序中的软件断点
与Cortex-M3处理器相比,Cortex-M4支持的指令更多。新增的功能包括:单指令多数据(SIMD)、饱和指令、其他的乘法和MAC(乘累加)指令、打包和解包指令、可选的浮点指令等。这些指令可以让Cortex-M4可以更加高效地进行实时数字信号处理
目前基于ARM处理器的程序大多采用C语言开发
特定场合下必须使用汇编语言(系统启动程序)
分类
基于Windows平台
基于Linux平台
其他分类方法
ARM官方提供的软件
KeilMDK
Arm Development Studio
Compiler
KeilRTX5
Software Test Libraries
FuSaRTS
ARM-Linux-GCC
GNU Compiler Collection(GCC)是一套由GNU开发的编译器集,不仅支持C语言编译,还支持C++、Ada、Object C等许多语言。GCC还支持多种处理器架构,包括X86、ARM、和MIPS等处理器架构,是在Linux平台下被广泛使用的软件开发工具
GNU:是“GNU is Not Unix”的递归缩写,是一个自由软件工程项目。这些软件在GNU通用公共许可的保护下允许任何人免费使用和传播(但必须同时提供源程序),GNU软件许可相当宽松,有很多公司利用GNU软件进行商业活动
ARM-Linux-GCC是基于ARM目标机的交叉编译软件,所谓交叉编译简单来说就是在一个平台上生成另一个平台上的可执行代码
ARM-Linux-GCC使用命令行来调用命令执行
MDK
MDK由Keil公司推出
MDK主要特点:
ARM Development Studio 5(DS-5)
DS-5是一款支持开发所有ARM内核芯片的IDE,主要特点如下:
MDK vs DS-5
不同的应用领域
使用经验
Keil MDK的软件开发周期
μVision集成开发环境
μVision IDE是一款集编辑、编译和项目管理于一身的基于窗口的软件开发环境
μVision集成了C语言编译器,宏编译,链接/定位,以及HEX文件产生器。
μVision特性:
ARM仿真器
仿真器可以替代目标系统中的MCU,仿真其运行。它运行起来和实际的目标处理器一样,但是增加了其它功能,使用户能够通过计算机或其它调试界面来观察MCU中的程序和数据,并控制MCU的运行,它是调试嵌入式软件的一个经济、有效的手段
具有以下优点:
在ARM汇编语言程序里,有一些特殊指令助记符,这些助记符与指令系统的助记符不同,没有相对应的操作码,通常称这些特殊指令助记符为伪指令,他们所完成的操作称为伪操作
伪指令不像机器指令那样在处理器运行期间由机器执行,而是汇编程序对源程序汇编期间由汇编程序处理,包括:定义变量、分配数据存储空间、控制汇编过程、定义程序入口等,这些伪指令仅在汇编过程中起作用,一旦汇编结束,伪指令的使命就完成了
符号定义伪指令用于定义ARM汇编程序中的变量、对变量赋值以及定义寄存器的别名等操作。常见的符号定义伪指令有如下几种:
GBLA、GBLL和GBLS
语法格式:
xxxxxxxxxx
GBLA (GBLL或GBLS) 全局变量名;
GBLA、GBLL和GBLS伪指令用于定义一个ARM程序中的全局变量,并将其初始化
其中:
以上三条伪指令用于定义全局变量,在整个程序范围内变量名必须唯一
举例:
xxxxxxxxxx
GBLA Test1 ;定义一个全局的数字变量,变量名为Test1
Test1 SETA 0xaa ;将该变量赋值为0xaa
GBLL Test2 ;定义一个全局的逻辑变量,变量名为Test2
Test2 SETL{TRUE} ;将该变量赋值为真
GBLS Test3 ;定义一个全局的字符串变量,变量名为Test3
Test3 SETS “Testing”;将该变量赋值为“Testing”
LCLA、LCLL和LCLS
语法格式:
xxxxxxxxxx
LCLA (LCLL或LCLS) 局部变量名;
LCLA、LCLL和LCLS伪指令用于定义一个ARM程序中的局部变量,并将其初始化
其中:
以上三条伪指令用于声明局部变量,在其作用范围内变量名必须唯一
举例:
xxxxxxxxxx
LCLA Test4 ;声明一个局部的数字变量,变量名为Test4
Test3 SETA 0xaa ;将该变量赋值为0xaa
LCLL Test5 ;声明一个局部的逻辑变量,变量名为Test5
Test4 SETL {TRUE} ;将该变量赋值为真
LCLS Test6 ;定义一个局部的字符串变量,变量名为Test6
Test6 SETS “Testing”;将该变量赋值为“Testing”
SETA、SETL和SETS
语法格式:
xxxxxxxxxx
变量名 SETA (SETL或SETS) 表达式;
伪指令SETA、SETL、SETS用于给一个已经定义的全局变量或局部变量赋值
其中:
其中,变量名为已经被定义过的全局变量或局部变量,表达式为将要赋给变量的值
举例:
xxxxxxxxxx
LCLA Test3 ;声明一个局部的数字变量,变量名为Test3
Test3 SETA 0xaa ;将该变量赋值为0xaa
LCLL Test4 ;声明一个局部的逻辑变量,变量名为Test4
Test4 SETL{TRUE} ;将该变量赋值为真
RLIST
语法格式:
xxxxxxxxxx
名称 RLIST {寄存器列表};
RLIST伪指令可用于对一个通用寄存器列表定义名称,使用该伪指令定义的名称可在ARM指令LDM/STM中使用。在LDM/STM指令中,列表中的寄存器访问次序为根据寄存器的编号由低到高,而与列表中的寄存器排列次序无关
举例:
xxxxxxxxxx
RegList RLIST {R0-R5,R8,R10};将寄存器列表名称定义为RegList,可在ARM指令LDM/STM中通过该名称访问寄存器列表
数据定义伪指令一般用于为特定的数据分配存储单元,同时可完成已存储单元的初始化。常见的数据定义伪指令有如下几种:
DCB
语法格式:
xxxxxxxxxx
标号 DCB 表达式;
DCB伪指令用于分配一段连续的字节(8位)存储单元并用伪指令中指定的表达式初始化。其中,表达式可以为0~255的数字或字符串,DCB也可用“=”代替
举例:
xxxxxxxxxx
Str DCB "This is a test!" ;分配一段连续的字节存储单元并初始化
DCW(或DCWU)
语法格式:
xxxxxxxxxx
标号 DCW(或DCWU) 表达式;
DCW(或DCWU)伪指令用于分配一段连续的半字(16位)存储单元并用伪指令中指定的表达式初始化。其中表达式可以为程序标号或数字表达式
用DCW分配的字存储单元是半字对齐的,而用DCWU分配的字存储单元并不严格半字对齐
示例:
xxxxxxxxxx
DataTest DCW 1,2,3 ;分配3个连续的半字存储单元并用1,2,3初始化
DCD(或DCDU)
语法格式:
xxxxxxxxxx
标号 DCD(或DCDU) 表达式;
DCD(或DCDU)伪指令用于分配一段连续的字(32位)存储单元并用伪指令中指定的表达式初始化。其中,表达式可以为程序标号或数字表达式,DCD也可用“&”代替
用DCD分配的字存储单元是字对齐的,而用DCDU分配的字存储单元并不严格字对齐
示例:
xxxxxxxxxx
DataTest DCD4,5,6 ;分配3个连续的字存储单元并用4,5,6初始化
DCFD(或DCFDU)
语法格式:
xxxxxxxxxx
标号 DCFD(或DCFDU) 表达式;
DCFD(或DCFDU)伪指令用于为双精度的浮点数分配一段连续的字存储单元并用伪指令中指定的表达式初始化,每个双精度的浮点数占据两个字单元
用DCFD分配的字存储单元是字对齐的,而用DCFDU分配的字存储单元并不严格字对齐
示例:
xxxxxxxxxx
FDataTest DCFD 0.1,0.2,0.3 ;分配3个连续的双字存储单元并初始化为0.1,0.2,0.3的双精度数表达
DCFS(或DCFSU)
语法格式:
xxxxxxxxxx
标号 DCFS(或DCFSU) 表达式;
DCFS(或DCFSU)伪指令用于为单精度的浮点数分配一段连续的字存储单元并用伪指令中指定的额表达式初始化,每个单精度的浮点数占据一个字单位
用DCFS分配的字存储单元是字对齐的,而用DCFSU分配的字存储单元并不严格字对齐
示例:
xxxxxxxxxx
FDataTest DCFS-0.1,-0.2,-0.3 ;分配3个连续的字存储单元并初始化为-0.1,-0.2,-0.3的单精度数表达
DCQ(或DCQU)
语法格式:
xxxxxxxxxx
标号 DCQ(或DCQU) 表达式;
DCQ(或DCQU)伪指令用于分配一段以8个字节为单位的连续存储区域并用伪指令中指定的表达式初始化
用DCQ分配的存储单元是字对齐的,而用DCQU分配的存储单元并不严格字对齐
示例:
xxxxxxxxxx
DataTest DCQ 100,101,102;分配3个连续的双字内存单元,并用100D,101D,102D的16进制数据进行初始化
SPACE
语法格式:
xxxxxxxxxx
标号 SPACE 表达式;
SPACE伪指令用于分配一片连续的存储区域并初始化为0,其中,表达式为要分配的字节数,SPACE也可用“%”代替
示例:
xxxxxxxxxx
DataSpace SPACE 100 ;分配连续100字节的存储单元并初始化为0
MAP
语法格式:
xxxxxxxxxx
MAP 表达式 {,基址寄存器};
MAP伪指令用于定义一个结构化的内存表的首地址,可以用“^”代替
表达式可以为程序中的标号或数学表达式,基址寄存器可为可选项,当基址寄存器选项不存在时,表达式的值即为内存表的首地址,当该选项存在时,内存表的首地址为表达式的值与基址寄存器的和
示例:
xxxxxxxxxx
MAP 0x100, R0 ;定义结构化内存表首地址的值为0x100+R0
FIELD
语法格式:
xxxxxxxxxx
标号 FIELD 表达式;
FIELD伪指令常与MAP伪指令配合使用来定义结构化的内存表。MAP伪指令定义内存表的首地址,FIELD伪指令定义内存表中的各个数据域,并可以为每个数据域指定一个标号供其他的指令引用
表达式的值为当前数据域在内存表中所占的字节数
注意:MAP和FIELD伪指令仅用于定义数据结构,并不实际分配存储单元
示例:
xxxxxxxxxx
MAP 0x100 ;定义结构化内存表首地址的值为0x100
A FIELD 16 ;定义A的长度为16字节,起始位置为0x100
B FIELD 32 ;定义B的长度为32字节,起始位置为0x110
S FIELD 256 ;定义S的长度为256字节,起始位置为0x130
汇编控制伪指令用于控制汇编程序的执行流程,常用的汇编控制伪指令包括:
IF、ELSE、ENDIF
语法格式:
xxxxxxxxxx
IF 逻辑表达式
指令序列1
ELSE
指令序列2
ENDIF
IF、ELSE、ENDIF可嵌套使用
示例:
xxxxxxxxxx
GBLL Test ;声明一个全局的逻辑变量,变量名为Test
......
IF Test=TRUE
指令序列1
ELSE
指令序列2
ENDIF
WHILE、WEND
语法格式:
xxxxxxxxxx
WHILE 逻辑表达式
指令序列
WEND
WHILE和WEND可以嵌套使用
xxxxxxxxxx
GBLA Counter ;声明一个全局的数学变量,变量名为Counter
Counter SETA 3 ;由变量Counter控制循环次数
......
WHILE Counter<10
指令序列
WEND
MACRO、MEND
语法格式:
xxxxxxxxxx
MACRO
{$标号} 宏名 {$参数1, $参数2,......}
指令序列
MEND
MACRO、MEND伪指令可以将一段代码定义为一个整体,两条指令称为宏指令,需要时可以在程序中通过宏指令多次调用这段代码
其中,$标号在宏指令被展开时会被替换成用户定义的符号。宏指令可以使用一个或多个参数,当宏指令被展开时,这些参数被相应的值替换
包含在MACRO和MEND之间的指令序列称为宏定义体,在宏定义体的第一行应声明宏的原型(包含宏名、所需的参数),然后就可以在汇编程序中通过宏名来调用该指令序列。在源程序被编译时,汇编器将宏调用展开,用宏定义中的指令序列代替程序中的宏调用,并将实际参数的值传递给宏定义中的形式参数
宏指令的使用方式和功能与子程序有些香相似,子程序可以提供模块化的程序设计、节省存储空间并提高运行速度。但在使用子程序结构时需要保护现场,从而增加了系统开销。因此,在代码较短且需要传递的参数较多时,可以使用宏指令代替子程序
MACRO、MEND伪指令可嵌套使用
示例:
xxxxxxxxxx
MACRO ;宏指令开始
$label test $p1,$p2,$p3 ;宏的名称为test,有三个参数p1,p2,p3
;宏的标号$label可用于构造宏定义体内的其他标号名称
CMP $p1,$p2 ;比较参数p1和p2的大小
BHI $label.save ;无符号比较后若p1>p2,跳转到$label.save标号处,
;$label.save为宏定义体的内部符号
MOV $p3,$p2
B $label.end
$label.save MOV $p3,$p1
$label.end ;宏定义功能即将参数p1,p2无符号比较后的大值存入参数p3
MEND ;宏定义结束
上述代码中,宏名为test,标号为$label,有三个参数$p1,$p2,$p3。标号和参数在实际调用中可根据需要替换成不同的符号,而宏名是唯一确定的
调用上述宏的方法:
xxxxxxxxxx
abc test R0,R1,R2 ;通过宏的名称test调用宏,宏的标号为abc
;三个参数为寄存器R0,R1,R2
汇编处理宏时会展开还原成一段代码,结果如下:
xxxxxxxxxx
CMP R0,R1
BHI abc.save
MOV R2,R1
B abc.end
abc.save MOV R2,R0
abc.end
......
采用宏定义的方法可以用一条语句代替一大段指令序列,提高编程效率
MEXIT
语法格式:
xxxxxxxxxx
MACRO ;宏定义开始
{$标号} 宏名 {$参数1,$参数2,......}
指令序列;
IF condition1
MEXIT
ELSE
指令序列;
ENDIF
...
MEND
AREA
语法格式:
xxxxxxxxxx
AREA 段名 属性1,属性2,......
AREA伪指令用于定义一个代码段或数据段,段名若以数字开头,则该段名需用“|”括起来,如|1_test|
属性字段表示该代码段(或数据段)的相关属性,多个属性用逗号分隔。常用属性如:
示例:
xxxxxxxxxx
AREA RESET,CODE,READONLY
...
;该伪指令定义了一个代码段,段名为RESET,属性为只读
ALIGN
语法格式:
xxxxxxxxxx
ALIGN{表达式{,偏移量}};
ALIGN伪指令可以通过添加填充字节的方式,使当前位置满足一定的对齐方式
表达式的值用于指定对齐方式,可能取值为2的幂,如1,2,4,8,16等。若未指定表达式,则将当前位置对齐到下一个字的位置
偏移量也为一个数字表达式,若使用该字段,假设N=表达式,则当前位置的对齐方式为:2N+偏移量
示例:
xxxxxxxxxx
AREA RESET,CODE,READONLY,ALIGN=3 ;指定后面的指令为8字节对齐
......
END
CODE16、CODE32
语法格式:
xxxxxxxxxx
CODE16(或CODE32);
若在汇编源程序中同时包含有ARM指令和Thumb指令,可用CODE16伪指令通知编译器其后的指令序列为16位的Thumb指令,CODE32伪指令通知编译器其后的指令序列位32位的ARM指令
在使用ARM指令和Thumb指令混合编程的代码中,可用这两条伪指令进行切换,注意他们只通知编译器其后指令的类型,并不能对处理器的状态进行切换
示例:
xxxxxxxxxx
AREA RESET,CODE,READONLY
......
CODE32 ;通知编译器其后的指令为32位的ARM指令
LDR R0,=NEXT+1 ;将跳转地址放入寄存器R0
BX R0 ;程序跳转到新的位置执行,并将处理器切换到Thumb工作状态
......
CODE16 ;通知编译器其后的指令为16位的Thumb指令
NEXT LDR R3,=0x3FF
......
END ;程序结束
ENTRY
语法格式:
xxxxxxxxxx
ENTRY;
ENTRY伪指令用于指定汇编程序的入口点。在一个完整的汇编程序中至少要有一个ENTRY,但在一个源文件里最多只能有一个ENTRY
示例:
xxxxxxxxxx
AREA RESET,CODE,READONLY
ENTRY ; 指定应用程序的入口点
......
END
语法格式:
xxxxxxxxxx
END;
END伪指令用于通知编译器已经到达源程序的结尾
示例:
xxxxxxxxxx
AREA RESET,CODE,READONLY
......
END ;指定应用程序的结尾
EQU
语法格式:
xxxxxxxxxx
名称 EQU 表达式{,类型};
EQU伪指令用于为程序中的常量、标号等一个等效的字符名称,类似于C语言中的#define。其中EQU可用“*”代替
示例:
xxxxxxxxxx
Test EQU 50 ;定义标号Test的值为50
EXPORT(或GLOBAL)
语法结构:
xxxxxxxxxx
EXPORT 标号 {[WEAK]};
EXPORT伪指令用于在程序中声明一个全局的标号,该标号可在其他文件中引用。EXPORT可用GLOBAL代替。标号在程序中区分大小写,[WEAK]选项声明其他的同名标号优先于该标号被引用
示例:
xxxxxxxxxx
AREA RESET,CODE,READONLY
EXPORT Stest ;声明一个全局的标号Stest
.....
END
IMPORT
语法格式:
xxxxxxxxxx
IMPORT 标号 {[WEAK]};
IMPORT伪指令用于通知编译器要使用的标号在其他源文件中的定义,但要在当前源文件中引用,而且无论当前源文件是否引用该标号,该标号均会被加入到当前源文件的符号表中
标号在程序中区分大小写,[WEAK]选项表示当所有的源文件都没有定义这样一个标号时,编译器也不给出错误信息,在多数情况下将该标号置为0,若该标号被B或BL指令引用,则将B或BL指令置为NOP操作
示例:
xxxxxxxxxx
AREA RESET,CODE,READONLY
IMPORT MAIN ;通知编译器当前文件要引用标号MAIN,但MAIN在其他源文件中定义
......
END
EXTERN
语法格式:
xxxxxxxxxx
EXTERN 标号 {[WEAK]};
EXTERN伪指令用于通知编译器要使用的标号在其他的源文件中定义,但要在当前源文件中引用。如果当前源文件实际并未引用该标号,该标号就不会被加入到当前源文件的符号表中
示例:
xxxxxxxxxx
AREA RESET,CODE,READONLY
EXTERN Main ;通知编译器当前文件要引用标号Main,但Main在其他源文件中定义
......
END
GET(或INCLUDE)
语法格式:
xxxxxxxxxx
GET 文件名;
GET伪指令用于将一个源文件包含在当前的源文件中,并将被包含的源文件在当前位置进行汇编处理。可以使用INCLUDE代替GET
汇编程序中常用的方法是在某源文件中定义一些宏指令,用EQU定义常量的符号名称,用MAP和FIELD定义结构化的数据类型,然后用GET伪指令将这个源文件包含到其他的源文件中。使用方法与C语言中的“INCLUDE”相似
GET伪指令只能用于包含源文件,包含目标文件需要使用INCLUDE伪指令
示例:
xxxxxxxxxx
AREA RESET,CODE,READONLY
GET a1.s ;通知编译器当前源文件包含当前目录下的a1.s文件
GET C:/a2.s ;通知编译器当前源文件包含C盘根目录下的a2.s文件
......
END
INCBIN
语法格式:
xxxxxxxxxx
INCBIN 文件名;
INCBIN伪指令用于将一个目标文件或数据文件包含到当前的源文件中,被包含的文件不作任何变动的存放到当前文件中,编译器不对文件内容进行编译,编译器从其后开始继续处理
示例:
xxxxxxxxxx
AREA RESET,CODE,READONLY
GET a1.s
INCBIN a1.dat ;通知编译器当前源文件包含a1.dat
INCBIN C:/a2.txt ;通知编译器当前源文件包含C盘根目录下文件a2.txt
......
END
RN
语法格式:
xxxxxxxxxx
名称 RN 表达式;
RN伪代码用于给一个寄存器定义一个别名
其中,名称为给寄存器定义的别名,表达式为寄存器的编码
xxxxxxxxxx
Temp RN R0 ;将R0定义一个别名Temp
ROUT
语法格式:
xxxxxxxxxx
{名称} ROUT
ROUT伪指令用于给一个局部变量定义作用范围
在程序中未使用该伪指令时,局部变量的作用范围为所在的AREA,而使用ROUT后,局部变量的作用范围为当前ROUT和下一个ROUT之间
汇编语言程序设计的符号定义应遵循的约定:
程序中的变量
程序中的变量是指其值在程序的运行过程中可以改变的量。ARM(Thumb)汇编程序所支持的变量有数字变量、逻辑变量和字符串变量。
数字变量用于在程序的运行中保存数字值,但注意数字值的大小不应超出数字变量所能表示的范围。
逻辑变量用于在程序的运行中保存逻辑值,逻辑值只有两种取值情况:真或假。
字符串变量用于在程序的运行中保存一个字符串,但注意字符串的长度不应超出字符串变量所能表示的范围
在ARM汇编语言程序设计中,可以使用GBLA、GBLL、BGLS伪指令声明全局变量,使用LCLA、LCLL、LCLS伪指令声明局部变量,并可使用SETA、SETL、SETS进行初始化
示例:
xxxxxxxxxx
LCLS S1 ;
LCLS S2 ;定义局部字符串变量S1和S2
S1 SETS "Test!" ;字符串变量S1的值为"Test!"
S2 SETS "Hello!";字符串变量S2的值为"Hello!"
程序中的常量
程序中的常量是指其值在程序的运行过程中不能被改变的量。ARM(Thumb)汇编程序所支持的常量有数字常量、逻辑常量和字符串常量
数字常量一般为32位的整数,当作为无符号数时,其取值范围为0~232-1,当作为有符号数时,其取值范围为-231~232-1
逻辑常量只有两种取值情况:真或假
字符串常量为一个固定的字符串,一般用于程序运行时的信息提示
示例:
xxxxxxxxxx
NUM EQU 64
abcd EQU 2 ;定义abcd符号的值为2
abcd EQU label+16 ;定义abcd符号的值为(label+16)
abcd EQU 0x1c,CODE32 ;定义abcd的符号的值为绝对地址值0x1c,而且此处为ARM32指令
对比:EQU指令 vs “=”
程序中的变量代换
程序中的变量可以通过代换操作取得一个常量。代换操作符为"$"
如果在数字变量前面有一个代换操作符“$”,编译器会自动将该数字的值转换为十六进制的字符串,并将十六进制的字符串代换“$”后的数字变量
如果在逻辑变量前面有一个代换操作符"$",编译器会将该逻辑变量代换为它的取值(真或假)
如果在字符串变量前面有一个代换操作符“$”,编译器会将该字符串变量的值代换“$”后的字符串变量
示例:
xxxxxxxxxx
LCLS S1 ;定义局部字符串变量S1和S2
LCLS S2
S1 SETS "Test!"
S2 SETS "This is a $S1" ;字符串变量S2的值为"This is a Test!"
运算次序与优先级:
数学表达式及运算符
运算符 | 用法 | 作用 |
---|---|---|
+ | X+Y | X与Y的和 |
- | X-Y | X与Y的差 |
x | XxY | X与Y的乘积 |
/ | X/Y | X除以Y的商 |
MOD | X:MOD:Y | X除以Y的余数 |
ROL | X:ROL:Y | 将X循环左移Y位 |
ROR | X:ROR:Y | 将X循环右移Y位 |
SHL | X:SHL:Y | 将X左移Y位 |
SHR | X:SHR:Y | 将X右移Y位 |
AND | X:AND:Y | 将X和Y按位作逻辑与的操作 |
OR | X:OR:Y | 将X和Y按位作逻辑或的操作 |
NOT | :NOT:Y | 将Y按位作逻辑非的操作 |
EOR | X:EOR:Y | 将X和Y按位作逻辑异或的操作 |
逻辑表达式及运算符
运算符 | 用法 | 作用 |
---|---|---|
= | X=Y | X等于Y |
> | X>Y | X大于Y |
< | X<Y | X小于Y |
`>=` | X>=Y | X大于等于Y |
`<=` | X<=Y | X小于等于Y |
/= | X/=Y | X不等于Y |
<> | X<>Y | X不等于Y |
LAND | X:LAND:Y | 将X和Y作逻辑与操作 |
LOR | X:LOR:Y | 将X和Y作逻辑或操作 |
LNOT | :LNOT:Y | 将Y作逻辑非操作 |
LEOR | X:LEOR:Y | 将X和Y作逻辑异或操作 |
字符串表达式及运算符
运算符 | 用法 | 作用 |
---|---|---|
LEN | :LEN:X | 返回字符串长度 |
CHR | :CHR:M | 将0~255之间的整数转换为一个字符 |
STR | :STR:X | 将一个数字表达式或逻辑表达式转换为一个字符串 |
LEFT | X:LEFT:Y | 返回某个字符串左端的一个字串 |
RIGHT | X:RIGHT:Y | 返回某个字符串右端的一个字串 |
CC | X:CC:Y | 用于将两个字符串连接成一个字符串 |
与寄存器和程序计数器PC相关的表达式及运算符
运算符 | 用法 | 作用 |
---|---|---|
BASE | :BASE:X | 返回基于寄存器的表达式中寄存器的编号 |
INDEX | :INDEX:X | 返回基于寄存器的表达式中相对于其基址寄存器的偏移量 |
其他运算符
运算符 | 用法 | 作用 |
---|---|---|
? | ?X | 返回某代码行所生成的可执行代码的长度 |
DEF | :DEF:X | 判断是否定义某个符号 |
RM汇编中语句中所有标号必须在一行的顶格书写,其后面不要添加“:”,而所有指令均不能顶格书写。ARM汇编器对标识符大小写敏感,书写标号及指令时字母大小写要一致,在ARM汇编程序中,一个ARM指令、伪指令、寄存器名可以全部为大写字母,也可以全部为小写字母,但不要大小写混合使用
ARM汇编语句的格式如下:
xxxxxxxxxx
[LABEL] OPERATION [OPERAND] [;COMMENT]
;标号域 ;操作助记符域 ;操作数域 ;注释域
标号域
操作助记符域
操作数域
在ARM(Thumb)汇编语言程序中,通常以段为单位来组织代码段是具有特定名称且功能相对独立的指令或数据序列根据段的内容,分为代码段和数据段
一个汇编程序至少应该有一个代码段,当程序较长时,可以分割为多个代码段和数据段
一个汇编语言程序段的基本结构如下所示:
xxxxxxxxxx
AREA Buf, DATA, READWRITE ;定义一个可读写属性的数据段
Num DCD 0x11
Nums DCD 0x22 ;分配一片连续存储单元并初始化
;本节及下节所有汇编代码程序都是利用MDKIDE编写,Device设置为STM32F407ZG,
;代码段放在IROM中起始地址为0x08000000,数据段放在IRAM中起始地址为0x20000000
AREA RESET,CODE,READONLY ;只读的代码段,RESET为段名
ENTRY ;程序入口点
START LDR R0,= Num ;取Num地址赋给R0
LDRR1,[R0] ;取Num中内容赋给R1
ADD R1,#0x9A; R1=R1+0x9A
STR R1,[R0] ;R1内容赋给Num单元
LDR R0,= Nums ;......
LDR R2,[R0]
ADD R2,#0xAB
STR R2,[R0]
LOOP B LOOP ;无限循环反复执行
END ;段结束
顺序结构
顺序结构是一种最简单的程序结构,这种程序按指令排列的先后顺序逐条执行
示例:对数据段中数据进行寻址操作
xxxxxxxxxx
AREA BUF,DATA,READWRITE ;定义数据段Buf
Array DCB 0x11,0x22,0x33,0x44
DCB 0x55,0x66,0x77,0x88
DCB 0x00,0x00,0x00,0x00 ;定义12个字节的数组Array
AREA RESET,CODE,READONLY
ENTfRY
LDR R0,=Array ;取得数组Array首地址
LDR R2,[R0] ;从数组第1字节取32位数据给R2即R2=0x44332211
MOV R1,#1 ;R1=1
LDR R3,[R0,R1,LSL#2] ;将存储器地址为R0+R1x4的32位数据读入寄存器R3,
;R3=0x88776655
LOOP B LOOP
END
分支结构
一般情况下,程序按指令的先后顺序逐条执行,但经常要求程序根据不同条件选择不同的处理方法,利用条件指令或条件转移指令根据当前CPSR中的状态标志值选择路径,使用带有条件码的指令实现的分支程序段
分支结构中经常使用的条件码助记后缀:
例如寄存器中R0和R1分别保存两个数,如果R0小于R1,将R1值传给R0,实现代码如下:
xxxxxxxxxx
CMP R0,R1 ;比较R0和R1
MOVLT R0,R1 ;MOVLT=MOV+LT LT是有符号数比较小于
分支结构的几种实现方法:
利用条件码可以很方便地实现IF ELSE分支结构地程序
xxxxxxxxxx
MOV R0,#76 ;初始化R0的值
MOV R1,#88 ;初始化R1的值
CMP R0,R1 ;判断R0>R1?
MOVHI R2,#100 ;R0>R1时,R2=100
MOVLS R2,#50 ;R0<=R1时,R2=50
......
B(Branch)条件转移及衍生指令实现分支结构
B指令
格式:
xxxxxxxxxx
B(条件)+目标地址
用法:B指令是最简单的跳转指令,一旦遇到一个B指令,ARM处理器将立即跳转到给定的目标地址,从那里继续执行
示例:
xxxxxxxxxx
B Label ;程序无条件跳转到标号Label处执行
示例:
xxxxxxxxxx
CMP R1, #0
BEQ Label ;当CPSR寄存器中Z条件码置位时,程序跳转到标号Label处执行
......
BL指令
格式:
xxxxxxxxxx
BL{条件}+目标地址
用法:BL是一个跳转指令,但跳转之前,会在寄存器R14中保存PC当前的内容。因此,可以通过将R14的内容重新加载到PC中,来返回到跳转指令之后的那个指令处执行。这个指令是实现子函数调用的一个基本且常用的手段
xxxxxxxxxx
BL Label ;让程序无条件跳转到标号是Label处执行,同时将当前的PC值保存到R14(LR)中。
BL实现子函数调用时完成如下的三个操作:
使用BL调用子程序后,通常在子程序的尾部添加MOV PC,LR来返回
循环结构
循环结构可以减少源程序重复书写的工作量,用来描述重复执行某段算法的问题,这是程序设计中最能发挥计算机特长的程序结构
for循环结构实现
C语言形式:
xxxxxxxxxx
for(int i=0;i<1-;i++)
x++;
ARM汇编语言形式:R0为x,R2为i,均为无符号整数
xxxxxxxxxx
MOV R0,#0 ;初始化R0=0
MOV R2,#0 ;初始化R2=0
LOOP CMP R2,#0 ;判断R2<10?
BCS FOR_E ;若条件失败(即R>=10),退出循环
ADD R0,R0,#1 ;执行循环体,R0=R0+1,即x++
ADD R2,R2,#1 ;R2=R2+1,即i++
B LOOP
FOR_E......
while循环结构实现
C语言形式:
xxxxxxxxxx
while(x<=y)
x*=2;
ARM汇编语言形式:x为R0,y为R1,均为无符号整数
xxxxxxxxxx
MOV R0,#1 ;初始化R0=1
MOV R1,#20 ;初始化R1=20
W1 CMP R0,R1 ;判断R0<=R1,即x<=y
MOVLS R0,R0,LSL#1 ;循环体,R0*=2
BLS W1 ;若R0<=R1,继续循环体
W_END
子程序调用与返回
在ARM汇编语言中,子程序的调用一般是通过BL指令来完成的
BL指令的语法格式如下:
xxxxxxxxxx
BL SUB
SUB是被调用的子程序的名称
BL指令完成2个操作,即将子程序的返回地址放在LR寄存器中,同时将PC寄存器指向子程序的入口点,当子程序执行完毕需要返回主程序时,只需将存放在LR中的返回地址重新赋给指令指针寄存器PC即可。通过调用子程序,能够完成参数的传递和从子程序返回运算的结构(通常使用寄存器R0-R3来完成)
BL调用子程序的经典用法如下:
xxxxxxxxxx
BL NEXT ;跳转NEXT
......
NEXT
......
MOV PC, LR ;从子程序返回
当子程序需要使用的寄存器与主程序使用的寄存器发生冲突(即子程序与主程序都要使用同一组寄存器时),为了防止主程序这些寄存器中的有用数据丢失,在子程序的开始应该把这些寄存器数据压入堆栈以保护现场,在子程序返回之前需要把保护到堆栈的数据自堆栈中弹出以恢复现场
PUSH{R4,LR}
将寄存器R4入栈,LR也入栈。POP{R4,PC}
将堆栈中的数据弹出到寄存器R4及PC中PUSH{R0-R7,LR}
将寄存器R0-R7全部入栈,LR也入栈;POP{R0-R7,PC}
将堆栈中的数据弹出到寄存器R0-R7及PC中STMFD SP!,{R0-R7,LR};
功能是满递减入栈,将寄存器R0-R7、LR压栈,SP不断减4,执行后SP=SP-9*4[SP]=R0,[SP+4]=R1,....,[SP+4*8]=LRLDMFD SP!,{R0-R7,PC};
满递减出栈,给寄存器R0-R9出栈,并使程序跳转回函数的调用点,SP不断增4;同理,LDMFD是STMFD的逆操作,[SP]->R0,[SP+4]->R1,...,[SP+4*8]->PCSP=SP+4*9
注意:BLSUB...MOVPC,LR这种调用子程序结构在一些情况下是会出现问题的,例如当出现子程序嵌套调用时,LR寄存器中内容在第二次子程序调用时会被覆盖,如果仍使用常用调用方式会出现无法返回现场的问题,这个时候使用STMFD/LDMFD指令可以有效避免LR被覆盖而出现错误
示例:
xxxxxxxxxx
AREA RESET,CODE,READONLY
ENTRY
START LDR SP,=0x20000460
MOV R0,#0x03
MOV R1,#0x04
MOV R7,#0x07
BL POW
LOOP B LOOP
POW STMFD SP!, {R0-R7,LR}
MOVS R2,R1
MOVEQ R0,#1
BEQ POW_END
MOV R1,R0
SUB R2,R2,#1
POW_L1 BL DO_MUL ;子程序调用嵌套,这个时候如果不用指令会出现LR覆盖,FD/LDMF,影响子程序调用返回
SUBS R2,R2,#1
BNE POW_L1
POW_END LDMFD SP!,{R0-R7,PC}
DO_MUL MUL R0,R1,R0
MOV PC.LR
END
ATPCS概述
为了使单独编译的C语言程序和汇编程序之间能够相互调用,必须为子程序之间的调用制定一定的规则。ATPCS就是ARM程序和Thumb程序中子程序调用的基本规则
ATPCS(ARM-ThumbProcedureCallStandard,基于ARM指令集和Thumb指令集过程调用规则)规定了一些不同语言撰写的函数之间相互调用(mixcalls)的基本规则,这些基本规则包括子程序调用过程中寄存器的使用规则、数据栈的使用规则、以及参数的传递规则
TPCS规定了在子程序调用时的一些基本规则,主要包括以下3方面的内容:
各寄存器的使用规则及其相应的名字;
数据栈的使用规则(FD);
参数传递的规则;
C程序调用汇编函数实例
ARM编译器使用的函数调用规则就是ATPCS标准,也是设计可被C程序调用的汇编函数的编写规则。为了保证程序调用时参数传递正确,C程序调用的汇编函数时必须严格按照ATPCS规则
如果汇编函数和调用函数的C程序不在同一个文件中,则需要在汇编语言中用EXPORT声明汇编语言起始处的标号为外部可引用符号,该标号应该为C语言中所调用函数的名称
例:调用汇编函数,实现把字符串srcstr复制到dsstr中
xxxxxxxxxx
//main.c
extern void strcopy(char*d,char*s);//需要调用的汇编函数原型并加extern关键字
int main()
{
char* srcstr="0123456";
chardststr[]="abcdefg";
strcopy(dststr,srcstr);
return 0;
}
汇编语言源程序Scopy.s,汇编文件和*.c文件在同一工程中
xxxxxxxxxx
AREA Scopy,CODE,READONLY
EXPORTstrcopy
strcopy;必须与EXPORT后面标号一致
LOOP LDRB R2,[R1],#1;R1指向源地址
STRB R2,[R0],#1;R0指向目标地址
CMP R2,#0
BNE LOOP;先执行后判断,源字符串的终止符‘\0’
;也复制到目的字符串
MOV PC,LR
END
汇编程序调用C函数实例
在汇编程序中调用C语言函数,需要在汇编程序中利用IMPORT说明对应的C函数名,按照ATPCS的规则保存参数。完成各项准备工作后利用跳转指令跳转到C函数入口处开始执行。跳转指令后所跟标号为C函数的函数名
例:汇编程序中调用C函数实现求5个整数相加的和;test.s,工程设置为基于汇编的工程,不需要从main函数启动,代码段名称必须设为RESET
xxxxxxxxxx
PRESERVE8
AREA RESET,CODE,READONLY
ENTRY
IMPORT CAL;
LDR SP,=0x20000460;设置堆栈指针
MOV R0,#1;R0=1
ADD R1,R0,R0;R1=2
ADD R2,R1,R0;R2=3
ADD R3,R0,R2;R3=4
ADD R4,R0,R3;R4=5
STR R4,[SP,#-4]!
BL CAL
LDR R4,=0x20000000;结果R0存入内存单元
STR R0,[R4]
END
xxxxxxxxxx
//C源程序example.c和汇编文件在同一个工程中
int CAL(int a, int b, int c, int d, int e)
{
return (a+b+c+d+e);
}
嵌入式系统开发中,目前使用的主要编程语言是C和汇编,C++已经有相应的编译器,但是现在使用还是比较少的。在稍大规模的嵌入式软件中,大部分的代码都是用C编写的
C语言中使用内嵌汇编代码,可以在C/C++程序中实现C/C++不能完成的一些操作,同时程序的代码效率也会更高
在C语言程序中嵌入汇编指令
如果要在C程序中嵌入汇编有两种方法:内联汇编和内嵌汇编。嵌入汇编使用的标记是__asm或者asm关键字,用法如下:
xxxxxxxxxx
__asm
{
instruction [;instruction]
...
[instruction]
}
asm(“instruction[;instruction]”);
内联汇编的示例代码如下:
xxxxxxxxxx
int Add(int i)
{
int R0;
__asm
{
ADD R0,i,1
EOR i,R0,i
}
return i;
}
内嵌汇编的示例代码如下:
xxxxxxxxxx
#include<stdio.h>
__asm void my_strcpy(const char*src,char*dst)
{
LOOP LDRB R2,[R0],#1;R0保存第一个参数
STRB R2,[R1],#1;R1保存第二个参数
CMP R2,#0
BNE LOOP BLX LR;返回指令须要手动加入
}
xxxxxxxxxx
int main(void)//主程序
{
constchar*a="Helloworld!";
char b[20];
my_strcpy(a,b);//调用内嵌汇编程序
return 0;
}
由两种方法的示例可以看出:内联汇编可以直接嵌入C代码使用,而内嵌汇编更像一个函数。由于内联式汇编只能在ARM状态中进行,而Cortex-M3/M4只支持Thumb-2,所以Cortex-M3/M4只能使用内嵌汇编的方式,也就是第二种方法
在C语言中内嵌汇编指令与汇编程序中的指令有些不同,存在一些限制,主要有下面几个方面:
示例:在C程序中使用内联汇编代码实现字符串复制
xxxxxxxxxx
#include<stdio.h>
void my_strcpy(constchar*src,char*dest)
{
charch;__asm//注意是双下划线
{
LOOP:
LDRB ch,[src],#1
STRB ch,[dest],#1
CMP ch,#0
BNE LOOP
}
}
int main()
{
char* a="ok!";
char b[64];
my_strcpy(a,b);
return 0;
}
在汇编中调用C语言定义的函数和全局变量
硬件平台:
核心控制模块:嵌入式处理器+电源电路、时钟电路、存储器电路
软件平台:应用层、操作系统OS层、驱动层
硬件
软件
开发工具(如:ARM/KEIL MDK和IAR EWARM)
软件资源,包括:
文档
开发环境
宿主机(如:通用PC,用于:编写、编译、链接等,生成可在目标机上执行的二进制代码)
目标机(系统实际运行环境,如:ARM处理器)
宿主机和目标机之间的连接
开发工具
嵌入式软件开发阶段及其工具:
集成开发工具KEIL MDK的组成
调试方法
片上调试OCD图示:
基于JTAG的嵌入式调试环境:
需求分析(系统规格说明书,含功能性/非功能性需求)
系统设计(也称总体/概要设计)
系统实现(又称详细设计,包括硬件和软件实现)
系统测试(包括:测试方法、工具及步骤)
系统发布
特性:
结构原理
引脚及连接模块
端口寄存器与操作
3个32位用于引脚功能选择寄存器,即:
控制寄存器操作时,建议采用:“读→修改→写回”方式
好处是:
系统总线
I-Code总线;指令预取
D-Code总线;数据加载和调试访问
系统总线
DMA总线
总线矩阵;含:
4个驱动部件(CPU的D-Code、系统总线、DMA1/2总线)
4个被动部件(FLITF、SRAM、FSMC和AHB-APB桥)
AHB-APB桥;共两个,AHB和两个APB总线间连接
程序、数据存储器、所有外设都统一编址(4GB);各自有固定存储空间区域,使用不同总线进行访问
Cortex-M3内核,视为CPU,通过相应总线再经总线矩阵与程序、数据存储器、所有外设相接并控制其读写访问
外设分为高速/低速两类,各自通过桥接再通过AHB系统总线连至总线矩阵,实现与内核的接口;外设时钟可各自配置;两种访问操作方式:CPU直接操作和DMA方式
系统时钟,均由复位与时钟控制器RCC产生,为系统和各外设提供所需时钟以确定各自工作速度
功能模块
系统模块
辅助和维护正常工作,如:电源、外部晶振、内部RC振荡器、锁相环PLL、复位和时钟控制RCC、实时时钟、看门狗Watchdog和循环冗余校验CRC等
通信模块
与标准通信接口外设间数据交换,如:USART、SPI、I2C、USB、CAN和SDIO
虚拟模块
对模拟信号的处理,如:ADC、DAC
控制模块
对电机等设备控制和操作,如:定时器
性能简介
系统复位
复位除备份区域的寄存器以外所有寄存器
(时钟控制状态寄存器RCC_CSR中复位标志不会复位)
触发一个系统复位有数种方式:
电源复位
备份区域复位
仅影响备份区域,有两个专门的复位:
复位电路:延时,使CPU保持复位,暂不进入工作状态(防止执行错误指令),确保其及各部件处于确定的初始状态,直至电压稳定复位电路直接影响系统稳定性和可靠性
内部RC振荡器与外部晶振的选择
内部RC振荡器:可为PLL提供时钟,不够准确稳定,误差1%左右,精度通常比外部晶振低10倍以上
外部主时钟源:高速外部时钟HSE,两种时钟源产生
STM32时钟树
时钟树图中的序号解释:
①:输入,外部晶振HSE,可选为2~16MHZ
②:第一个分频器PLLXTPRE,可选1分频/2分频
③:时钟源选择,开关PLLSRC,可选其输出为:外部高速时钟HSE或内部高速时钟HSI
④:锁相环PLL,具有倍频功能(2~16),经过PLL的时钟称为PLLCLK(若设9倍频,即从8MHz的HSE变为72MHz)
⑤:开关SW,经过SW后即系统时钟SYSCLK。SW可选SYSCLK时钟源为:HSI、PLLCLK、HSE
⑥:AHB预分频器(分频系数为1/2/4/8/16/64/128/256/512)
⑦:APB2预分频器(分频系数为1/2/4/8/16)。若为1,则高速外设APB2(PCLK2)为72MHz(AHB输出为72MHz时)
时钟树从左至右,相关时钟可依次分为:
输入时钟
从时钟频率分:高速/低速时钟;从芯片角度分:内部时钟(片内时钟)/外部时钟源(片外时钟)。有以下5种:
系统时钟SYSCLK
由系统时钟分频所得其他时钟(即SYSCLK经过AHB预分频器输出)
时钟输出的使能及其流程
假设,使用HSE及ST库函数,配置时钟(参数)流程如下:
① 将RCC重新设置为默认值,RCC_DeInit
② 打开HSE,RCC_HSEConfig(RCC_HSE_ON)
③ 等待HSE工作,HSEStartUpStatus=RCC_WaitForHSEStartUP
④ 设置AHB时钟,RCC_HCLKConfig
⑤ 设置高速/低速AHB时钟,RCC_PCLK2Config/RCC_PCLK1Config
⑥ 设置PLL,RCC_PLLConfig
;打开PLL,RCC_PLLCmd(ENABLE)
⑦ 等待PLL工作,while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET))
⑧ 设置系统时钟,RCC_SYSCLKConfig
⑨ 判断PLL是否是系统时钟,while(RCC_GetSYSCLKSource()!=0x08)
⑩ 打开要用外设时钟,RCC_APB2PeriphClockCmd/RCC_APB1PeriphClockCmd
时钟管理寄存器
时钟控制寄存器RCC_CR:使能外部时钟和内部时钟,使能PLL功能;在各种时钟就绪时,置位其中就绪标志并可配置内部时钟的校准和设置偏移量
时钟配置寄存器RCC_CFGR:配置某时钟作为系统时钟SYSCLK;显示当前系统时钟源;配置AHB、APB、ADC的预分频(即配置其时钟频率);选择PLL时钟源,设置倍频系数;选择MCO时钟源
时钟中断寄存器RCC_CIR:使能PLL、HSE、HIS、LSE、LSI就绪中断,显示/清除其就绪中断标志
APB2外设复位寄存器RCC_APB2RSTR
APB1外设复位寄存器RCC_APB1RSTR
AHB外设时钟使能寄存器RCC_AHBENR
APB2外设时钟使能寄存器RCC_APB2ENR
APB1外设时钟使能寄存器RCC_APB1ENR
备份域控制寄存器RCC_BDCR,各位分别为:
控制/状态寄存器RCC_CSR,各位分别为:
各复位标志由硬件置1,由电源复位或软件置RMVF位为1清除;系统复位可清除其余位
时钟系统相关库函数
存放于stm32f10x_rcc.h
和stm32f10x_rcc.c
中
RCC_GetSYSCLKSource
:返回用作系统时钟的时钟源RCC_GetClocksFreq
:返回不同片上总线时钟频率RCC_AHBPeriphClockCmd
:使能/禁止AHB总线上外设时钟RCC_APB2PeriphClockCmd
:使能/禁止APB2总线上外设时钟RCC_APB1PeriphClockCmd
:使能/禁止APB1总线上外设时钟启动代码:上电后程序执行的真正入口,通常包括初始化:异常向量表、时钟、存储器、堆栈,跳转到main函数等,为系统运行做好准备
启动过程:
复位时,STM32F103存储空间和重要寄存器
复位异常服务程序Reset_Handler
的执行过程
嵌入式软件系统结构
驱动层
板级初始化程序及与系统/应用软件相关的驱动
操作系统层
嵌入式内核、文件系统、TCP/IP网络系统、GUI系统和电源管理等
中间件层
嵌入式CORBA、Java等中间件软件
应用层
多个相对独立应用任务(如I/O、计算和通信等)组成
常使用操作系统作为软件平台,由专用引导程序在系统上电时进行系统引导,对底层硬件采用驱动程序方式进行调用,各类应用程序运行于操作系统之上
嵌入式软件系统工作流程
上电复位、板级初始化:堆栈指针寄存器、BSS段及CPU芯片级(如中断控制器和内存等)初始化
系统引导/升级:多种方式
系统初始化:
操作系统等所需:堆栈空间、数据空间,接口和外设等
按特定顺序:内核 → 网络、文件系统 → 中间件
应用初始化:应用任务、信号量和消息队列等创建
多任务应用:多任务状态,操作系统进行任务调度
嵌入式软件系统引导和加载
功能:初始化硬件,建立内存空间映射图,调用操作系统内核
过程:(一般指Bootloader的运行)
嵌入式软件特点
EOS,屏蔽底层硬件差异,为运行其上的应用程序提供统一调用接口,主要完成:内存、多任务及外围设备等的管理
一般,嵌入到微处理器或其他存储载体中,负责全部软硬件资源的分配、调度、控制、协调,提供必要运行环境(各种系统服务供调用,如文件系统、内存分配、I/O存取、中断、任务服务、时间服务、多种通信协议和用户接口函数库等)
与硬件关系紧密,一般需移植/配置
核心体积很小,常需加载/卸载某些模块满足不同功能
(嵌入式系统将所有程序,包括操作系统、驱动及应用程序等均烧写进ROM里执行。EOS更像一套函数库)
EOS的特点:
RTOS(嵌入式实时操作系统ERTOS)
实时,能够在确定时间内完成特定系统功能或中断响应;当外界事件或数据产生时,能够接受并快速处理,其处理结果能在规定时间内控制或响应生产过程
特征主要包括:允许多任务、带有优先级的任务调度、资源的同步访问、任务间通信、定时时钟、所有实时任务受控协调一致运行等
应用RTOS的一般背景:
基于寄存器
基于(ST)固件库
基于操作系统
中间件
如STM32Cube,统一集成化开发平台,整合图形式配置器和初始化C代码生成器,向导功能帮助有效配置微处理器引脚、时钟树和外设接口。配置完成,自动生成初始化C代码
循环轮询系统架构
最简单的,由一个初始化函数和一个无限循环构成
前后台系统架构
工程方式
输出驱动器:多路选择器、输出控制和一对互补的MOS管组成
输入驱动器:TTL肖特基触发器、带开关的上拉电阻电路和带开关的下拉电阻电路组成
输出驱动器
多路选择器:根据设置决定该引脚是普通输出(来自GPIO的输出数据寄存器)还是复用功能AF输出(可能来自多个不同片上外设,同一时刻,一个引脚只能使用这些复用功能中的一个,其他复用功能都处于禁止状态)
输出控制逻辑和一对互补的MOS管:输出控制逻辑根据设置通过控制PMOS管和NMOS管的状态(导通/关闭)决定GPIO输出模式(推挽、开漏还是关闭)
输入驱动器
与输出驱动器不同,输入驱动器没有多路选择开关,输入信号送到输入数据寄存器的同时也送给片上外设,所以输入没有复用功能选项
根据TTL肖特基触发器、上拉电阻端和下拉电阻端两个开关的状态,GPIO的输入可分为以下4种:
注意事项:
对于复用输入功能,端口须配置成输入模式(浮空、上拉或下拉)且输入引脚须由外部驱动
对于复用输出功能,须配置成复用功能输出模式(推挽或开漏)
对于双向复用功能,须配置成复用功能输出模式(推挽或开漏)输入驱动器被配置成浮空输入模式
若端口配置成复用输出功能,则引脚和输出寄存器断开,并和片上外设的输出信号连接,若此外设未被激活,其引脚输出将不确定
GPIO的锁定机制允许冻结I/O配置。当在一个端口上执行了锁定(LOCK)程序,下一次复位前,将不能再更改端口配置
通过对GPIO寄存器编程,可设置每个端口工作模式,包括
例如,GPIOB_CRL就是B组GPIO端口的配置低寄存器,GPIOC_CRH即C组GPIO端口配置高寄存器
输出模式下,常需设置其输出速度(指I/O口驱动电路响应速度,非输出信号速度)
有多个响应速度不同的输出驱动电路,根据需要选择,达到最佳噪声控制和降低功耗目的
一般推荐I/O引脚的输出速度是其输出信号速度的5~10倍
3种选择:2MHz、10MHz和50MHz。常见应用参考:
引脚复用有几种情况:
引脚复用重映射:可把某外设复用功能从(某默认)引脚转移至(某备用)引脚上
可分时复用外设,虚拟增加端口数量,优化引脚配置和布线设计PCB,同时减少信号交叉干扰
复用重映射需设置:复用重映射和调试I/O配置寄存器AFIO_MAPR
复用功能重映射典型举例:
从I/O引脚角度看
从外设复用功能角度看
复用功能重映射的实现:
外部中断映射
事件输出
几乎每个I/O引脚(除端口F和G外)都可用作事件输出如,使用SEV指令产生脉冲,通过事件输出信号将STM32F103从低功耗模式中唤醒
存放于stm32f10x_gpio.h
和stm32f10x_gpio.c
中
常用库函数
GPIO_DeInit
:将GPIOx端口的寄存器恢复为复位启动时的默认值GPIO_Init
:根据GPIO_InitStruct中指定的参数初始化GPIOx端口GPIO_SetBits
:将指定的GPIO端口的一个或多个指定引脚置位GPIO_ResetBits
:将指定的GPIO端口的一个或多个指定引脚复位GPIO_Write
:向指定的GPIO端口写入数据GPIO_ReadOutputDataBit
:读取指定GPIO端口的指定引脚输出值(1b)GPIO_ReadOutputData
:读取指定GPIO端口的输出值(16b)GPIO_ReadInputDataBit
:读取指定GPIO端口的指定引脚的输入值(1b)GPIO_ReadInputData
:读取指定GPIO端口的输入值(16b)GPIO_EXTILineConfig
:选择被用作外部中断/事件线的GPIO引脚初始化结构体
典型库函数——初始化函数GPIO_Init
端口配置低寄存器CRL
其余寄存器
举例:
GPIOD引脚4:50MHz推挽输出,引脚15:上拉下拉输入模式
寄存器设置:CRL.CNF4
为00,CRL.MODE4
为11,CRL.CNF7
为10,CRH.MODE7
为00
xxxxxxxxxx
GPIOD_CRL&=0XFFF0FFFF; //清掉对位4的配置
GPIOD_CRL|=0X00030000; //写位4的配置为0011b(即3)
GPIOD_CRH&=0X0FFFFFFF; //清掉对位15的配置
GPIOD_CRH|=0X8000000; //写位15的配置为1000b(即8)
假设GPIOD位4、位5(即引脚4、5)端口50MHz频率推挽输出
现将位4置1输出高电平,可如下:
xxxxxxxxxx
GPIOD_ODR| =1<<4;//等同于GPIOD_ODR| =0x10;
若写成GPIOD_ODR=0x10
,将PD其他位都清0了,会引发不可预测后果
使位4端口再输出低电平,可如下:
xxxxxxxxxx
GPIOD_ODR&=(~(1<<4)); //等同于GPIOD_ODR& =0xEF(11101111B)
若使位4端口输出低电平,位5端口输出高电平,可如下:
xxxxxxxxxx
GPIOD_ODR&=(~(1<<4));GPIOD_ODR|=1<<5;
需两条语句,且均有回读操作,不适合高实时性。可用BSRR完成:
xxxxxxxxxx
GPIOD_BSRR=0x00100020
避免回读(&=或|=),且一次实现2个引脚操作,效率高,速度快
用BRR完成位4端口输出低电平:
xxxxxxxxxx
GPIOD_BRR=1<<4
GPIO开发三部曲
使用任何一个片上外设,此步都不可少,一般在初始化一开始就进行
GPIO_InitTypeDef
结构体是引脚配置关键,由其成员可快速了解GPIO特性;将指定工作模式和输出速度等写入对应成员,用此结构体变量初始化指定引脚,可实现对引脚真正配置
若引脚设置为输出,操作引脚是往该引脚输出高/低电平
若引脚设置为输入,操作引脚是从该引脚读取高/低电平
STM32F103可编程定时器主要类型:
具有延时、信号频率测量、信号PWM测量、PWM输出、三相六步电机控制及编码接口等功能
从功能上看,基本定时器是通用定时器的子集,通用定时器是高级定时器的子集
基本TIM6和TIM7
通用TIM2、TIM3、TIM4和TIM5
高级TIM1和TIM8
独立的看门狗
窗口看门狗
系统时间定时器SysTick
构成:
计数器是核心,由预分频器驱动,自动重装载预设值
TIM6和TIM7只有最基本的定时功能(提供时间基准),即累计时钟脉冲数超过预设值时,产生定时器溢出事件
如果使能了中断或DMA操作,将产生中断或者DMA操作
定时器时钟源路径:
APB1预分频 → TIMxCLK → CK_INT → 预分频(PSC)→ CK_CNT
基本定时器仅有向上计数模式,自动重装载寄存器ARR保存定时器溢出值/预设值
工作过程:计数器从0开始,在CK_CNT触发下不断累加计数;当计数器CNT计数值等于ARR中预设值时,产生溢出事件,可触发中断或DMA请求(已使能时);然后,CNT计数值被清零,重新开始向上计数
延时时间=(ARR+1)*(PSC+1)/TIMxCLK
其中,ARR(预设值)和PSC(预分频系数)都是16位,取值范围0~65535;TIMxCLK为72MHz(上电复位后,通常值)
更新事件UEV(Update Event)
CR1.URS
位设置,设置更新中断标记SR.UIF
状态(0/1:是/否产生中断或DMA请求),同时所有寄存器均被更新(重复计数器重新装载RCR值;自动重装载寄存器重新置入ARR值,预分频器重置为PSC值)CR1.UDIS
=1,可禁止更新事件(用来避免在写入新寄存器值时更新影子寄存器),在CR1.UDIS
被清零之前,将不产生更新事件。此时,在应产生更新事件时,计数器及预分频器的计数仍被清零,但预分频器数值不变EGR.UG
=1(通过软件方式或使用从模式控制器),同样也可产生一个UEVCR1.URS
=1(选择更新请求),当置EGR.UG
=1时,将产生一个更新事件,但硬件不设置SR.UIF
(即仍为0),即不产生中断或DMA请求,以避免捕获模式下清除计数器时,同时产生更新和捕获中断预分频寄存器PSC:存放分频系数,16位
计数器CNT:存放当前计数值,16位
自动重装载寄存器ARR:决定定时器的上溢时刻(定时周期),当计数器在(向上)计数过程中,计数值达到ARR值,计数器就要归零
时基单元:包含CNT、PSC、ARR三部分(通用和高级定时器另有RCR),这些寄存器均可由软件任意读/写
定时(周期)计算公式:
Tout(μs)=((ARR+1)*(PSC+1))/TCLK(MHz)
影子寄存器shadow和预装载寄存器preload
ARR(作为预装载寄存器)和影子寄存器的关系
根据CR1.APRE的设置,ARR内容:可随时传送到影子寄存器,即两者是连通的(permanently);或在每次更新事件UEV时,才传送到影子寄存器,具体:
CR1.APRE
=0,当ARR值被修改时,同时更新影子寄存器的值(无预装功能)CR1.APRE
=1,ARR值被修改时,须在下次UEV发生后,才更新影子寄存器值(即有缓冲区,预装功能)如需立刻更改影子寄存器的值,而不是等待下一个事件,可有如下两种方法:
使CR1.APRE
=0,即:
xxxxxxxxxx
TIM_ARRPreloadConfig(ch1_Master_Tim, DISABLE)
使CR1.APRE
=1时,更改完ARR后,立刻设置UEV(主动发生UEV),即更改EGR.UG
=1:
xxxxxxxxxx
TIM_GenerateEvent(TIM1,TIM_EventSource_Update)
定时/计数工作过程
CK_CNT
驱动,仅当设置了CR1.CEN
(计数器使能位)时,CK_CNT
才有效CK_CNT
时钟频率按1~65536之间任意值分频CR1.CEN
=1的一个时钟周期后,计数器开始计数;当计数器达到溢出条件并当CR1.UDIS
=0时,产生更新事件,若中断允许,可同时触发中断或DMA请求每个通用定时器:
测量输入脉冲频率/宽度
可输出PWM脉冲
计数器CNT核心构成类似,主要增加:捕获/比较功能
捕获/比较寄存器CCR(Capture/Compare Register)
包括输入捕获部分(数字滤波、多路复用和预分频器)和比较输出部分(比较器和输出控制)
CCR,共用,在输入和输出模式中含义和作用不同:
有多种选择,可由以下四种时钟源提供:
内部时钟CK_INT
与基本定时器相同,来自RCC的TIMxCLK
,APB1预分频器输出(通常为72MHz)。如果禁止了从模式(SMCR.SMS=000),则CR1.CEN
、CR1.DIR
及EGR.UG是事实上的控制位,且只能被软件修改(EGR.UG
位仍会被自动清除)
内部触发输入ITRx
ITRx
来自芯片内部其他定时器的触发输入,使用一个定时器作为另一定时器的预分频器例如,可配置TIM1作为TIM2的预分频器
外部输入捕获引脚TIx
TIx
来自外部输入捕获引脚上的边沿信号;计数器可在选定的输入端(引脚1:TI1FP1
或TI1F_ED
,引脚2:TI2FP2
)的每个上升沿或下降沿计数;也称外部时钟模式1(之一)
配置向上计数器在TI2输入端的上升沿技术,步骤如下,设置:
xxxxxxxxxx
CCMR1.CC2S=01; //配置通道2检测TI2输入的上升沿
CCMR1.IC2F=0000; //不需要滤波器;
CCER.CC2P=0; //选定上升沿极性;
SMCR.SMS=111; //选择定时器外部时钟源模式1;
SMCR.TS=110; //选定TI2作为触发输入源;
CRl.CEN=1; //启动计数器。
SR.TIF
被设置外部触发输入引脚ETR
ETR信号来自外部引脚ETR,计数器能在外部触发输入ETR的每个上升沿或下降沿计数,也称外部时钟模式2
配置在ETR下每2个上升沿计数一次的向上计数器,步骤如下,设置:
xxxxxxxxxx
SMCR. ETP=0; //选择ETR的上升沿检测
SMCR. ETF=0000; //不需要滤波器
SMCR. ETPS=01; //设置预分频器
SMCR. ECE=1; //开启外部时钟源模式2
SMCR.TS=110; //选定TI2作为触发输入源
CRl.CEN=1; //启动计数器。
双向计数模式
PSC值为0(内部分频系数为1),ARR预设值为6
(CR1.CEN
=1)使能计数时,计数器在CK_CNT
驱动下减1计数
当计数值到达1时,产生计数器下溢事件,然后继续从0开始加1计数。当计数值到达5时,产生计数器上溢事件,然后继续从6开始减1计数
计数器在CK_CNT
驱动下从0开始计数到ARR的预设值-1,然后产生一个计数器溢出事件,再向下计数到1并且产生一个计数器下溢事件,接着再从0开始重新计数
此模式不能写入CR1.DIR
,由硬件更新并指示当前计数方向,更新事件产生在每次计数上溢和每次计数下溢
可用来测量(输入信号)脉冲宽度或频率
通过检测CHx
上的边沿信号,在其发生跳变(如上升沿/下降沿)时,(利用中断功能)将当前定时器CNT值,锁存到对应通道的捕获/比较寄存器CCRx
中,把前后两次捕获到的CCR值相减,即可算出脉宽或频率
除了TIM6和TIM7,其他定时器均有输入捕获功能
捕获过程信号流程:输入信号由CHx
经采样、滤波后所得信号TIxF
,由边沿检测器产生信号TIxFPx
(可作为从模式控制器的输入触发或作为捕获控制),再通过预分频成为ICxPS
进入捕获寄存器CCR,即:
CHx
→TIxF
→TIxFPx
→ICxPS
→CCR
输入通道
待测量信号从外部引脚CH1~4进入,常称为TI1~4
输入滤波和边沿检测
CR1.CKD
和CCMR.ICxF
控制,采样频率fSAMPLE可由fCK_INT(内部时钟)或fDTS分频后提供CCER.CCxP
和CCER.CCxNP
决定捕获通道
CCRx
中CCMR.CCxS
配置预分频器
ICx
的输出信号会经过预分频器,决定发生多少个事件时进行一次捕获;事件个数由CCMR.ICxPSC
配置
捕获寄存器CCR
ICxPS
是最终被捕获信号CCxI
,相应中断位SR.CCxIF
被置1,通过软件或读取CCR值可将SR.CCxIF
清0SR.CCxIF
已置1),则捕获溢出标志SR.CCxOF
会被置位(对其清零只能通过软件)输入捕获过程描述
CCRx
中(即捕获事件发生),SR.CCxIF
被置1(若已使能中断/DMA操作,会产生中断/DMA操作)设置在TI1输入的上升沿时捕获计数器CNT值到CCR1中,如下:
xxxxxxxxxx
CCMR1.CC1S=01; //CC1被设置为输入,IC1映射在TI1上
CCMR1.IC1F=0011; //配置输入滤波器所需带宽,连续采样8次
CCER.CC1P=0; // TI1通道选择上升沿有效
CCMR1.IC1PSC=00; //输入无分频器,每一个边沿都触发一次捕获
CCER.CC1E=1; //允许捕获计数器的值到捕获寄存器中
DIER.CC1IE=0; //允许中断请求
DIER.CC1DE=0; //允许DMA请求
测量脉冲宽度(捕获高电平脉宽):
示例:利用ST库函数实现TIM设置,使用TIM2的1/3通道进行频率测量,设置过程如下:
xxxxxxxxxx
TIM_ICInitStructure.TIM_ICMode=TIM_ICMode_ICAP;//配置为输入捕获模式
TIM_ICInitStructure.TIM_Channel=TIM_Channel_1; //选择通道
1TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;//输入上升沿捕获
TIM_ICInitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI;//通道方向选择
TIM_ICInitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1;//每检测到捕获就触发一次捕获
TIM_ICInitStructure.TIM_ICFilter=0x0;
TIM_ICInit(TIM2,&TIM_ICInitStructure);
TIM_ICInitStructure.TIM_ICMode=TIM_ICMode_ICAP;
TIM_ICInitStructure.TIM_Channel=TIM_Channel_3;//选择通道3
TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter=0x0;
TIM_ICInit(TIM2,&TIM_ICInitStructure);
TIM_SelectInputTrigger(TIM2,TIM_TS_TI1FP1);
//选择滤波后TI1作为输入触发源,触发下面程序的复位
TIM_SelectSlaveMode(TIM2,TIM_SlaveMode_Reset);
//复位模式-选中的触发输入(TRGI)的上升沿初始化计数器,并且产生一个更新信号
TIM_SelectMasterSlaveMode(TIM2,TIM_MasterSlaveMode_Enable);//主从模式选择
普通输入捕获模式的一种特殊应用
将同一输入映射两个ICx信号(IC1和IC2),其中一个捕获上升沿,另一个捕获下降沿,在中断中读上升沿和下降沿分别对应的CNT值,得到周期和占空比,具体即:
PWM输入捕获与普通输入捕获区别
ICx
信号被映射至同一个TIx
输入ICx
信号为边沿有效但极性相反TIxFP
作为触发输入(SMCR设为复位模式)将待测PWM输入信号通过GPIO引脚输入到定时器PWM检测通道TI1,设置CNT向上计数(ARR预设值足够大)
输入脉冲TI1上升沿到达时,触发IC1和IC2输入捕获中断,CNT值复位为0随后,CNT在CK_CNT驱动下从0开始累加计数
TI1下降沿到来时,触发IC2捕获事件,CNT当前值被锁存到CCR2中,CNT继续累加。(设TCK_CNT为CK_CNT周期)
待测脉冲高电平时间为(CCR2+1)*TCK_CNT
TI1第二个上升沿到达时,触发IC1中断,CNT当前值锁存到CCR1中,同理待测脉冲周期为(CCR1+1)*TCK_CNT
由周期和高电平时间,可算出占空比为(高电平时间/脉冲周期)*100%=(CCR2+1)/(CCR1+1)
常用于控制输出一个波形或指示一段给定时间已到
当CNT计数值(变动至)与CCR值相等时:
CCR能在任何时候通过软件进行更新以控制输出波形,前提条件是不使用预装载寄存器(即CCMR.OCxPE
=0),否则只能在发生下一次更新事件时被更新
比较输出模式下翻转OC1的时序图:
比较输出寄存器
当CNT值跟CCR值相等时,输出参考信号OCxREF
会发生改变(再经过一系列控制后成为真正输出信号OCx
/OCxN
),并产生比较中断CCxI
,SR.CCxIF
置1
死区发生器
仅高级定时器才有;在OCxREF
基础上,插入死区时间,用于生成两路互补的输出信号OCx
和OCxN
输出控制
进入输出控制电路的信号被分成两路,原始和被反向信号(通过设置CCER.CCxP
和CCER.CCxNP
控制极性选择);由OCx
输出到外部引脚CHx/CHxN
(通过设置CCER.CxE
和CCER.CxNE
控制是否输出)
输出引脚
比较输出的输出信号最终通过定时器外部IO输出,分别为CH1~4(前三通道还有互补的输出通道CH1~3N)
比较输出模式种类
共8种:冻结、匹配时输出有效/无效电平、翻转、强制为有效/无效电平、PWM1/2;(通过设置CCMR.OCxM
选择模式)。其中,
比较输出原理
即通过(计数值和CCR比较后)定时器外部引脚输出受控的波形。可认为有两部分实现信号(的受控)输出:
比较输出模式的说明:
CCMRx.CCxS
=00,即选择相应通道为输出模式CCMRx.OCxPE
选择CCRx
是否需要使用预装载寄存器OCxREF
和OCx
输出没有影响PWM输出模式
PWM的定义和应用
脉冲宽度调制(简称脉宽调制),指对脉冲宽度的控制,利用数字输出对模拟电路进行控制。在电力电子中应用广泛,包括:测量、通信、功率控制与变换、电机控制、伺服控制、调光、开关电源等
PWM的实现
PWM输出模式的工作过程
假设:CNT向上计数,ARR预设值N,CNT当前计数值X,CCR预设值A,时钟周期TCK_CNT。工作过程:
X在CK_CNT驱动下从0开始不断累加计数
X(在计数同时)与A进行比较:
若X<A,输出高/低电平;若X≥A,输出低/高电平
当X大于N时,X清零并重新开始计数
循环往复,所得PWM输出信号:周期为(N+1)*TCK_CNT
,脉冲宽度为A*TCK_CNT
,占空比为A/(N+1)
PWM输出模式的说明
占空比=(CCR+1)/(ARR+1)
CCMRx.OCxM
=110(PWM模式1)或=111(PWM2),能独立设置每个OCx
输出通道产生一路PWMCCMRx.OCxPE
=1,可使能相应CCR预装载寄存器EGR.UG
=1来初始化所有寄存器OCx
极性通过设置CCER.CCxP
实现(高/低电平)OCx
输出使能通过CCER.CCxE
、CCER.CCxNE
、BDTR.MOE
、BDTR.OSSI
、BDTR.OSSR
的组合控制CCRx≤CNT
,并根据CR1.CMS
状态,选择边沿或中央对齐模式单脉冲模式OPM
编码器接口
主要特性(相比基本定时器所增加特性)
ITRx
、外部输入捕获TIx
、外部触发输入ETR
除具有通用定时器所有功能外,还可视为一个分配到6个通道的三相PWM发生器,具有嵌入死区时间的互补PWM输出
完全独立,不共享任何资源,可同步操作
内部结构
与通用定时器相比,主要多了BRK和DTG两个结构,因而具有死区时间控制功能
时钟源
与通用定时器唯一的不同在于:内部时钟CK_INT的来源TIMxCLK
来自APB2预分频器输出,上电复位后,APB2预分频系数为1,TIMxCLK
是APB2时钟PCLK2(通常为72MHz)
功能描述
相比通用定时器,另具有三相六步电机的接口、刹车功能及用于PWM驱动电路的死区时间控制,非常适于控制电机
主要特性
TIMxCLK
来自APB2预分频器输出所有TIMx
均在内部相连,用于同步或级联
定时器一般通过软件设置启动,也可由另一定时器触发或通过外部信号触发而启动,还可通过另一定时器某一条件被触发而启动(某一条件可为:定时到时、定时器超时、比较成功等)
通过一个定时器触发另一定时器的工作方式,有时也称为定时器的同步
发出触发信号的定时器工作于主模式,接受触发信号而启动的定时器工作于从模式
定时器工作于主模式时,能产生触发输出(并作为其它定时器的触发输入)信号,还可对另一处于从模式的定时器进行复位、启动、停止或提供时钟等操作
定时器工作于从模式时,受到外来触发信号的影响或控制,其具体工作模式又可分为多种
定时器处于主从双角色模式:既受外来触发信号影响或控制,同时又能输出触发信号影响或控制其他从定时器
触发输出信号(TRGO)
TIM输出(至其它TIM或外设的)触发信号;一般有数种方式产生:
EGR.UG
=1CR1.CEN
=1OCxREF
触发输入信号(TRGI)
从外部引入(到TIM)的触发信号,根据SMCR.TS
设置,分为3类,共8个,如下:
来自定时器外部的各种触发输入信号TRGI ,均须经过触发输入选择器连接至从模式控制器SMCR(控制或影响计数器工作),此时TIM工作于从模式
从模式控制器检测到触发输入信号时,有多种控制方式(以控制或影响TIM工作),形成相应工作模式,如下:
使用一个定时器作为另一个定时器的预分频器
配置定时器1作为定时器2的预分频器,TIM2由TIM1周期性的上升沿(即TIM1的计数器溢出)信号驱动
xxxxxxxxxx
TIM1_CR2. MMS=010; //TIM1为主模式;设定UEV作为触发输出,每产生
//一个UEV时(即每次计数器溢出),在TRGO1上输出一个周期性上升触发信号
TIM2_SMCR.TS=000; //主从模式对应主TIM2,从TIM1;
//ITR0作为内部触发,TIM2从TIM1获得触发输入
TIM2_SMCR.SMS=111; //TIM2使用外部时钟源模式1配置TIM1的ARR;//定时周期
TIM1_CR1.CEN=1;
TIM2_CR1.CEN=1; //使能TIM1、TIM2
使用一个外部触发同步地启动2个定时器
定时器1的TI1输入上升时使能定时器1,使能定时器1的同时使能定时器2
xxxxxxxxxx
TIM1_CR2. MMS=001; //TIM1为主模式;设定它的使能作为触发输出
TIM1_SMCR.TS=100; //TIM1为从模式,从TI1获得输入触发
TIM1_SMCR.SMS=110; //TIM1为触发模式
TIM1_SMCR.MSM=1; //TIM1为主/从模式;对TI1为从,对TIM2为主
TIM2_SMCR.TS=000; //TIM2从TIM1获得输入触发
TIM2_SMCR.SMS=110; //TIM2为触发模式
TIM1_CR1.CEN=1; //使能TIM1
当TIM1的TI1上出现一个上升沿时,TIM1和TIM2同步地按照内部时钟开始计数两个TIF标志也同时被设置。为保证计数器对齐,TIM1须配置为主/从模式(既是主也是从)
存放于stm32f10x_tim.h
和stm32f10x_tim. c
文件中
常用库函数
TIM_TimeBaseInit
:根据TIM_TimeBaseInitStruct初始化TIMxTIM_ARRPreloadConfig
:使能或禁止ARR上的预装载寄存器TIM_Cmd
:使能或禁止TIMxTIM_ITConfig
:使能或禁止指定TIMx中断TIM_GenerateEvent
:设置TIM事件由软件产生TIM_GetITStatus
:检查指定TIMx中断是否发生TIM_ETRClockMode1Config
:配置TIM外部时钟源模式1TIM_CounterModeConfig
:设置TIM计数器模式TIM_SelectInputTrigger
:选择TIM输入触发源TIM_CCxCmd
:使能或禁止TIM捕获/比较通道xTIM_SelectSlaveMode
:选择TIM从模式初始化结构体
基本初始化结构体TIM_TimeBaseInitTypeDef
xxxxxxxxxx
typedefstruct
{
uint16_t TIM_Prescaler; //预分频:0~0xFFFF
uint16_t TIM_CounterMode; //计数模式:Up/Down向上/向下CenterAligned1/2/3中央1/2/3
uint16_t TIM_Period; //ARR值:0~0xFFFF
uint16_t TIM_ClockDivision; //采样分频系数:DIV1/2/4
uint8_t TIM_RepetitionCounter;//重复定时器值(计数周期数)
}TIM_TimeBaseInitTypeDef; //TIM初始化各参数定义
输入捕获初始化结构体TIM_ICInitTypeDef
xxxxxxxxxx
typedefstruct
{
uint16_t TIM_Channel; //通道,共4个,1~4:通道1~4
uint16_t TIM_ICPolarity; //边沿触发:Rising上升沿,Falling下降沿
uint16_t TIM_ICSelection; //输入:TRC,与TRC相连;DirectTI,TI1/2/3/4与IC1/2/3/4相连;
//IndirectTI,TI1/2/3/4与IC2/1/4/3相连
uint16_t TIM_ICPrescaler; //输入预分频,每N(1/2/4/8)个事件执行一次捕获:DIV1/2/4/8
uint16_t TIM_ICFilter; //滤波器:0x0~0x0F
}TIM_ICInitTypeDef;
比较输出初始化结构体TIM_OCInitTypeDef
xxxxxxxxxx
typedefstruct
{
uint16_t TIM_OCMode;//输出模式
uint16_t TIM_OutputState; //输出使能
uint16_t TIM_OutputNState;//互补输出使能
uint16_t TIM_Pulse;//占空比:0x0000~0xFFFF
uint16_t TIM_OCPolarity;//输出极性,High:高,Low:低
uint16_t TIM_OCNPolarity;//互补输出极性
uint16_t TIM_OCIdleState;//空闲状态输出电平
uint16_t TIM_OCNIdleState;//空闲状态互补输出电平
}TIM_OCInitTypeDef;
典型库函数
频率设置
TIMIntemalClockConfig
等函数选择时钟时钟来源
4类共8个触发源,可作为定时器时钟源
计数器模式
编程步骤
实质上,PWM就是定时器的一个比较功能,利用翻转输出,形成一个具有一定脉冲宽度的高/低电平周期波
PWM频率取决于ARR,占空比取决于CCR
配置输出通道
选择使用某个/某几个通道作为PWM输出通道,其对应引脚(其实就是GPIO)须进行时钟和引脚输出方式配置
一般为复用推挽输出AF_PP
应用中,可选不同引脚(即,改变GPIO与输出通道默认映射关系),此时须使用重定向功能Remap,即:
配置定时器
配置PWM模式(即输出特性)
配置TIM3_CCMR1相关位来控制TIM3_CH3模式,利用TIM_OC3Init实现,其原型:
xxxxxxxxxx
void TIM_OC3Init(TIM_TypeDef* TIMx,TIM_OCInitTypeDef* TIM_OCInitStruct)
xxxxxxxxxx
TIM_OCStructInit(&TIM_OCInitStructure); //设置默认值
TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1; // PWM模式1输出
TIM_OCInitStructure.TIM_Pulse=400-1; //占空比=(CCR/(ARR+1))或Pulse/(Period+1)
TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High; //输出极性:高
TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable; //输出状态使能
TIM_OC3Init(TIM3,&TIM_OCInitStructure); //TIM3的CH3输出
TIM_CtrIPWMOutputs(TIM3,ENABLE); //TIM3的PWM输出为使能
PWM两种输出模式
模式1(PWM1)和模式2(PWM2),由CCMR.OCxM
值确定(110 为模式1,111为模式2);模式1和2正好互补,互为相反,运用差别不大
动态调整占空比
修改CCR可控制输出占空比,库函数TIM_SetComparex
用于修改占空比(x为1~4,代表相应通道),其原型为:
xxxxxxxxxx
void TIM_SetComparex(TIM_TypeDef* TIMx,uint16_t Compare2)
PWM输出基本步骤
决定一个中断是否能被屏蔽及何时可响应(未屏蔽时)
优先级分组
优先级实现
中断响应顺序
startup_stm32f10x_hd.s
,已标明中断处理函数名称,不能随意定义NVIC_IRQChannel
(即类型)在stm32f10x.h
中进行了宏定义,通道常以中断号表示,优先级可设置(个别除外)建立中断向量表
分配栈空间并初始化
设置中断优先级
设置中断优先级分组(的位数)
4位中,抢占优先级和子优先级各占几位(二者和为4),可有5种方式:抢占优先级0~4位/子优先级4~0位NVIC_PriorityGroup_0~4
设置抢占优先级和子优先级,根据上一步中分组情况,分别设置抢占和子优先级(即在各自取值范围中设置优先级确定值)
使能中断
通过失效中断总屏蔽位和分屏蔽位,可使能对应中断
编写对应ISR代码
ISR最后,退出程序前应清除对应中断标志位(表示该中断已处理完毕),否则,该中断请求始终存在,该ISR将被反复执行
组成:
外部中断/事件输入线
APB外设接口
通过此接口访问各功能模块。若使用引脚的外部中断/事件映射功能,须打开APB2总线上该引脚对应端口时钟及AFIO功能时钟
边沿检测器
共19个,用来连接19个外部中断/事件输入线,是EXTI主体部分。由边沿检测电路、控制寄存器、门电路和脉冲发生器组成
外部中断/事件请求的产生和传输
从输入(外部输入线)到输出(外部中断/事件请求信号),过程依次
事件与中断
从外部激励信号看,中断和事件的请求信号没有区别,只是在STM32F103内部将它们分开:
主要特性
常用NVIC库函数
存放于标准外设库的misc.h
和misc.c
文件中
NVIC_PriorityGroupConfig
设置优先级分组NVIC_Init
根据NVIC_InitStruct
中指定参数初始化NVICNVIC_DeInit
将NVIC寄存器恢复为复位启动时默认值常用EXTI库函数
存放于stm32f10x_exti.h
和stm32f10x_exti.c
文件中
EXTI_DeInit
将EXTI寄存器恢复为复位启动时默认值EXTI_Init
根据EXTI_InitStruct
中指定参数初始化EXTIEXTI_GetFlagStatus
检查指定外部中断/事件线标志位EXTI_ClearFlag
清除指定外部中断/事件线标志位EXTI_GetITStatus
检查指定EXTI线触发请求发生与否EXTI_ClearITPendingBit
清除指定EXTI线中断挂起位使用EXTI前,需先使用GPIO库函数
GPIO_EXTILineConfig
,将指定GPIO引脚设置为EXTI线
初始化结构体
NVIC初始化结构体NVIC_InitTypeDef
xxxxxxxxxx
typedef struct
{
uint8_t NVIC_IRQChannel; //中断通道
uint8_t NVIC_IRQChannelPreemptionPriority; //抢占/主优先级
uint8_t NVIC_IRQChannelSubPriority; //子/从优先级
FunctionalState NVIC_IRQChannelCmd;
}NVIC_InitTypeDef;
AFIO结构体AFIO_TypeDef
xxxxxxxxxx
typedef struct
{
vu32 EVCR;
vu32 MAPR;
vu32 EXTICR[4];//IO复用里的外部中断配置寄存器EXTICR
} AFIO_TypeDef;
EXTI初始化结构体EXTI_InitTypeDef
xxxxxxxxxx
typedefstruct
{
uint32_t EXTI_Line;//中断/事件线,可选EXTI0~EXTI19
EXTIMode_TypeDef EXTI_Mode;//模式选择,产生Interrupt中断或Event事件
EXTITrigger_TypeDef EXTI_Trigger;//触发方式,Rising上升沿/Falling下降沿/Rising_Falling双向
FunctionalState EXTI_LineCmd;//EXTI 使能,使能ENABLE,禁用DISABLE
} EXTI_InitTypeDef;
EXTI控制寄存器定义结构体EXTI_TypeDef
xxxxxxxxxx
typedefstruct
{
vu32 IMR; //中断屏蔽,偏移量0x00
vu32 EMR; //事件屏蔽,偏移量0x04
vu32 RTSR; //上升沿触发选择,偏移量0x08
vu32 FTSR; //下降沿触发选择,偏移量0x0C
vu32 SWIER; //软件中断事件,偏移量0x10
vu32 PR; //挂起,偏移量0x14
}EXTI_TypeDef;
典型库函数
EXTI的,所有(共6个)32位寄存器中,位[31:19]保留,位[18:0]需定义,如下(x为0~18,对应19个外部中断)
NVIC,共有7种控制寄存器组,除IPR/IR外,其余6种/组,每组共60个有效位,每位分别对应60个可编程可屏蔽中断
AFIO_EXTICR1~4外部中断配置寄存器1~4
为将I/O口设置为外部中断入口以作为中断源,须利用GPIO复用功能,将I/O口映射到相应外部事件,即:
EXTICRx(x=1~4),可由软件读写,选择外部中断的输入源;其映射规则如下:
中断、异常、外部中断及EXTI
EXTI中断向量及中断服务函数
相应中断服务函数名称(在启动文件startup_stm32f10x_hd.s
中):EXTI0_IRQHandler
;EXTI1_IRQHandler
;EXTI2_IRQHandler
;EXTI3_IRQHandler
;EXTI4_IRQHandler
;EXTI9_5_IRQHandler
;EXTI15_10_IRQHandler
配置及应用外部中断步骤要点
GPIO_Init
RCC_APB2PeriphClockCmd
GPIO_EXTILineConfig
EXTI_Init
NVIC_PriorityGroup
,使能中断NVIC_Init
EXTIx_IRQHandler
EXTI_ClearITPendingBit
EXTI及NVIC的初始化
xxxxxxxxxx
void EXTI_Config (void)
{
EXTI_InitTypeDef EXTI_InitStructure;
RCC_APB2PeriphClockCmd (RCC_APB2Periph_AFIO, ENABLE) ;
GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource5);
EXTI_InitStructure.EXTI_Line= EXTI_Line5;
EXTI_InitStructure.EXTI_Mode= EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd= ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
xxxxxxxxxx
void NVIC_Config (void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig (NVIC_PriorityGroup_1) ;
NVIC_InitStructure.NVIC_IRQChannel= EXTI9_5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority= 1;
NVIC_InitStructure.NVIC_IRQChannelCmd= ENABLE;
NVIC_Init( &NVIC_InitStructure) ;
}
中断服务程序
xxxxxxxxxx
void EXTI9_5_IRQHandler(void)
{
unsigned char temp=LED0_IsOn () ;
if (EXTI_GetITStatus (EXTI_Line5) ! = RESET)
{
if (temp)
LED0_Off ();
else
LED0_On();
EXTI_ClearITPendingBit (EXTI_Line5) ;
}
}
相关引脚简介
数据发送过程
数据发送,须设置相关寄存器各位,过程如下:
数据接收过程
配置过程:
常用库函数
存放于stm32f10x_usart.h
和stm32f10x_usart.c
文件中
USART_DeInit
将USARTx
寄存器恢复为复位启动时默认值USART_Init
根据USART_InitStruct
中指定参数初始化USART寄存器USART_StructInit
把USART_InitStruct
中的每个参数按默认值填入USART_Cmd
使能或禁止指定USARTUSART_SendData
通过USART发送单个数据USART_ReceiveData
返回指定USART最近接收到数据USART_GetFlagStatus
查询指定USART标志位状态USART_ClearFlag
清除指定USART标志位USART_ITConfig
使能或禁止指定USART中断USART_GetITStatus
查询指定USART中断是否发生USART_ClearITPendingBit
清除指定USART中断挂起位USART_DMACmd
使能或禁止指定USART的DMA请求初始化结构体
USART初始化结构体USART_InitTypeDef
xxxxxxxxxx
typedefstruct
{
uint32_t USART_BaudRate; //波特率
uint16_t USART_WordLength;//传输字长=数据+检验位数:8b/9b
uint16_t USART_StopBits;//停止位数:1、1_5、2、0_5
uint16_t USART_Parity; //校验:No无;Odd奇;Even偶
uint16_t USART_HardwareFlowControl;//硬件流控:None无;RTS请求发送;CTS清除发送;RTS_CTS发送和接收都用流控
uint16_t USART_Mode;//模式(可组合):Tx发送;Rx接收
uint16_t USART_Clock;//时钟使能:Enable高;Disable低
uint16_t USART_CPOL;//SLCK引脚时钟输出极性:High高;Low低
uint16_t USART_CPHA;//SLCK引脚时钟输出相位,配合CPOL产生时钟/数据采样关系:1Edge时钟第一个边沿数据捕获;2Edge第二个
uint16_t USART_LastBit;//同步模式下,SLCK输出最后一位数据对应时钟脉冲使能:Enable最后一位数据的时钟脉冲从SLCK输出;Disable不输出
} USART_InitTypeDef;
典型库函数
例:需设置参数为波特率,字长,停止位,奇偶校验位,硬件数据流控制,模式(收/发)
xxxxxxxxxx
USART_InitStructure.USART_BaudRate = bound;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl= USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure); //初始化串口
在接收到数据时(RXNE读数据寄存器非空),要产生中断,开启中断方法:
xxxxxxxxxx
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
在发送数据结束时(TC发送完成),要产生中断,开启中断方法:
xxxxxxxxxx
USART_ITConfig(USART1,USART_IT_TC, ENABLE);
某中断发生时,会置位SR中某标志位,中断处理函数中,可调用此函数判断该中断是否发生。如,串口发送完成时,产生中断,对其判断:
xxxxxxxxxx
USART_GetITStatus(USART1, USART_IT_TC)
若返回值是SET,说明中断发生判断读寄存器是否非空(RXNE):
xxxxxxxxxx
USART_GetFlagStatus(USART1, USART_FLAG_RXNE);
判断发送是否完成(TC):
xxxxxxxxxx
USART_GetFlagStatus(USART1, USART_FLAG_TC);
共7个:状态寄存器SR、数据寄存器DR、波特率寄存器BRR、控制寄存器CR1~3、保护时间和预分频寄存器GTPR
SR,标识USART各种状态,均由硬件置位,大都由软件序列(先读SR,再相关读写)清零,部分状态标志被置1同时会产生中断(已使能时)
DR,包含发送或接收的数据,接收时称为RDR,发送时称为TDR(二者共用一片物理空间),提供内部总线和输入/输出移位寄存器间的并行接口,因此兼具读写功能。仅低9位[8:0]有效(其他位保留)。使能校验位(CR1.PCE=1)时:发送,写入MSB值(根据数据长度不同,MSB是第7位或第8位)被校验位取代;接收,读到的MSB值是校验位
BRR,装载分频器整数和小数部分;若TE或RE分别被禁止,波特计数器停止计数;其中,DIV_Fraction[3:0] 定义USARTDIV小数部分;DIV_Mantissa[15:4]为整数;其余位保留
CR1 ,多由软件置位/清零(除:RWU及SBK,硬件也可复位)
初始化外设PPP
PPP_InitTypeDef
,用以配置各种不同外设(涵盖外设特牲和功能)操作外设PPP
外设PPP输入/输出,常置于main的无限循环体或相应中断服务函数中;运行期间,条件满足时将反复执行
PPPx
(意为指定的外设PPPx
,是外设PPP的细分表示,PPP若是GPIO,PPPx
可以是GPIOA、GPIOB、GPIOC等;PPP若是TIM,PPPx
可以是TIM1、TIM2等)PPP_DeInit
以系统默认参数初始化PPPx
的寄存器PPP_Init
根据PPP_InitTypeDef
结构体变量中指定参数初始化PPPx
的寄存器;输入参数:PPP_InitStruct
,指向PPP_InitTypeDef
结构体变量的指针,包含PPPx
配置信息PPP_Cmd
使能/禁止PPPx
;输入参数:NewState
,PPPx
的新状态(ENABLE,使能PPPx
;DISABLE,禁止)PPP_SendData
通过PPPx
发送数据(常见于USART、SPI和I2C等外设);输入参数:Data,待发送的数据PPP_ReceiveData
返回PPPx
最新收到数据(常见同上);返回值:PPPx
最新收到数据PPP_GetFlagStatus
查询PPPx
的指定标志位;输入参数:PPP_FLAG
,PPPx
的指定(待查询)标志位;返回值:最新状态(SET或RESET,即1/0)PPP_ClearFlag
清除PPPx
的指定标志位;输入参数:PPP_FLAG
,PPPx
的指定(待清除)标志位PPP_ITConfig
使能或禁止PPPx
的指定中断;输入参数:PPP_IT
,待使能或禁止的PPPx
中断源;NewState
,新状态(ENABLE,使能;DISABLE,禁止)RCC_APB2PeriphClockCmd
USART_DeInit
GPIO_Init
;引脚复用映射(非必须)GPIO_PinAFConfig
USART_Init
NVIC_Init
;USART_ITConfig
USART_Cmd
USARTx_IRQHandler
USART_ReceiveData
;USART_SendData
USART_GetFlagStatus
;USART_ClearITPendingBit
USART_GetITStatus
读取状态位以区分SR.RXNE/SR.TXE/SR.TC
;直接向该位写0,也可清除SR.RXNE/SR.TC
可与外部设备以半双工/全双工、同步、串行方式通信(含CRC);使用一条双向数据线的双线单工同步传输
常为主模式(可多主),为各从设备提供通信时钟SCK
主要应用于:EEPROM,FLASH,实时时钟,AD转换器,数字信号处理器和解码器等
作为主设备,产生SCK时钟信号;MOSI输出,MISO输入
配置步骤
设置串行时钟波特率CR1.BR[2:0]
设置SPI协议CR1.CPOL和CR1.CPHA
设置数据格式CR1.DFF和CR1.LSBFIRST
设置NSS工作模式:
CR2.SSOE
位(可调用SPI_SSOutputCmd
实现)时,开启主模式下NSS输出(输出低电平),此时,当其他SPI的NSS引脚与其相连,会收到低电平,即片选成功,成为从设备CR1.SSM
和CR1.SSI
置1;此时,NSS引脚被释放出来,可作他用(如,可作为普通GPIO引脚,驱动从设备片选信号)设置CR1.MSTR
和CR1.SPE
:仅当NSS脚连到高电平,这些位才能保持置位
数据发送过程
数据接收过程
小结
作为从设备,SCK接收主设备时钟,MOSI输入,MISO输出
主设备发送时钟前,应先使能从设备(否则可能会发生意外的数据传输),且通信时钟第一个边沿到来之前或正进行的通信结束之前,从设备的数据寄存器须就绪
配置步骤
设置SPI协议CR1.CPOL和CR1.CPHA(须和主设备配置相同,保证正确数据传输)
设置数据格式CR1.DFF和CR1.LSBFIRST(和主设备配置相同)
设置NSS工作模式:
清除CR1.MSTR,置位CR1.SPE,引脚工作于SPI模式下
数据发送过程
数据接收过程
状态标志
SPI中断
同一SPI各种中断事件都被连接到同一中断向量,不同SPI有不同中断向量
中断事件中,最常用:
常用库函数
存放于stm32f10x_spi.h
和stm32f10x_spi.c
中
SPI_I2S_DeInit
将SPI寄存器恢复为复位启动时默认值SPI_Init
根据SPI_InitStruct
中指定参数初始化指定SPI寄存器SPI_StructInit
把SPI_InitStruct
每个参数按默认值填入SPI_Cmd
使能或禁止指定SPISPI_I2S_SendData
通过SPI发送单个数据SPI_I2S_ReceiveData
返回指定SPI最近接收到的数据SPI_I2S_GetFlagStatus
查询指定SPI标志位状态SPI_I2S_ClearFlag
清除指定SPI标志位SPI_I2S_ITConfig
使能或禁止指定的SPI中断SPI_I2S_GetITStatus
查询指定的SPI中断是否发生SPI_I2S_ClearITPendingBit
清除指定SPI中断挂起位SPI_I2S_DMACmd
使能或禁止指定SPI的DMA请求初始化结构体
SPI初始化结构体SPI_InitTypeDef
xxxxxxxxxx
typedefstruct
{
uint16_t SPI_Direction;//通讯方向:2Lines_FullDuplex双线全双工;2Lines_RxOnly双线只接收;1Line_Rx单线只接收;1Line_Tx单线只发送
uint16_t SPI_Mode;//主/从模式:Master主模式;Slave从模式
uint16_t SPI_DataSize;//数据帧长度:8b,8位;16b,16位
uint16_t SPI_CPOL;//时钟极性:High高电平;Low低电平
uint16_t SPI_CPHA;//时钟相位:1Edge奇/前沿采样;2Edge偶/后沿
uint16_t SPI_NSS;//NSS引脚使用:Hard硬件控制模式;Soft软件
uint16_t SPI_BaudRatePrescaler;//时钟分频因子:2/4/8/.../128/256
uint16_t SPI_FirstBit;//先行:MSB高位数据在前;LSB低位在前
uint16_t SPI_CRCPolynomial;// CRC校验表达式:大于1整数即可
}SPI_InitTypeDef;
典型库函数
xxxxxxxxxx
SPI_InitTypeDef*SPI_InitStructure;
SPI_InitStructure.SPI_Direction=SPI_Direction_2Lines_FullDuplex;//双线双向全双工
SPI_InitStructure.SPI_Mode=SPI_Mode_Master;//主SPI
SPI_InitStructure.SPI_DataSize=SPI_DataSize_8b;//SPI发送接收8位帧结构
SPI_InitStructure.SPI_CPOL=SPI_CPOL_High;//串行同步时钟空闲状态高电平
SPI_InitStructure.SPI_CPHA=SPI_CPHA_2Edge;//第二个跳变沿数据被采样
SPI_InitStructure.SPI_NSS=SPI_NSS_Soft;//NSS信号由软件控制
SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_256;
SPI_InitStructure.SPI_FirstBit=SPI_FirstBit_MSB; //数据传输从MSB位开始
SPI_InitStructure.SPI_CRCPolynomial=7;//CRC值计算的多项式
SPI_Init(SPI2,&SPI_InitStructure); //由上述参数初始化SPIx寄存器
SPI配置一般步骤
GPIO_Init
SPIx
时钟RCC_APB2PeriphClockCmd
SPIx
,设置工作模式SPI_Init
SPIx
使能SPI_Cmd
SPI
传输数据SPI_I2S_SendData
;SPI_I2S_ReceiveData
SPI
传输状态SPI_I2S_GetFlagStatus
注意事项
I2C默认工作模式为从模式,当生成起始信号后,自动地由从模式切换到主模式
两种模式下,都可作为发送器或接收器(由SR2.TRA位标识)因此共有4种(主/从+收发器/发送器)
主发送器发送流程及事件说明:
存放于stm32f10x_i2c.h
和stm32f10x_i2c.c
中
I2C_DcInit
将I2Cx的寄存器恢复为复位启动时默认值I2C_Init
根据I2C_InitStruct
中指定的参数初始化指定I2C的寄存器I2C_Cmd
使能或禁止指定I2CI2C_GenerateSTART
产生I2Cx传输的起始信号I2C_Send7bitaddress
发送地址信息选中指定的I2C从设备I2C_SendData
通过I2C发送单字节数据I2C_ReceiveData
返回指定I2C最近接收到的字节数据I2C_CheckEvent
查询I2Cx最近一次发生的事件是否是I2C_EVENT指定的事件I2C_AcknowledgeConfig
使能或者禁止指定I2C的应答功能I2C_GenerateSTOP
产生I2Cx传输的结束信号I2C_GetFlagStatus
查询指定I2C的标志位状态I2C_ClearFlag
清除指定I2C的标志位I2C_ITConfig
使能或禁止指定的I2C中断I2C_GetITStatus
查询指定的I2C中断是否发生I2C_ClearITPendingBit
清除指定的I2C中断请求挂起位I2C_DMACmd
使能或禁止指定I2C的DMA请求I2C初始化结构体I2C_InitTypeDef
xxxxxxxxxx
typedefstruct
{
uint16_t I2C_InitStructure.I2C_ClockSpeed;//时钟频率,标准100K;快速400K
uint16_t I2C_InitStructure.I2C_Mode;//工作模式,I2C,I2C模式;SMBusDevice,SMBus设备模式;SMBusHost,SMBus主控模式
uint16_t I2C_InitStructure.I2C_DutyCycle;//快速模式下,占空比,16_9,2
uint16_t I2C_InitStructure.I2C_OwnAddress1;//第一个设备自身地址,7/10位
uint16_t I2C_InitStructure.I2C_Ack;//使能或禁止ACK,Enable;Disable
uint16_t I2C_InitStructure.I2C_AcknowledgedAddress;//应答7/10位地址
}I2C_InitTypeDef;
xxxxxxxxxx
I2C_InitTypeDef* I2C_InitStructure;
I2C_InitStructure.I2C_Mode=I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle=I2C_DutyCycle_2;
I2C_InitStructure.I2C_ClockSpeed=I2C_Standard_Speed;
I2C_InitStructure.I2C_OwnAddress1 = 0x00;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_Init(I2C1,&I2C_InitStructure);//初始化
I2C_Cmd(I2C1,ENABLE);//使能I2C
I2C配置的一般步骤
GPIO_Init
I2Cx
时钟RCC_APB1PeriphClockCmd
I2Cx
,设置工作模式I2C_Init
I2Cx
使能I2C_Cmd
I2C_GenerateSTART
;I2C_Send7bitaddress
I2C
传输数据I2C _SendData
;I2C _ReceiveData
I2C
传输状态I2C_GetFlagStatus
I2C应用要点及细节
英文简称 | 英文全称 | 中文译名 |
---|---|---|
ENIAC | Electronic Numerical Integrator And Calculator | 电子数字积分器和计算器 |
EDVAC | The Electronic Discrete Variable Automatic Computer | 离散变量自动电子计算机 |
EDSAC | Electronic Delay Storage Automatic Calculator | 存储程序式电子计算机 |
PA | Physic Address | 物理地址 |
ALU | Arithmetic and Logic Unit | 算术逻辑单元 |
IR | Instruction Register | 指令寄存器 |
ID | Instruction Decoder | 指令译码器 |
OC | Instruction Controller | 指令控制器 |
LSI | Large Scale Integrated | 大规模集成电路 |
VLSI | Very Large Scale Integration | 甚大规模集成电路 |
ULSI | Ultra Large Scale Integration | 超大规模集成电路 |
EMPU | Embedded Microprocessor Uni | 嵌入式微处理器 |
EMCU | Embedded Microcontroller Unit | 嵌入式微控制器 |
DSP | Digital Signal Processor | 数字信号处理器 |
SOC | System On Chip | 片上系统 |
SOPC | System on a Programmable Chip | 可编程片上系统 |
CISC | Complex Instruction Set Computer | 复杂指令集计算机 |
RISC | Reduced Instruction Set Computer | 简化指令集计算机 |
RAM | Random Access Memory | 随机存取存储器 |
DRAM | Dynamic Random Access Memory | 动态随机存取存储器 |
ACC | Accumulator | 累加器 |
FR | Flag Register | 标志寄存器 |
PSR | Program State Register | 程序状态寄存器 |
PSW | Program State Word | 程序状态字 |
CU | Control Unit | 控制单元 |
EU | Execution Unit | 执行单元 |
ISA | Instruction Set Architecture | 指令集架构 |
PC | Program Counter | 程序计数器 |
EPIC | Explicitly Parallel Instruction Computers | 精确并行指令计算机 |
IPC | Instruction Per Clock | 每一时钟周期内所执行的指令多少 |
BTB | Branch Target Buffer | 转移/分支目标缓冲器 |
SISD | Single Instruction Single Data | 单指令流单数据流 |
SIMD | Single Instruction Multiple Data | 单指令流多数据流 |
CMP | Chip Multiprocessor | 片上多处理器 |
VA | Virtual Address | 虚拟地址 |
JTAG | Joint Test Action Group | 联合测试组 |
EPI | Energy Per Instruction | 每条指令的耗能 |
MIPS | Million Instructions Per Second | 单字长定点指令平均执行速度 |
ROM | Read Only Memory | 只读存储器 |
DRAM | Dynamic Random Access Memory | 动态随机存取存储器 |
SRAM | Static Random Access Memory | 静态随机存取存储器 |
EEPROM | Electrically Erasable Programmable Read Only Memory | 电可擦除可编程只读存储器 |
IDE | Integrated Device Electronics | 电子集成驱动器 |
ATA | Advanced Technology Attachment | 高级技术连接 |
SCSI | Small Computer System Interface | 小型计算机系统接口 |
SATA | Serial ATA | 串行ATA |
SAS | Serial Attached SCSI | 串行连接SCSI接口 |
eMMC | embedded Multi Media Card | 嵌入式多媒体卡 |
UFS | Universal Flash Storage | 通用闪存存储 |
RAS | Row Address Strobe | 行地址选通信号 |
CAS | Column Address Strobe | 列地址选通信号 |
PLD | Programmable Logical Device | 可编程逻辑器件 |
SPD | Serial Presence Detect | 模组存在的串行检测 |
FPM | Fast Page Mode | 快速页面模式 |
EDO | Extended Data Out | 扩展数据输出 |
SDRAM | Synchronous DRAM | 同步动态随机存取内存 |
MMU | Memory Manage Unit | 内存管理单元 |
DMA | Direct Memory Access | 直接存储访问 |
AMBA | Advanced Microcontroller Bus Architecture | 高级微控制器总线架构 |
AHB | Advanced High-performance Bus | 高级高性能总线 |
ASB | Advanced System Bus | 高级系统总线 |
APB | Advanced Peripheral Bus | 高级外设总线 |
PCI | Peripheral Component Interconnect | 外部设备互连 |
NVIC | Nested Vectored Interrupt Controller | 嵌套中断控制器 |
IVT | Interrupt Vector Table | 中断向量表 |
SPI | Serial Peripheral Interface | 串行外设接口 |
I2C | Inter Integrated Circuit | 集成电路总线 |
ISA | Instruction Set Architecture | 指令集体系结构 |
TCM | Tightly Coupled Memory | 紧耦合内存 |
WIC | Wake-up Interrupt Controller | 唤醒中断控制器 |
PMU | Power Management Unit | 电源管理单元 |
ETM | Embedded Trace Macro-cell | 嵌入式跟踪宏单元 |
ITM | Instrumentation Trace Macro-cell | 指令跟踪宏单元 |
DWT | Data Watchpoint and Trace | 数据观察点和跟踪单元 |
FPB | Flash Patch and Breakpoint Unit | Flash地址重载和断点单元 |
TPIU | Trace Port Interface Unit | 跟踪端口接口单元 |
SCS | System Control Space | 系统控制空间 |
CMSIS | Cortex Microcontroller Software Interface Standard | 微控制器软件接口标准 |
SCB | System Control Block | 系统控制块 |
CCR | Configuration Control Register | 配置控制寄存器 |
DBM | Data Memory Barrier | 数据存储器屏障 |
DSB | Data Synchronization Barrier | 数据同步屏障 |
ISB | Instruction Synchronization Barrier | 指令屏障 |
MSP | Main Stack Pointer | 主栈指针 |
PSP | Process Stack Pointer | 进程栈指针 |
ISER | Interrupt Set-enable Registers | 中断设置使能寄存器 |
ICER | Interrupt Clear-enable Registers | 中断清除使能寄存器 |
ISPR | Interrupt Set-pending Registers | 中断设置挂起寄存器 |
ICPR | Interrupt Clear-Pending Registers | 中断清除挂起寄存器 |
IABR | Interrupt Active Bit Registers | 中断激活位寄存器 |
IPR | Interrupt Priority Registers | 中断优先级寄存器 |
STIR | Software Trigger Interrupt Registers | 软件触发中断寄存器 |
ICSR | Interrupt Control and State Register | 中断控制和状态寄存器 |
AIRCR | Application Interrupt and Reset Control Register | 应用中断和复位控制寄存器 |
SHPR | System Handler Priority Register | 系统处理优先级寄存器 |
SHCSR | System Handler Control and State Register | 系统处理控制和状态寄存器 |