嵌入式八股文-ARM
网上有很多八股文 但还是想自己总结以下 部分内容有借鉴这位博主嵌入式八股文总结(ARM篇)-CSDN博客
一、I2C通信
1.I2C基本概念
I2C一共有两根通信线:时钟线SCL(Serial Clock)、数据线SDA(Serial Data),同步、半双工。
如图1所示,在空闲时时钟线和数据线都处于高电平状态。
(1)起始条件:SCL高电平期间,SDA从高电平切换到低电平。
(2)终止条件:SCL高电平期间,SDA从低电平切换到高电平
(3)应答信号:
(4)在SCL高电平时为数据采样阶段,数据线SDA必须保持稳定。SCL为低电平时为数据放置阶段,数据线SDA才能变化。这样规定有效的区分了数据采样阶段和数据放置阶段。
(5)指定地址写数据:•对于指定设备(Slave Address),在指定地址(Reg Address)下,写入指定数据(Data)如图2所示,
I2C设备地址多为7位地址(也有10位地址)。
发送起始信号后紧跟着的是 7位地址+1位读写位(0表示写数据,1表示读数据;)
接收到应答信号后,发送寄存器地址。然后就可以发送数据了,发送完成后为终止信号。若要发送多个字节的数据,只用接收到应答信号后持续发送数据,若需要停止发送终止信号。
(6)指定地址读数据:指定地址读的前两位和写数据一样,首先发送从机地址(地址+0写数据位)+寄存器地址,然后再发送一次从机地址(这里是地址+1读数据位),此时就能读取指定地址下的数据,读取完成后发送终止信号。
2.I2C常问问题
(1)I2C为什么需要加上拉电阻,一般为多大,为什么需要使用开漏输出?
I2C支持总线挂载多设备(一主多从、多主多从),当两个设备同时抢占总线时,当主设备 A 输出高电平(1
),主设备 B 输出低电平(0
)时,会形成 电源到地的短路路径,烧毁器件!
而开漏输出无高电平状态,当设备拉低总线时就获得控制权,此时就需要增加上拉电阻,赋予高电平状态。
上拉电阻大小一般如图所示:
(2)I2C通信失败该怎样排查问题?
-
硬件:电源、地、上拉电阻(值是否合适?存在吗?)、线路连接(短路/断路)、总线电容是否过大。
-
软件:SCL/SDA GPIO 配置是否正确(开漏输出?上拉使能?)、I2C 外设初始化参数(速率、地址)、时序是否符合规范(特别是启动/停止/ACK)。
-
工具:用示波器或逻辑分析仪抓取 SCL/SDA 波形(最有效!),查看是否有起始/停止/ACK/数据波形,电平是否正常,时序是否满足要求。
-
设备:确认从机地址是否正确、从机是否正常工作(电源、复位)、是否存在地址冲突。
(3)什么是I2C死锁,怎样解决?
现象:I2C死锁就是时钟线SCL一直处于高电平,数据线SDA一直处于低电平。
原因:从机拉低数据线SDA时(发送应答信号给主机时或发送数据0时)主机意外复位,主机复位后时钟线SCL就为高电平了,此时,SCL为高电平而SDA为低电平,主机就以为有其他设备占有了总线,而SCL为高电平时 数据位SDA不允许有变化,意思是:主机就一直等待时钟线SDA拉高,而从机就一直等待时钟线SCL拉高 就造成了死锁的现象。
解决方法:1.选择带有复位功能的从设备,复位后SDA被拉高。2.设置时钟延展时间:当检测到SDA低电平超过预设时间,超时则强制复位并终止传输。3.主机检测SDA被拉低超过指定时间后,主动复位从设备,前提需要主机具有控制有复位引脚的从设备
(4)I2C最多可以挂载多少个设备?
理论上可以挂载112个设备(七位从机地址)
AI给的,理论可以挂载2^7 - 不可用地址 = 112个
但是I2C协议没有限制总线上的最大设备数,但是规定了总线电容不得超过400pF,所以实际上I2C总线上的设备数推荐不超过8个。
(5)常见的I2C设备有什么?你用过那个?遇到过什么问题,怎样解决的?
常见的有:EEPROM芯片、MPU6050、一些OLED屏
EEPROM和MPU6050是我经常使用的,其中EEPROM是一款可擦可编程只读存储器,型号为24C02,当时在完成BootLoder代码时需要存储一些重要的标志位,不允许掉电丢失,所以将其存储到EEPROM芯片当中。
问题:当时遇到了写入后读取数据错误。
-
主机连续写入 64 字节(页写)后立即读取,返回的数据随机错误(部分字节为0xFF或旧数据)。
-
根本原因:跨页写入时未拆分数据(24LC256 页大小为64字节),导致地址回卷(Address Wrapping)。
-
解决方案:强制页写拆分;
(6)你写IIC驱动的时候,速率是多少?
在使用硬件IIC的时候,我一般选择标准模式(速率为100KHz),但在需要高频读取数据时,总线可能会成为瓶颈,导致数据丢失或延迟,这时我会选择快速模式(400KHz)。
在使用软件IIC的时候,不需要想硬件IIC那样设置固定速率,软件IIC速率完全由自己决定。例如在软件IIC写SCL或SCK的时候我会选择延迟个10us,防止时序频率超过要求。
二、SPI通信
1.SPI通信基本概念
SPI通信模式一共有四根通信线:
SCK(Serial Clock):时钟线
MOSI(Master Output Slave Input):主机输出从机输入
MISO(Master Input Slave Output):主机输入从机输出
SS(Slave Select):片选线
SPI具有两根数据线 所以支持同时收发数据 并且具有时钟线 属于全双工同步通信
如图所示:
•所有SPI设备的SCK、MOSI、MISO分别连在一起
•主机另外引出多条SS控制线,分别接到各从机的SS引脚
•输出引脚配置为推挽输出,输入引脚配置为浮空或上拉输入
(1)起始条件:只用将片选信号拉低 终止条件:将片选信号拉高
(2)工作模式:SPI一共有四种工作模式
时钟极性决定SCK的电平起始电平 相位决定采样时刻
以模式0为例,如图所示:我们可以看到MISO刚开始为高阻态,是因为对于主机来说,未被使能的从机是输出到主机的,若同时开始会造成冲突,则在SS未被使能的情况下,MISO处于高阻态。
片选信号先拉低 在SCK的第一个上升沿采样数据,在第二个边沿放数据,第三个边沿采样数据,直到数据传输完成,SS拉高结束。
2.SPI常见问题
(1)SPI可以去掉那些线?
SPI有四根线:SCLK、MISO 、MOSI、CS。当只需要主机向从机发送指令,而不需要从机回复数据时,MISO信号线就可以去掉;当主机只想读取从机的数据,而不需要向从机发送指令时,MOSI就可以去掉;如果只有一个从机,那么CS片选线也可以不要,直接将其固定为有效电平,一直处于使能的状态。需要注意的是,时钟线不能去掉,发送数据和接收到数据时都需要使用时钟线进行数据采样。
(2)SPI和I2C的差别是什么?
SPI只有两根线而SPI具有四根线 I2C的通信则要复杂一点
(3)SPI通信失效如何排查?
(4)面试管问你常用的SPI设备有什么?你遇到过什么问题?是怎样解决的?
我用过的SPI设备有:存储芯片W25Q64和SPI OLED屏幕
在写BootLoder程序时,用W25Q64当作外部Flash使用,用于存储不同的APP代码和阿里云下发的APP代码。但是在写外部Flash的时候总是遇到偏移量不好计算的问题。具体来说,因为我是通过Xmode协议一片一片写入Flash当中的,每片数据的大小固定,但不同APP代码的总长度不一样,比如数据写入到某个地址后,下一片数据的起始偏移量需要准确衔接,可一旦某片数据的处理出现偏差,后续分片的偏移量都会出错,导致APP无法正常加载。
为了解决这个问题,我在代码中加入了分片校验和偏移量预检查机制。每处理一片数据前,先检验该片的序号是否连续。
还有个最简单的问题,我写入Flash时后读取总为FF,结果发现是片选没使能。
三、串口通信
1.基本概念
•串口是一种应用十分广泛的通讯接口,串口成本低、容易使用、通信线路简单,可实现两个设备的互相通信
•单片机的串口可以使单片机与单片机、单片机与电脑、单片机与各式各样的模块互相通信,极大地扩展了单片机的应用范围,增强了单片机系统的硬件实力
普通串口有两根线 发送TX 接收RX •TX与RX要交叉连接 当只需要单向传输时只用一根通信线当电当电平标准不一致时,需要加电平转换芯片,如图所示。
串口参数及时序:
(1)波特率:串口通信的速率
(2)起始位:标志一个数据帧的开始,固定为低电平
(3)数据位:数据的有效载荷,1为高电平,0为低电平,低位先行
(4)校验位:用于数据验证,根据数据位计算得来
(5)停止位:用于数据帧间隔,固定位高电平
2.RS485基本理念
RS485用于工业和通信领域的串行通信标准,具有通信距离长、多点通信、抗干扰能力强的特点。
(1)差分信号:RS485有两根信号线(通常为A或B,或者Data+和Data-),RS485是通过两根线之间的电压差来表达传输逻辑,通常A B 差>200mv代表逻辑1,A B差<200mv代表逻辑0。 相比单端信号,差分信号对噪声的抗干扰能力更强,因为噪声通常影响两条线的相同程度,因此它们之间的电压差不会受到噪声的显著影响。
(2)多点总线拓扑:RS485设计用于连接多个设备到同一条通信总线上。
(3)半双工模式:这是常见的RS485应用模式,所有设备共享一对信号线,同一时间只能有一个设备发送数据(作为发送器),其他设备只能接收(作为接收器)。需要一个通信协议(如Modbus)来管理那个设备在何时获得总线控制权。
这里的RS485是硬件层协议:用于解决逻辑电平0和1的可靠传输
Modbus协议是软件层面:解决传输目的,解决为什么两者要传输的协议,与之前的I2C和SPI物理层协议不同,Modbus协议是应用层协议,
3.串口通信常见问题
(1)面试官问在处理串口数据时你是怎样设计处理方案的?
1.在非裸机的项目中,我通常在中断中接收数据,任务中处理数据。具体来说,在中断服务程序中(ISR)仅将数据存入缓冲区中,再通过同步信号(如队列、任务通知、信号量)唤醒处理任务。任务在没有唤醒前一直处于阻塞状态,等到ISR发送数据到达信号,接收到信号后,从缓冲区取出数据进行数据处理(解包、校验、执行业务逻辑)。
2.在裸机项目中,可以采用中断存储数据+状态机解析的方案。具体来说,就是在ISR中使用环形缓冲器暂存数据,接收完数据后置位标志位。循环中检查标志位,状态机实现协议解析。
四、什么是回调函数?
回调函数就是一个通过函数指针来调用的函数。
-
你把一个函数(B)的引用作为参数传递给另一个函数(A)。
-
函数 A 执行完自己的任务后,回过头来调用(Call Back)你传给它的那个函数 B。
-
所以,函数 B 就是回调函数。
五、中断函数
1.定义
中断函数,也叫中断服务程序(ISR - Interrupt Service Routine),是嵌入式系统中用于响应硬件中断的特殊函数。
2.常见的面试问题
(1)中断函数为什么需要快进快出
如果ISR执行时间过长,其他同等或更高优先级的中断无法及时得到响应,可能导致事件丢失。并且长时间处理中断会影响主程序的运行,影响系统整体性能和响应速度。
(2)如果中断处理需要做很多耗时的操作,你该怎么办?
在ISR中只做最紧急的事,如清除标志位、读取数据,然后通过设置标志位、发送信号量等方式通知主循环或任务来处理耗时的逻辑。
(3)volatile
可以在中断函数中使用吗?一般怎样使用?
“volatile
在中断中至关重要,主要用于修饰那些在中断服务程序和主循环(或非ISR任务) 之间共享的全局变量。
六、嵌入式基于ROM运行和基于RAM运行有什么区别
基于ROM运行:程序代码直接在非易失性存储器(如FLASH)中被CPU读取和执行。
基于RAM运行:程序代码先从非易失性存储器复制到易失性存储(RAM)中,然后CPU再从RAM中读取并执行。
这里的“ROM”是现代嵌入式系统中Flash存储器的统称。
七、BootLoader/IAP
BootLoader:中文名为引导加载程序,是嵌入式系统中一段存储再非易失存储器(Flash)起始地址的底层程序,相当于启动管家。它负责在系统上电后初始化硬件,验证用户程序完整性,并决定是否跳转到APP执行。
八、介绍下TCP 连接中的“三次握手”和“四次挥手”
(1)三次握手定义
1.三次握手的目标是同步序列号,确保双方都准备好发送和接收数据。序列号是TCP实现可靠传输的关键。(同步服务器和客户端之间的通信)
①:客户端向服务器发送SYN=1(同步序列号),并随即生成一个初始序列号(seq=x),客户端状态由关闭(CLOSED)进入SYN-SENT(同步发送);
②:服务器收到并同意之后,服务器设置SYN=1和ACK=1(应答信号)并随机生成初始序列号(seq=y)。同时,将确认号设置为ack = x +1(客户端的序列号 + 1),表示已经收到客户端序列号了,希望下次从x+1的位置开始接收数据。
③:客户端收到服务器的包之后,向服务器发送一个确认包,ACK=1,将序列号设置为seq = x+1,(即第二次服务器希望的),再将确认号设置为ack = y +1,表示收到了服务器的序列号。最后客户端和服务器都进入连接模式。
简洁说:客户端:发送同步信号;服务器:收到了,你能接收到我的信息吗?客户端:我也收到了,连接成功可以开始通信了。
(2)四次挥手定义
四次挥手的目标是安全地、可靠地关闭双向数据流。因为TCP连接是全双工的,每个方向必须单独关闭。
①:主动关闭方(如客户端)发送一个TCP数据包。包中为FIN=1(完成标志位),一个序列号seq = u。客户端状态由已连接-终止等待1。
②:服务器收到后,发送确认包。包中为ACK=1,将确认号设置为ack = u + 1;序列号为 seq = v;
服务器由已连接-关闭等待;客户端状态由终止等待1-终止等待2;
此时TCP处于半关闭状态,客户端已无消息发送,服务器可能还有数据要送,此时为单端通信;
③此时,服务器还会发送一个包;关闭它与客户端的连接;包中为结束标志位FIN = 1,seq = w,确认号不变为 ack = u + 1;服务器状态由关闭等待-最后确认;
④:客户端接收到FIN后,发送确认包。包中为ACK = 1; seq = u + 1;ack = w + 1;
客户端从终止等待2-时间等待状态后,等待2MSL后才进入关闭状态。
服务器接收到ACK后就立即关闭。
简洁说:要关闭连接的话,主动连接方发送完成标志位(FIN),被动关闭方接收到后发送ACK(确认),被动关闭方再发送与主动方关闭连接的完成标志位(FIN),主动关闭方接收到后,发送ACK,确认双方断开连接,两者均进入到关闭状态。