1.硬件基础
1.1 NAND_FLASH和NOR_FLASH
类型 | NOR | NAND |
---|
读 | 快,像访问SRAM一样,随机访问任意地址数据 | 快,发送读命令>发送地址>判断nand是否就绪>读取一页数据 |
写 | 慢,写之前要擦除 | 快,也需要擦除 |
擦除 | 非常慢(5S) | 快(3ms) |
XIP(本地执行) | 可以 | 不可以 |
可靠性 | 高,位反转比例小于NAND的10% | 比较低,位反转常见 |
接口 | 与RAM接口相同,地址和数据总线分开 | I/O接口 |
可擦除次数 | 10000-100000 | 100000-1000000 |
容量 | 小,1-32MB | 大,16-512MB |
主要用途 | 保存代码和关键数据 | 保存数据 |
价格 | 高 | 低 |
1.2 CPU、MPU、MCU、SOC、SOPC
- CPU:计算机的运算和控制核心。由运算器、控制器、寄存器及实现它们之间联系的数据、控制及状态总线构成。运作原理:提取、解码、执行、写回;
- MPU:微处理器,可理解为增强版的CPU,往往是个人计算机和高端工作站的核心CPU;
- MCU:微控制器,将计算机的CPU、RAM、ROM、定时计数器和多种I/O接口集成在一个芯片上,形成芯片级的芯片;
- SOC:片上系统,系统级的芯片,不仅像MCU那样可以运行代码,还可以运行系统级的代码;
- SOPC:可编程片上系统(如FPGA)。SOPC的硬件配置和软件配置都可以改,把硬件配置信息下载进去,就可以变成对应的芯片。
在一种计算机环境中运行的编译程序,能编译出在另外一种环境下运行的代码,称这种编译器支持交叉编译。环境包括以下两个概念:体系结构和操作系统。如X86 Linux体系结构就是intel x86体系结构和Linux for x86操作系统的简称。
1.4 为什么需要交叉编译
- 目的平台上不允许或不能够安装我们需要的编译器,而我们需要这个编译器的某些特征;
- 目的平台资源匮乏,无法运行我们需要的编译器;
- 目的平台没有建立,没有操作系统。
1.5 基于ROM和基于RAM的运行方式
- 基于RAM:需要把硬盘和其他介质的代码加载到RAM中,一般要重定位;速度比基于ROM快,可用RAM比基于ROM少,因为代码数据都必须存放在RAM中;
- 基于ROM:速度较慢,与一个将变量、代码从存储器(硬盘,flash)搬移到RAM的过程;可用资源比基于RAM多。
2.1 哈佛结构和冯诺依曼结构
- 冯诺依曼:指令和数据统一编址,用同条总线传输,CPU读取指令和数据的操作无法重叠;主要用于通用计算机领域,要对存储器中的代码和数据频繁地进行修改,统一编址有利于节约资源;
- 哈佛:指令和数据独立编址,使用两条独立的总线传输,CPU读取指令和数据的操作可以重叠;主要用于嵌入式计算机,程序固化在硬件中,有较高的可靠性、运算速度和吞吐量。
2.2 ARM流水线技术
即通过多个功能部件并行工作来缩短程序执行时间,提高处理器的效率和吞吐率的技术。ARM7处理器使用了三级流水线的冯诺依曼结构,ARM9使用了五级流水线的哈佛结构。
PC代表程序计数器,指令分为三个阶段执行:
- 取值,从存储器装载一条指令;
- 译码,识别将要被执行的指令;
- 执行,处理指令并将结果写回寄存器。
PC总是指向正在取值的指令,而我们将正在执行的指令称为第一条指令,因此PC总是指向第三条指令,在ARM指令模式下,每条指令是4个字节,所以PC的地址为当前程序地址+8。
CPU正在译指的指令地址为PC-4,执行的指令地址为PC-8,当发生中断时,保存的是PC地址,而PC-4就是下一条指令的地址。
2.3 ARM的工作模式
模式 | 特点 | 用途 |
---|
用户模式USR | 运行在操作系统的用户态,没有权限操作其他硬件,只能执行自己的数据 | 用户程序的工作模式 |
系统模式SYS | 特权模式,不受用户模式限制,与用户模式共用一套寄存器 | 一些特权任务用这个模式访问一些受控的资源 |
一般中断模式IRQ | 特权模式,可以自由访问系统硬件资源 | 处理一般的中断请求 |
快速终端模式IRQ | 有自己的专用寄存器R8-R14,发生中断时可以不用保存和恢复某些寄存器 | 处理比较紧急的中断,如高速数据传输、通道处理 |
管理模式SVC | CPU上电后默认模式 | 主要用于系统初始化,软中断处理也在SVC模式下 |
终止模式ABT | 用户程序访问非法地址、没有权限读取内存地址时进入该模式 | 用于支持虚拟内存或存储器保护 |
未定义模式UND | CPU在指令译码阶段不能识别指令时进入该模式 | 支持硬件协处理器的软件仿真 |
2.4 ARM的寄存器组
ARM共有37个32位的寄存器,包含31个通用寄存器和6个状态寄存器。可见的通用寄存器与16个,即R0-R15,可以分为三类:
- 未备份寄存器:R0-R7。所有模式下,未备份寄存器都指向同一个物理寄存器,未被系统用作特殊用途;
- 备份寄存器:R8-R14。它们每次访问的物理寄存器都与当前的处理器运行模式有关。R13常用作存放堆栈指针,R14常用来保存返回地址;
- 程序计数器PC:R15。
- CPSR:当前程序状态寄存器,所有模式都共用一个CPSR。
- SPSR:备份程序状态寄存器,除了USR和SYS外,特定的异常中断发生时,SPSR寄存器用来保存当前程序状态寄存器(CPSR)的值,当异常退出以后可以用SPSR中保存的值来恢复CPSR。
2.5 ARM处理器的工作状态
- ARM状态,执行32位的字对齐ARM指令,绝大部分工作处于该状态;
- Thumb状态:执行16位的半字节对齐的Thumb指令。
2.6 ARM系统函数调用参数的传递方式
- 参数小于等于4的时候通过R0-R3寄存器来进行传递;
- 参数大于4时通过压栈传递。
2.7 ARM协处理器3类指令的功能
- ARM处理器初始化ARM协处理器的数据处理操作(CDP);
- ARM处理器的寄存器和ARM协处理器的寄存器之间的数据传递操作(MCR/MRC);
- ARM协处理器的寄存器和内存单元之间的数据传递(LDC\STC)。
2.8 什么是PLL (锁相环)
PLL是为了产生一个不同频,但锁相的信号。如某晶振10Mhz,频率综合器使用该参考源产生了900Mhz的时钟,另一个频率综合器产生了1Ghz的时钟,两路频率不一样,但仍为同源信号。
3. 中断与异常
3.1 中断与异常的区别
- 中断指外部硬件产生的一个电信号从CPU的中断引脚进入,打断CPU的运行;
- 异常指软件运行过程中发生了必须处理的时间,CPU自动产生一个陷入打断CPU的运行。
3.2 中断与DMA的区别
- DMA:一种无需CPU参与,就可以让外设与系统内存之间进行双向数据传输的硬件机制;
- 中断:CPU执行程序过程中,出现某些突发事件,CPU暂停执行当前的任务,去处理突发事件,处理完毕后返回被中断的位置继续执行。
3.3 中断的响应执行流程
CPU接受中断>保存中断上下文跳转到中断处理历程>执行中断上半部>执行中断下半部>恢复中断上下文
3.4 中断能不能睡眠?
- 中断上半部:如3.3中的前三个步骤属于中断上半部,在几个步骤中,所有中断都是被屏蔽的,如果这时候睡眠了,操作系统不会收到任何中断,系统处于瘫痪状态。
- 中断下半部(软中断):中断运行在中断上下文,没有一个所谓的中断描述符来描述它,它不是操作系统的调度单位。一旦在中断上下文中睡眠,首先无法切换上下文(没有中断描述符,当前上下文的状态得不到保存),其次没有人来唤醒它,因为它不是操作系统的调度单位。
3.5 一个异常出现后,ARM微处理器会执行哪些操作
- 将下一条指令的地址存入寄存器LR即R14;
- 将CPSR复制到相应的SPSR中;
- 根据异常类型,强制设置CPSR的运行模式位;
- 强制PC从相关的异常向量地址取下一条指令执行,跳转到相应的异常处理程序。
3.6 写一个中断服务程序的注意点,中断产生后要做较多的事应该怎么办
- 写一个中断服务程序要快进快出,在中断服务程序里尽量快速采集信息,包括硬件信息,然后退出;
- 中断服务程序中不能有阻塞操作,中断期间是完全占用CPU的,中断被阻塞住,其他进程无法操作;
- 中断服务程序注意返回值,要用操作系统定义的宏为返回值,不能自己定义;
- 如果要做的事情多,应将这些任务放在中断下半部。
3.7 为什么FIQ比IRQ快
- FIQ模式有更多的备份寄存器,R8-R14和SPSR;IRQ模式没有R8-R12对应的备份寄存器,中断处理程序要自己保存R8-R12寄存器,退出时要恢复这几个寄存器;
- FIQ比IRQ有更高优先级,如果它们同时产生,那么FIQ先处理;
- 在异常向量表中,FIQ处在最末尾。在异常向量表中IRQ只能保存中断处理程序的首地址,在发生IRQ时需要一次跳转;而FIQ处在最末尾,所以可以直接将FIQ模式下的中断处理程序紧接着存放,这样在处理FIQ时就少一次跳转。
3.8 中断和轮询那个效率高,使用场景如何?
- 中断是CPU被动地接收设备的信号,一般设备如果请求cpu的频率较低,则用中断效率高;
- 轮询是CPU主动地去查询该设备是否有请求,如果设备频繁请求CPU,那么轮询的效率高。
4.通信协议
4.1 同步传输和异步传输
- 同步传输:需要外界的时钟信号进行通信,把数据字节组合在一起发送,组合称为帧,传输速度较快;
- 异步传输:典型的基于字节的输入输出,数据按每次一个字节进行传输,传输速度低。
4.2 RS232和RS485
区别 | RS232 | RS485 |
---|
传输方式 | 不平衡传输,单端通讯 | 平衡传输,差分传输 |
传输距离 | 不超过20m | 几十米到上千米 |
设备数量 | 一对一通信 | 总线上允许连接多达128个收发器 |
连接方式 | 电平表示数据,单线路,要两根线实现全双工 | 差分电平表示数据,两根线才能传输数据,全双工要4根线 |
4.3 SPI协议
4.3.1 SPI的应用和接口
SPI协议,即串行外围设备接口,是一种高速全双工的通信总线。可以使MCU与各种外围设备以串行方式进行通信以交换信息。
接口:
- MOSI:主设备输出/从设备输入引脚;
- MISO:主设备输入/从设备输出引脚;
- SCLK:时钟信号线,用于通讯数据同步,由通讯主机产生;
- SS:从设备选择信号线,即片选信号线,SPI协议没有设备地址,SS被置为低的设备被选中为从设备,和主设备通信。
4.3.2 协议层
SPI设备常见的连接方式如下:
SPI的通讯时序如下:
- 图中标号1处,NSS线由高变低,就是通讯起始信号;NSS由低变高,就是通讯的停止信号;
- SPI使用MOSI和MISO来传递数据,使用SCK信号线来进行数据同步,SCK的每个时钟周期都会传输一位数据,输入输出是同事的,一般MSB先行,即高位先行;
- CPOL(时钟极性)/CPHA(时钟相位)及通讯模式:SPI一共有四种通讯模式,区别在于总线空闲时SCK的时钟状态及数据采样时刻。
4.4 IIC协议
IIC协议是由数据线SDA和时钟SCL构成的串行总线,可发送和接收数据,是一个多主机的半双工通信方式,每个挂接在总线上的器件都有一个唯一的地址。
时序介绍:
- 空闲状态:SDA和SCL同时处于高电平状态,就是空闲状态,两条线都被上拉电阻拉高;
- 起始信号:SCL为高期间,SDA由高向低跳变,只能由主机发起;
- 停止信号:SCL为高期间,SDA由低到高跳变;
- 传输数据格式:发了起始信号后,就开始传输数据;SCL为高电平期间,获取SDA数据值,这期间SDA数据必须是稳定的;当SCL为低电平时,便是SDA的电平变化状态;
- 应答信号ACK:I2C总线的数据以8位数据(字节)进行,发送8个数据后,发送方在第9个时钟脉冲期间释放SDA数据,接收方接收该字节成功,输出一个ACK应答信号;
- 完整的数据传输:发送起始信号后,便发送一个8位的设备地址,第8位是读写标志,紧跟着就是数据;
- IIC传输数据的格式:读和写操作的格式如下。
5. 编程
5.1 大端和小端
- 大端模式:低位字节存储在高地址上,高位字节存储在低地址上;
- 小端模式:高位字节存储在高地址上,低位字节存储在低地址上;
5.2 如何判断计算机是大端还是小端
#include<stdio.h>
int checkCPU()
{
union w
{
int a;
char b;
}c;
c.a = 1;
return(c.b == 1);
}
int main()
{
if(checkCPU())
{
printf("小端\n");
}
else
{
printf("大端\n");
}
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
5.3 大小端转换
int swapInt32(int intValue)
{
int tmp = 0;
tmp = ((intValue & 0x000000FF) << 24 |
(intValue & 0x0000FF00) << 8 |
(intValue & 0x00FF0000) >> 8 |
(intValue & 0xFF000000) >> 24));
return tmp;
}
5.4 如何操作绝对地址0x100000
*(unsigned int*)0x100000 = 1234;
*((void(*)())0x100000)();
void(*)()0x100000;
*((void(*)())0x100000)();