在学习的时候找到几个十分好的工程和个人博客,先码一下,内容都摘自其中,有些重难点做了补充!
才鲸 / 嵌入式软件笔试题汇总
嵌入式与Linux那些事
阿秀的学习笔记
小林coding
百问网linux
嵌入式软件面试合集
2022年春招实习十四面(嵌入式面经)
NAND Flash和NOR Flash都是非易失性存储器(Non-Volatile Memory,NVM)的一种,但是它们在存储方式、结构和应用场景等方面有很大的差异。
页(Page)和块(Block)
的存储结构,它将多个存储单元组成一页,然后将多个页组成一个块。NOR Flash的存储单元是基于字节(Byte)
的存储结构,每个字节都可以单独进行读写操作。串联
的,每个存储单元之间有一个选择器(Selector)进行控制。NOR Flash的存储单元是并联
的,每个存储单元都可以直接访问。适用于大容量数据存储
,如固态硬盘(SSD)和USB闪存驱动器等。而NOR Flash的存储单元小且存储密度低,因此它适用于需要快速读取
的应用场景,如嵌入式系统和手机等。**交叉编译(Cross-Compilation)**是指在一种操作系统上编译能在另一种操作系统上运行的程序的过程。在交叉编译过程中,编译器和相关工具链需要根据目标平台的特定架构生成可执行文件,并将其移植到目标平台上运行。
交叉编译通常用于嵌入式系统、移动设备和其他跨平台应用程序的开发中。在这些应用场景中,由于资源受限和平台差异等原因,需要将代码和可执行文件移植到目标平台上运行。使用交叉编译技术可以使开发人员在开发和测试阶段快速迭代,并在最终部署时获得更高的效率和性能。
交叉编译的过程通常包括以下步骤:
交叉编译技术对于嵌入式系统、移动设备和其他跨平台应用程序的开发非常重要,可以提高开发效率和部署效率,同时还可以确保程序在不同平台上的稳定性和性能。
嵌入式系统可以基于ROM(只读存储器)或RAM(随机存储器)来运行,它们之间的主要区别在于存储器的性质和使用方式。
基于ROM的运行方式:程序代码和数据通常存储在ROM中,这些存储器中的数据只能被读取,不能被写入或修改
。因此,在运行时,程序代码和数据必须从ROM中读取到RAM中进行处理。由于ROM的存储容量通常比RAM大,因此可以存储更多的程序代码和数据。
基于RAM的运行方式:程序代码和数据存储在RAM中,这些存储器中的数据可以被读取、写入和修改
。因此,在运行时,程序代码和数据可以直接从RAM中读取和处理。由于RAM的存储容量通常比ROM小,因此可以存储的程序代码和数据量相对较小。
综上所述,基于ROM的嵌入式系统可以存储更多的程序代码和数据,但在更新程序代码或数据时较为困难;基于RAM的嵌入式系统可以进行灵活的程序代码和数据更新,但存储空间相对较小。
定义
指令和数据统一编址,使用同条总线传输
,CPU读取指令和数据的操作无法重叠
。指令和数据独立编址,使用两条独立的总线传输
,CPU读取指令和数据的操作可以重叠
。流水线技术通过多个功能部件并行工作来缩短程序执行时间,提高处理器核的效率和吞吐率,从而成为微处理器设计中最为重要的技术之一。ARM7
处理器核使用了典型三级流水线的冯·诺伊曼
结构,ARM9
系列则采用了基于五级流水线的哈佛结构
。通过增加流水线级数简化了流水线各级的逻辑,进一步提高了处理器的性能。
ARM流水线技术是一种通过将CPU指令执行过程拆分成多个阶段,从而提高CPU性能和效率的技术。ARM处理器是一种基于RISC架构的CPU,其流水线技术被广泛应用于各种嵌入式设备和移动设备。
ARM流水线技术的核心思想是将CPU指令的执行过程分解成多个阶段,每个阶段只执行指令的一部分操作。不同的指令可以在不同的阶段执行,从而实现多条指令同时在执行的效果。这种技术可以有效地提高CPU的运行速度和效率,同时也降低了CPU的功耗。
ARM处理器的流水线一般分为以下几个阶段:
ARM处理器有七种工作模式,分别为:
通用寄存器包括R0-R15,可以分为3类:
未分组寄存器R0-R7
在所有运行模式下,未分组寄存器都指向同一个物理寄存器,他们未被系统用作特殊的用途。因此在中断或异常处理进行异常模式转换时,由于不同的处理器运行模式均使用相同的物理寄存器,所以可能造成寄存器中数据的破坏。
分组寄存器R8-R14
对于分组寄存器,他们每次所访问的物理寄存器都与当前的处理器运行模式相关。R13常用作存放堆栈指针
,用户也可以使用其他寄存器存放堆栈指针,但在Thumb指令集下,某些指令强制要求使用R13存放堆栈指针。R14称为链接寄存器
(LR,Link Register),当执行子程序时,R14可得到R15(PC)的备份,执行完子程序后,又将R14的值复制回PC,即使用R14保存返回地址。
程序计数器PC(R15)
寄存器R15用作程序计数器
(PC),在ARM状态下,位[1:0]为0,位[31:2]用于保存PC;在Thumb状态下,位[0]为0,位[31:1]用于保存PC。
在ARM系统中,在函数调用时,函数参数的传递可以通过以下两种方式实现:
寄存器传递(Register Passing):函数参数可以直接存储在通用寄存器R0到R3中。对于前4个参数,ARM规定它们应该按顺序存储在R0~R3中,如果参数个数超过4个,则余下的参数应该存储在栈中。在函数体内,可以直接使用这些寄存器中的值来访问函数参数。
栈传递(Stack Passing):当函数参数个数超过4个时,多余的参数将被存储在栈中。在函数调用前,程序将参数按照倒序依次压入栈中,然后调用函数。在函数内部,程序可以通过栈指针(SP)来访问这些参数。
中断是指外部硬件产生的一个电信号从CPU的中断引脚进入,打断CPU的运行。
异常是指软件运行过程中发生了一些必须作出处理的事件,CPU自动产生一个陷入来打断CPU的运行。
异常在处理的时候必须考虑与处理器的时钟同步,实际上异常也称为同步中断,在处理器执行到因编译错误而导致的错误指令时,或者在执行期间出现特殊错误,必须靠内核处理的时候,处理器就会产生一个异常。
DMA:是一种无须CPU的参与,就可以让外设与系统内存之间进行双向数据传输的硬件机制,使用DMA可以使系统CPU从实际的I/O数据传输过程中摆脱出来,从而大大提高系统的吞吐率。
中断:是指CPU在执行程序的过程中,出现了某些突发事件时,CPU必须暂停执行当前的程序,转去处理突发事件,处理完毕后CPU又返回源程序被中断的位置并继续执行。
所以中断和DMA的区别就是:DMA不需CPU参与,而中断是需要CPU参与的
。
中断不能睡眠。中断是一种异步事件,当中断事件发生时,处理器会立即停止当前的任务,转而执行中断服务程序来处理这个事件。因此,中断服务程序必须要能够快速响应中断事件,不能进行睡眠等可能导致延迟的操作。如果中断服务程序睡眠,那么处理器就无法响应中断事件,可能会导致系统崩溃或者出现其他严重问题。
下半部可以睡眠。下半部是指中断服务程序处理过程中可能需要完成的一些后续操作,例如数据传输、内存释放等。下半部通常是在中断处理程序执行完毕后异步地执行的,因此可以进行一些比较耗时的操作,例如等待IO操作完成或者进行内存管理等。由于下半部不是在中断上下文中执行,因此可以进行睡眠等可能导致延迟的操作。
需要注意的是,下半部睡眠的时候,需要确保系统不会在下半部执行期间再次触发中断,否则可能会导致下半部执行不完整或者出现其他问题。为了避免这种情况,一般会在下半部执行期间禁用中断,然后在下半部执行完毕后重新启用中断。
中断的响应执行流程通常包括以下几个步骤:
中断触发:当中断事件发生时,外部硬件设备或者软件会向CPU发送中断请求信号,CPU接收到信号后停止当前任务的执行,开始处理中断请求。
中断向量:CPU根据中断请求信号中携带的信息,定位到对应的中断处理程序的入口地址。这个地址称为中断向量,可以是一个固定的物理地址或者一个由操作系统动态分配的虚拟地址。
中断处理程序:CPU跳转到中断向量指定的地址,开始执行中断处理程序。中断处理程序是一个特殊的程序,用于处理中断事件。中断处理程序需要快速响应中断请求,完成相应的操作,并在完成后返回到原来的任务中继续执行。
中断上下文:中断处理程序执行时,会保存当前任务的上下文信息,包括程序计数器、状态寄存器、堆栈指针等,将这些信息保存在内存中。这些信息组成了中断上下文,用于在中断处理程序执行完毕后恢复任务的执行状态。
中断服务程序:中断处理程序可能需要调用其他的服务程序来完成一些操作,例如读取和写入设备寄存器、发送和接收数据等。这些服务程序称为中断服务程序。
中断返回:当中断处理程序完成所有的操作后,会从中断上下文中恢复任务的执行状态,包括程序计数器、状态寄存器、堆栈指针等,将这些信息恢复到CPU的寄存器中。然后,CPU从中断处理程序返回到原来的任务中继续执行,恢复任务的执行状态。
在 ARM 处理器中,FIQ(Fast Interrupt Request)和 IRQ(Interrupt Request)都是用于处理中断请求的机制。但是 FIQ 比 IRQ 快的原因是因为
具体来说,当 FIQ 发生时,CPU 会立即中断正在执行的指令,并切换到 FIQ 模式。在 FIQ 模式下,CPU 会禁用 IRQ 和一些正常运行的操作,如中断响应器(Interrupt Response Controller)、预取器(Prefetch Unit)
等,从而使 FIQ 能够更快地得到处理。此外,FIQ 还具有更多的寄存器和更大的中断向量表
,可以更灵活地处理中断请求。
相比之下,IRQ 的优先级较低,当 IRQ 发生时,CPU 会在当前指令执行完毕后才处理 IRQ 请求。此外,IRQ 在处理时不会禁用任何正常运行的操作,因此处理 IRQ 请求时可能会受到一些干扰,导致处理效率较低。
中断是CPU处于被动状态
下来接受设备的信号,而轮询是CPU主动去查询
该设备是否有请求。
凡事都是两面性,所以,看效率不能简单的说那个效率高。
UART:通用异步串行口,按照标准波特率完成双向通讯,速度慢。
UART是异步、全双工串口总线
。它比同步串口复杂很多。有两根线,一根TXD用于发送,一根RXD用于接收。
UART的串行数据传输不需要使用时钟信号来同步传输,而是依赖于发送设备和接收设备之间预定义的配置。
起始位:表示数据传输的开始,电平逻辑为“0” 。
数据位:可能值有5、6、7、8、9,表示传输这几个bit 位数据。一般取值为8,因为一个ASCII 字符值为8 位。
奇偶校验位:用于接收方对接收到的数据进行校验,校验“1” 的位数为偶数(偶校验) 或奇数(奇校验),以此来校验数据传送的正确性,使用时不需要此位也可以。
停止位:表示一帧数据的结束。电平逻辑为“1”。
如果用通用IO口模拟UART总线,则需一个输入口,一个输出口。
串口设置的一般步骤可以总结为如下几个步骤:
(1)串口时钟使能,GPIO时钟使能
(2)串口复位
(3)GPIO端口模式设置TX的GPIO工作模式为:GPIO_Mode_AF_PP;//复用推挽输出RX的GPIO工作模式为:GPIO_Mode_IN_FLOATING;//浮空输入
(4)串口参数初始化主要包含:波特率设置(115200)、8个数据位、1个停止位、无奇偶校验位、无硬件数据流控制、收发模式。
(5)开启中断并且初始化NVIC(如果需要开启中断才需要这个步骤)
(6)使能串口
(7)编写中断处理函数(可选)
USART(Universal Synchronous/Asynchronous Receiver/Transmitter)是一种通用的同步/异步收发器,可以实现串行通信,具有以下主要特点:
同步/异步通信:USART支持同步和异步
两种通信方式。
多种通信模式:USART支持多种通信模式,包括全双工、半双工和单向模式等。
支持多种数据格式:USART支持多种数据格式,包括8位、9位、10位数据位,支持奇偶校验和无校验等多种校验方式。
高速传输:USART可以实现高速传输,支持多种波特率,通常可以达到几十Mbps的传输速度。
支持多种中断:USART支持多种中断,包括接收中断、发送中断、帧错误中断、溢出中断等,可以通过中断机制实现数据的接收和发送。
多种工作模式:USART支持多种工作模式,包括普通异步模式、多主机模式、同步模式、单线模式等。
硬件流控制:USART支持硬件流控制,通过CTS(Clear To Send)和RTS(Request To Send)等信号实现发送和接收数据的流控制。
I2C (Inter-Integrated Circuit):由PHILIPS公司开发的两线式串行总线,用于连接微控制器及其外围设备。
I2C总线是一种同步、半双工双向的两线式串口总线
。它由两条总线组成:串行时钟线SCL和串行数据线SDA。
SCL线——负责产生同步时钟脉冲。
SDA线——负责在设备间传输串行数据。
该总线可以将多个I2C设备连接到该系统上。连接到I2C总线上的设备既可以用作主设备,也可以用作从设备。
主设备负责控制通信,通过对数据传输进行初始化,来发送数据并产生所需的同步时钟脉冲。从设备则是等待来自主设备的命令,并响应命令接收。
主设备和从设备都可以作为发送设备或接收设备。无论主设备是作为发送设备还是接收设备,同步时钟信号
都只能由主设备
产生。
如果用通用IO口模拟I2C总线,并实现双向传输,则需一个输入输出口(SDA),另外还需一个输出口(SCL)。
(1)开始信号:SCL 为高电平时,SDA 由高电平向低电平跳变,开始传送数据。
(2)结束信号:SCL 为高电平时,SDA 由低电平向高电平跳变,结束传送数据。
(3)应答信号:在I2C总线通信过程中,从设备在接收到数据后需要向主设备发送应答信号,表示已经准备好接收下一个数据位。应答信号由从设备向数据线上发送一个低电平信号,同时保持时钟线为高电平信号。主设备在接收到应答信号后,继续向从设备发送数据。如果从设备不能接收或者不希望接收下一个数据位,则可以发送非应答信号(即将数据线拉高)。
I2C总线的仲裁机制是通过SDA线上的电平
来实现的。
当一个设备想要控制总线时,首先会检测SDA线上的电平。如果SDA线上的电平为低电平
,表示总线上已经有其他设备在控制总线,此时该设备需要等待直到SDA线上的电平恢复为高电平。如果SDA线上的电平为高电平,表示总线上没有其他设备在控制总线,此时该设备可以开始向总线发送数据。
当两个或多个设备同时想要控制总线的时候,会出现冲突。此时,所有设备会同时检测SDA线上的电平,如果发现SDA线上的电平不同,就会进入仲裁过程。在仲裁过程中,所有设备都会继续发送自己的地址,并在发送完第一个字节后检测SDA线上的电平。如果检测到SDA线上的电平不同
,表示有其他设备已经获得了总线的控制权,此时正在发送数据的设备需要停止发送,并等待下一次机会。如果检测到SDA线上的电平相同
,表示当前设备获得了总线的控制权,可以继续发送数据。
需要注意的是,在I2C总线中,设备的地址是不同的,因此在仲裁过程中,只有一个设备会获得总线的控制权,其他设备将会等待下一次机会。如果多次仲裁后仍然无法解决冲突,就可能需要重新启动总线来重新开始通信。
SPI (Serial Peripheral Interface):MOTOROLA公司提出的同步串行总线方式。高速同步串行口。3~4线接口,收发独立、可同步进行。
SPI总线是同步、全双工双向的4线式串行接口总线。它是由“单个主设备+多个从设备”构成的系统。
在系统中,只要任意时刻只有一个主设备是处于激活状态的,就可以存在多个SPI主设备。常运用于AD转换器、EEPROM、FLASH、实时时钟、数字信号处理器和数字信号解码器
之间实现通信。
为了实现通信,SPI共有4条信号线,分别是:
主设备出、从设备入(Master Out Slave In,MOSI):由主设备向从设备传输数据的信号线,也称为从设备输入(Slave Input/Slave Data In,SI/SDI)。
主设备入、从设备出(Master In Slave Out,MISO):由从设备向主设备传输数据的信号线,也称为从设备输出(Slave Output/Slave Data Out,SO/SDO)。
串行时钟(Serial Clock,SCLK):传输时钟信号的信号线。
从设备选择(Slave Select,SS):用于选择从设备的信号线,低电平有效。
SPI 的工作时序模式由CPOL(Clock Polarity,时钟极性)和CPHA(Clock Phase,时钟相位)之间的相位关系决定,CPOL 表示时钟信号的初始电平的状态,CPOL 为0 表示时钟信号初始状态为低电平,为1 表示时钟信号的初始电平是高电平。CPHA 表示在哪个时钟沿采样数据,CPHA 为0 表示在首个时钟变化沿采样数据,而CPHA 为1 则表示在第二个时钟变化沿采样数据。
SPI接口,分类,四种模式,特点
SPI通信中有4种不同的操作模式,不同的从机设备可能在出厂时就被设置好了某种模式,并且无法更改。但是SPI通信必须处于同一种模式下才能进行。
因此我们应该对自己手里的SPI主机设备进行模式的配置,也就是通过CPOL(时钟极性)和CPHA(时钟相位)
来控制SPI主设备的通信模式,具体如下:
时钟极性(CPOL)定义了SCLK时钟线空闲状态时的电平:
时钟相位(CPHA)定义了数据位相对于时钟线的时序(即相位):
I2C线更少,比UART、SPI更为强大,但是技术上也更加麻烦些,因为I2C需要有双向IO的支持
,而且使用上拉电阻,抗干扰能力较弱
,一般用于同一板卡上芯片之间的通信,较少
用于远距离通信。
SPI实现要简单一些,UART
需要固定的波特率,就是说两位数据的间隔要相等,而SPI
则无所谓,因为它是有时钟的协议。
I2C的速度比SPI慢
一点,协议比SPI复杂一点,但是连线也比标准的SPI要少。
UART一帧可以传5/6/7/8位
,I2C必须是8位
。I2C和SPI都从最高位
开始传。
SPI用片选信号
选择从机,I2C用地址
选择从机。
传输线有两根,地线一根。电平是负逻辑:-3V ~ -15V逻辑“1”,+3V ~ +15V逻辑“0”。
RS-232串口通信传输距离15米左右。可做到双向传输,全双工
通讯,传输速率低20kbps 。
下图是DB9公头和母头的定义,一般用的最多的是RXD、TXD、GND三个信号。
单片机接口一般是TTL电平,如果接232电平的外设,就需要加TTL转RS232的模块。可用芯片MAX232进行转换。
RS-422有4根信号线:两根发送、两根接收和一根地线,是全双工通信
。
它有一个主设备,其余为从设备,从设备之间不能通信,所以RS-422支持点对多的双向通信。
RS-485采用平衡发送和差分接收,因此具有抑制共模干扰的能力。
采用两线半双工
传输,最大速率10Mb/s,电平逻辑是两线的电平差来决定的,提高抗干扰能力,传输距离长(几十米到上千米)。
+2V +6V逻辑“1”,-2 ~ -6V逻辑“0”。
TTL转成RS-485很常见,比如MAX485.
嵌入式里面说的串口,一般是指UART口。4个pin(Vcc,GND,RX,TX),用TTL电平。
PC中的COM口即串行通讯端口,简称串口。9个Pin,用RS232电平。
串口、COM口是指的物理接口形式(硬件)
。而TTL、RS-232、RS-485是指电平标准(电信号)
。
参考文章
CAN是控制器局域网络
的简称,是一种能够实现分布式实时控制的串行通信
网络。CAN总线的功能复杂且智能。主要用于汽车通信。
CAN总线网络主要挂在CAN_H和CAN_L,各个节点通过这两条线实现信号的串行差分传输,为了避免信号的反射和干扰,还需要在CAN_H和CAN_L之间接上120欧姆的终端电阻。
每一个设备既可做主设备也可做从设备。CAN总线的通信距离可达10千米(速率低于5Kbps),速度可达1Mbps(通信距离小于40M)。
CAN电平逻辑
CAN总线采用"线与"
的规则进行总线仲裁,1&0为0,所以称0为显性,1为隐性。
从电位上看,因为规定高电位为0,低电位为1,同时发出信号时实际呈现为高电位,从现象上看就像0覆盖了1,所以称0为显性,1为隐性。
CAN总线的特点:
1)可以多主方式工作,网络上任意一个节点均可以在任意时刻主动地向网络上的其他节点发送信息,而不分主从
,通信方式灵活。
2)网络上的节点可分成不同的优先级
,可以满足不同的实时要求。
3)采用非破坏性位仲裁
总线结构机制,当两个节点同时向网络上传送信息时,优先级低的节点主动停止数据发送,而优先级高的节点可不受影响地继续传送数据。
4)可以点对点,一点对多点及全局广播
几种传送方式接收数据。
5)直接通信距离最远可达10km(速率4Kbps以下)。
6)通信速率最高可达1MB/s(此时距离最长40m)。
USB接口最少有四根线,其中有两根是数据线,而所有的USB数据传输都是通过这两根线完成。它的通信远比串口复杂的多。
两根数据线采用差分传输
,即需要两根数据线配合才能传输一个bit,因此是半双工
通信,同一时间只能发送或者接收。
USB 规定,如果电压电平不变,代表逻辑1;如果电压电平变化,则代表逻辑0。
一般USB转串口都是用CH340G芯片。用串口通信比USB简单,因为串口通信没有协议。