嵌入式开发工程师笔试面试指南-面试题目整理(1)

1 ARM 有多少32位寄存器 ?

在 ARM 架构中,通常有 37 个 32 位寄存器,包括:

通用寄存器

R0 - R15:这 16 个寄存器是最常用的通用寄存器。其中 R0 - R3 通常用于传递函数参数和返回值,R4 - R11 用于保存局部变量等,R12 一般作为子程序内部的临时寄存器,R13 通常作为栈指针(SP),R14 为链接寄存器(LR),用于保存子程序的返回地址,R15 是程序计数器(PC),指向当前正在执行的指令地址的下一条指令地址。

特殊寄存器

CPSR:当前程序状态寄存器(Current Program Status Register),用于保存程序当前的运行状态,包括条件标志位、中断使能位、处理器模式等信息。

SPSR:备份程序状态寄存器(Saved Program Status Register),在异常发生时,用于保存 CPSR 的当前值,以便在异常处理结束后恢复原来的程序状态。

协处理器寄存器:ARM 架构支持协处理器,有多个协处理器寄存器用于特定的功能,如浮点运算等。

程序状态保存寄存器:用于在异常处理等情况下保存和恢复程序状态。

此外,在不同的 ARM 处理器版本和应用场景下,寄存器的数量和用途可能会略有差异,但一般来说都是在这个基础上进行扩展或调整。

2 CPU、MPU、MCU、SOC、SOPC联系和区别

CPU、MPU、MCU、SoC、SOPC 的联系和区别如下:

联系

它们都是集成电路芯片,是电子系统的核心部件,都可以处理数字信号,实现各种逻辑运算、数据处理等功能,且在架构和原理上有一定的相似性,都包含运算器、控制器等基本组成部分。

高级的 MCU、SoC、SOPC 通常会集成 CPU 作为核心处理单元,以实现更复杂的系统功能。

区别

CPU:即中央处理器,是计算机系统的运算和控制核心,主要进行算术逻辑运算、控制指令执行等,不包含内存、外设等,需搭配内存、主板芯片组等其他硬件才能构成完整系统,常见于电脑等。

MPU:即微处理器,是高性能的 CPU,强调运算和处理能力,有复杂指令集或高性能的精简指令集,用于对处理能力要求高的设备,如智能手机、平板电脑等。

MCU:即微控制器,把 CPU、存储器、定时器、计数器、多种接口等集成在一个芯片上,面向控制领域,对成本、功耗、可靠性要求高,用于家电、工业控制、汽车电子等。

SoC:即片上系统,将 CPU、GPU、内存、各种接口、通信模块等集成在一个芯片上,形成完整系统,注重系统集成和协同工作,用于手机、智能穿戴设备等。

SOPC:即可编程片上系统,基于可编程逻辑器件(FPGA)实现,可根据需求动态配置硬件电路,将软核 CPU 或硬核 CPU 与其他逻辑模块集成,灵活性高,用于科研、定制化产品开发等。

3 上拉、下拉、高阻态介绍

上拉、下拉和高阻态是数字电路中常见的概念,以下是它们的介绍:

上拉

定义:通过一个电阻将不确定的信号连接到高电平,使信号在默认状态下为高电平。

作用:确保在没有其他驱动信号时,信号引脚处于确定的高电平状态,防止信号悬空而产生不稳定或误触发的情况,常用于输入引脚,提高电路的抗干扰能力。

下拉

定义:与上拉相反,是通过电阻将信号连接到低电平,让信号在默认情况下为低电平。

作用:使信号引脚在无驱动时处于低电平,同样可避免信号悬空带来的问题,在一些电路中用于设定初始状态或确定特定的逻辑条件。

高阻态

定义:指电路中的某个节点或引脚既不呈现高电平也不呈现低电平,相当于该节点与其他电路部分断开连接,处于一种悬浮的高阻抗状态。

作用:常用于三态门电路等,实现多个设备共享总线等资源,当设备处于高阻态时,不会对总线上的信号产生影响,允许其他设备在总线上进行数据传输等操作。

4 串口协议讲一讲

串口协议即串行通信协议,是指数据一位一位地顺序传输的通信协议,常见的有 UART、RS-232、RS-485 等,以下是对串口协议的简要介绍:

UART:通用异步收发传输器,数据以帧为单位传输,一帧数据包含起始位、数据位、奇偶校验位和停止位。不使用时钟信号,靠双方约定的波特率来保证数据同步,适用于短距离、低速通信,如主板与外设通信。

RS-232:是 UART 的一种电气标准,规定了信号的电平、接口形状等。采用负逻辑,逻辑 “1” 为 - 3V 至 - 15V,逻辑 “0” 为 + 3V 至 + 15V,通信距离一般在 15 米以内,常用于计算机与调制解调器等设备连接。

RS-485:基于 UART,采用差分信号传输,抗干扰能力强,传输距离可达 1200 米左右,支持多节点通信,总线上可挂接多个设备,常用于工业控制、安防监控等领域的远距离、多设备通信。

5 IIC、SPI、UART、CAN协议区别

IIC、SPI、UART、CAN 协议的区别主要体现在以下几个方面:

通信方式

IIC:半双工通信,同一时刻只能进行发送或接收操作,通过 SDA(数据线)和 SCL(时钟线)两根线进行通信。

SPI:全双工通信,可同时进行数据的发送和接收,通常有四根线,分别是 MOSI(主出从入)、MISO(主入从出)、SCK(时钟线)和 SS(片选线)。

UART:半双工或全双工,常用的是异步通信,通过两根线,即 TXD(发送线)和 RXD(接收线)进行数据传输。

CAN:半双工通信,使用两根线 CAN_H 和 CAN_L,通过差分信号传输数据。

通信速率

IIC:标准模式下可达 100kbps,快速模式可达 400kbps,高速模式可达 3.4Mbps。

SPI:通信速率较高,可达到几十 Mbps,具体取决于设备和时钟频率。

UART:速率相对较低,常见的有 9600bps、115200bps 等。

CAN:速率根据不同的应用场景有所不同,最高可达 1Mbps。

应用场景

IIC:常用于连接低速的外围设备,如 EEPROM、传感器等,适合近距离、多设备的通信场景。

SPI:适用于需要高速数据传输的设备,如 Flash 存储器、ADC、DAC 等,常用于主设备与从设备之间的短距离通信。

UART:主要用于点对点的通信,如计算机与串口设备之间的通信,像调试串口、蓝牙模块通信等。

CAN:广泛应用于汽车电子、工业自动化等对可靠性和实时性要求较高的领域,用于多个节点之间的通信。

6 锁有哪些?有什么注意事项

常见的锁

互斥锁:用于保护共享资源,确保同一时刻只有一个线程或进程能够访问该资源,避免数据冲突和不一致。

读写锁:分为读锁和写锁,允许多个线程同时获取读锁进行读取操作,但只有一个线程能获取写锁进行写入操作,适用于读多写少的场景。

自旋锁:当线程尝试获取锁时,如果锁已被占用,它会一直循环等待,不断检查锁是否可用,直到获取到锁为止,通常用于短时间的锁操作。

条件变量锁:常与互斥锁配合使用,用于线程间的同步,允许线程在满足特定条件时才继续执行。

注意事项

死锁问题:多个线程或进程相互等待对方释放锁,导致程序无法继续执行,要合理设计锁的获取顺序和使用方式来避免。

锁粒度:锁的粒度过大可能导致并发度降低,过小则可能增加锁的开销和复杂性,需根据具体业务场景权衡。

性能开销:加锁和解锁操作会带来一定的性能开销,要避免不必要的锁使用,尽量减少锁的持有时间。

7 信号量和自旋锁的区别

信号量和自旋锁是用于实现多线程或多进程同步的机制,它们有以下区别:

实现原理

信号量:通过一个计数器来控制对资源的访问。当计数器大于 0 时,线程可以获取资源并将计数器减 1;当计数器为 0 时,线程需要等待,直到其他线程释放资源使计数器大于 0。

自旋锁:当线程尝试获取锁时,如果锁已被占用,线程会在原地循环等待,不断检查锁是否被释放,直到获取到锁为止。

适用场景

信号量:适用于资源数量有限且有多个线程或进程竞争的场景,常用于实现生产者 - 消费者模型等,能控制并发访问的数量。

自旋锁:适用于锁的持有时间非常短的场景,比如内核中的一些临界区保护,由于等待时间短,自旋锁可以避免线程切换带来的开销。

等待方式

信号量:当无法获取资源时,线程会进入阻塞状态,让出 CPU 资源,等待信号量的状态改变。

自旋锁:线程不会阻塞,而是持续占用 CPU 进行循环检测,直到获取锁,这可能会浪费 CPU 资源。

8 中断能不能睡眠,为什么?下半部能不能睡眠?

以下是关于中断和下半部能否睡眠及原因的分析:

中断

一般情况下,中断处理程序不能睡眠。因为中断是用来响应外部事件或紧急情况的,具有较高的优先级和及时性要求。如果中断处理程序睡眠,可能会导致其他重要的中断无法及时响应,使系统的实时性和稳定性受到严重影响,甚至可能引发系统崩溃等问题。例如在实时控制系统中,若中断处理程序睡眠,可能无法及时处理传感器传来的关键数据,导致控制出现偏差。

下半部

下半部通常可以睡眠。下半部机制的引入就是为了将中断处理中一些可以延迟执行的工作分离出来,在更合适的时机执行,以减少中断处理的时间。它可以睡眠是因为它本身就是设计用于在相对宽松的时间内完成任务,不会像中断处理那样对及时性有严格要求。比如,在网络数据接收中,将数据的后续处理等工作放在下半部进行,当下半部执行时,如果需要等待某些资源或进行一些耗时操作,是可以睡眠等待的,这样不会影响系统对其他紧急事件的处理。

9 死锁产生的原因和四个必要条件

死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。以下是死锁产生的原因和四个必要条件:

产生原因

资源竞争:系统中存在多个进程共享有限的资源,当多个进程同时请求使用这些资源时,如果资源分配不当,就可能导致死锁。例如,多个进程竞争打印机、内存等资源。

进程推进顺序不当:进程在运行过程中,请求和释放资源的顺序不合理,也可能导致死锁。即使资源充足,但由于进程推进顺序不合适,也可能使进程相互等待对方释放资源,从而陷入死锁状态。

四个必要条件

互斥条件:资源在某一时刻只能被一个进程所使用,即资源具有排他性。例如打印机在打印一份文件时,不能同时被另一个进程用来打印另一份文件。

请求和保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而新请求的资源又被其他进程占有,此时请求进程被阻塞,但对自己已获得的资源保持不放。

不可剥夺条件:进程所获得的资源在未使用完之前,不能被其他进程强行夺走,只能由该进程自己在使用完后主动释放。

环路等待条件:存在一个进程资源的环形链,链中的每一个进程都在等待下一个进程所占用的资源。例如,进程 P1 等待进程 P2 占用的资源,进程 P2 又等待进程 P3 占用的资源,以此类推,最后进程 Pn 等待进程 P1 占用的资源,形成一个环路。

这四个必要条件是死锁产生的充分条件,只有当这四个条件同时满足时,才会发生死锁。在解决死锁问题时,通常也是从破坏这四个必要条件入手。

10 什么是交叉编译?为什么需要交叉编译?

交叉编译的定义

交叉编译是指在一个平台上生成另一个平台可执行代码的过程。例如,在 x86 架构的 PC 上编译能在 ARM 架构的嵌入式设备上运行的程序。通常,进行交叉编译的环境称为宿主机,被编译的目标平台称为目标机。

需要交叉编译的原因

目标平台资源限制:像嵌入式系统等目标平台,往往资源有限,如内存小、处理器性能弱等,直接在目标平台上进行编译可能无法完成复杂项目的编译任务,而利用性能更强的宿主机进行交叉编译可解决此问题。

开发效率考量:在宿主机上有更完善的开发工具链和开发环境,开发人员可以更高效地进行代码编写、调试和编译等工作,然后将编译好的程序部署到目标平台上运行,能大大提高开发速度。

多平台支持需求:软件开发者为了让软件能在不同架构和操作系统的平台上运行,如同时支持 Windows、Linux、Android 等,通过交叉编译可以方便地为不同平台生成相应的可执行文件,而无需在每个平台上都搭建一套开发环境。

11 Linux设备中字符设备和块设备有什么主要区别?

在 Linux 设备中,字符设备和块设备主要有以下区别:

数据传输方式

字符设备:以字符为单位进行数据传输,数据是连续的字节流,按顺序依次处理,如键盘、鼠标等,读写操作是实时的,不存在缓冲。

块设备:以数据块(通常是 512 字节或其倍数)为单位传输数据,数据可随机访问,如硬盘、U 盘等,块设备通常会有缓存机制来提高读写效率。

访问方式

字符设备:通常采用顺序访问,程序按字节逐个读取或写入数据,不支持随机访问,读写操作简单直接。

块设备:支持随机访问,可在设备的任意位置进行读写操作,操作系统可对数据块进行重新排序和优化,以提高性能。

设备驱动与管理

字符设备:驱动程序相对简单,主要实现字符的读写和控制功能,内核通过字符设备文件进行管理。

块设备:驱动程序较为复杂,需处理数据块的缓存、调度和错误恢复等,内核使用更复杂的机制来管理块设备,如 I/O 调度器。

12 同步通信和异步通信的区别?

同步通信和异步通信是两种不同的通信方式,它们的区别主要体现在以下几个方面:

数据传输方式

同步通信:数据传输以数据块为单位,在通信过程中,发送方和接收方要保持严格的时钟同步,确保数据的准确传输,数据块之间通常没有间隙。

异步通信:以字符为单位进行数据传输,每个字符都有自己的起始位和停止位,字符之间可以有任意长度的间隙,不需要严格的时钟同步。

传输效率

同步通信:由于数据以块为单位传输且无间隙,在传输大量数据时,同步通信的效率较高,能够充分利用通信线路的带宽。

异步通信:每个字符都要附加起始位和停止位等额外信息,传输相同数量的数据时,相比同步通信会增加额外开销,传输效率相对较低。

13 内核链表为什么具有通用性?

内核链表具有通用性,主要原因如下:

数据类型无关:内核链表通过定义通用的结构体和操作函数,不依赖于具体的数据类型,可存储和操作各种不同类型的数据结构,只要将其与链表节点关联即可。

可扩展性强:其节点结构简单,只有指向前驱和后继节点的指针成员,用户能方便地根据自身需求在节点结构体中添加其他成员,扩展功能以适应各种复杂应用场景。

操作函数通用:内核提供了一套标准的链表操作函数,如插入、删除、遍历等,这些函数适用于各种链表,无论链表中存储的数据内容和用途如何,都能使用这些通用函数进行操作。

14 分配内存有哪些函数?有什么区别?

Linux 内核

kmalloc:用于分配物理上连续的内存,适合需要物理连续内存的场景,如 DMA 操作。分配的内存保持原有数据内容。

vmalloc:分配虚拟地址连续的内存,物理地址可能不连续,适合分配大块内存。

kzalloc:功能与 kmalloc 类似,但会将分配的内存初始化为零。

15 Linux内核硬中断、软中断的原理和实现

硬中断

原理:由外部硬件设备(如键盘、网卡等)产生,用于通知 CPU 有紧急事件发生,需立即处理。CPU 接收到硬中断信号后,会暂停当前正在执行的任务,保存现场信息,然后执行相应的中断处理程序。

实现:在 Linux 内核中,每个硬件设备都有对应的中断号。当设备产生中断时,通过中断控制器将中断信号传递给 CPU。CPU 根据中断号找到对应的中断处理程序入口,执行中断处理函数。中断处理程序通常要快速完成关键操作,以减少对系统的影响。

软中断

原理:是为了处理一些可以稍后执行的、相对不紧急的中断处理任务而设计的。它可以在 CPU 空闲时或在特定的时机执行,以提高系统的并发处理能力和响应效率。

实现:软中断通过软件方式触发,有自己的处理机制。内核定义了一系列软中断类型,如网络接收软中断、网络发送软中断等。每个软中断都有对应的处理函数,通过软中断向量表来管理。当需要触发软中断时,设置相应的软中断标志位,在合适的时机(如内核处理完硬中断后),内核会检查软中断标志位,执行相应的软中断处理函数。

#嵌入式#

该专栏面向嵌入式开发工程师,包括C语言、C++,操作系统,ARM架构、RTOS、Linux基础、Linux驱动、Linux系统移植、计算机网络、数据结构与算法、5篇面试题目、HR面试常见问题汇总和嵌入式面试简历模板等18篇文章。超全的嵌入式软件工程师笔试面试题目和高频知识点总结!招聘so easy。

全部评论
如果大家觉得可以帮助到自己,麻烦点赞、评论和订阅哦😀
1 回复 分享
发布于 昨天 21:13 安徽
点赞 回复 分享
发布于 今天 10:28 江苏
点赞 回复 分享
发布于 今天 11:37 江苏

相关推荐

评论
4
7
分享

创作者周榜

更多
正在热议
更多
牛客网
牛客企业服务