【粉丝问答13】11道嵌入式笔试题,看下你会几道?

一口Linux 2021-02-25 00:00

笔试题

笔试题

1. ARM指令和中B和BLX的区别?

B:

跳转执行 B 指令的格式为:

B{条件} 目标地址

B 指令是最简单的跳转指令。一旦遇到一个B 指令,ARM 处理器将立即跳转到给定的目标地址,从那里继续执行。

注意存储在跳转指令中的实际值是相对当前PC 值的一个偏移量,而不是一个绝对地址,它的值由汇编器来计算(参考寻址方式中的相对寻址)。

它是 24 位有符号数,左移两位后有符号扩展为 32 位,表示的有效偏移为 26 位(前后32MB 的地址空间)。

举例:

B Label ;   程序无条件跳转到标号 Label 处执行
CMP R1 ,# 0 ;  当 CPSR 寄存器中的 Z 条件码置位时,程序跳转到标号 Label 处执行
BEQ Label

BLX

带链接和状态切换的跳转。结合了BX与BL功能。BLX 指令的格式为:

BLX 目标地址

BLX 指令从ARM 指令集跳转到指令中所指定的目标地址,并将处理器的工作状态由ARM 状态切换到Thumb 状态,该指令同时将PC 的当前内容保存到寄存器R14 中。

因此,当子程序使用Thumb 指令集,而调用者使用ARM 指令集时,可以通过BLX 指令实现子程序的调用和处理器工作状态的切换。

总结

1、BL 和 BLX 指令可将下一个指令的地址复制到lr(r14,链接寄存器)中。2、BX 和 BLX 指令可将处理器的状态从 ARM 更改为 Thumb,或从 Thumb 更改为ARM。3、BLX label 无论何种情况,始终会更改处理器的状态。4、BX Rm 和 BLX Rm 可从 Rm 的位 [0]推算出目标状态。5、如果 Rm 的位 [0] 为 0,则处理器的状态会更改为(或保持在)ARM 状态。如果 Rm 的位 [0] 为 1,则处理器的状态会更改为(或保持在)Thumb 状态。

2. ARM处理器体系结构中IRQ发生时,处理器将执行哪些操作?

中断发生后,ARM核的操作步骤可以总结为4大步3小步。

1. 4大步3小步

  1. 保存执行状态:将CPSR复制到发生的异常模式下SPSR中;
  2. 模式切换:
  • CPSR模式位强制设置为与异常类型相对应的值,
  • 处理器进入到ARM执行模式,
  • 禁止所有IRQ中断,当进入FIQ快速中断模式时禁止FIQ中断;
  1. 保存返回地址:将下一条指令的地址(被打断程序)保存在LR(异常模式下LR_excep)中。
  2. 跳入异常向量表:强制设置PC的值为相应异常向量地址,跳转到异常处理程序中。

2. 步骤详解

  1. 保存执行状态

当前程序的执行状态是保存在CPSR里面的,异常发生时,要保存当前的CPSR里的执行状态到异常模式里的SPSR里,将来异常返回时,恢复回CPSR,恢复执行状态。

  1. 模式切换

硬件自动根据当前的异常类型,将异常码写入CPSR里的M[4:0]模式位,这样CPU就进入了对应异常模式下。不管是在ARM状态下还是在THUMB状态下发生异常,都会自动切换到ARM状态下进行异常的处理,这是由硬件自动完成的,将CPSR[5] 设置为 0。同时,CPU会关闭中断IRQ(设置CPSR 寄存器I位),防止中断进入,如果当前是快速中断FIQ异常,关闭快速中断(设置CPSR寄存器F位)。

  1. 保存返回地址

当前程序被异常打断,切换到异常处理程序里,异常处理完之后,返回当前被打断模式继续执行,因此必须要保存当前执行指令的下一条指令的地址到LR_excep(异常模式下LR,并不存在LR_excep寄存器,为方便读者理解加上_excep,以下道理相同),由于异常模式不同以及ARM内核采用流水线技术,异常处理程序里要根据异常模式计算返回地址。

  1. 跳入异常向量表

该操作是CPU硬件自动完成的,当异常发生时,CPU强制将PC的值修改为一个固定内存地址,这个固定地址叫做异常向量。

3. ARM状态与Thumb状态的切换指令是什么?举例说明

概念

  1. ARM状态 arm处理器工作于32位指令的状态,所有指令均为32位
  2. thumb状态 arm执行16位指令的状态,即16位状态

切换指令

  1. 由arm状态切换到thumb 状态将寄存器的最低位设置为1

BX指令:R0[0]=1,则执行BX R0指令将进入thumb状态

  1. 由thumb状态切换到ARM状态 寄存器最低位设置为0

BX指令:R0[0]=0,则执行BX R0指令将进入arm状态

举例

 AREA Arm_to_Thumb,CODE, READONLY
 ENTRY
 CODE32
start
 ldr r0,=aaa+1
 mov r3,#18
 bx r0
 CODE16
aaa 
 mov r1,#12
 mov r2,#10
 END

4. 请问ARM支持哪几种异常类型,请列出其中断向量地址。

异常源分类

要进入异常模式,一定要有异常源,ARM规定有7种异常源:

异常源 描述
Reset 上电时执行
Undef 当流水线中的某个非法指令到达执行状态时执行
SWI 当一个软中断指令被执行完的时候执行
Prefetch 当一个指令被从内存中预取时,由于某种原因而失败,如果它能到达执行状态这个异常才会产生
Data 如果一个预取指令试图存取一个非法的内存单元,这时异常产生
IRQ 通常的中断
FIQ 快速中断

异常向量表是一段特定内存地址空间,每种ARM异常对应一个字长空间(4Bytes),正好是一条32位指令长度,当异常发生时,CPU强制将PC的值设置为当前异常对应的固定内存地址。

异常向量表:

异常向量表

跳入异常向量表操作是异常发生时,硬件自动完成的,剩下的异常处理任务完全交给了程序员。由上表可知,异常向量是一个固定的内存地址,我们可以通过向该地址处写一条跳转指令,让它跳向我们自己定义的异常处理程序的入口,就可以完成异常处理了。

正是由于异常向量表的存在,才让硬件异常处理和程序员自定义处理程序有机联系起来。异常向量表里0x00000000地址处是reset复位异常,之所以它为0地址,是因为CPU在上电时自动从0地址处加载指令,由此可见将复位异常安装在此地址处也是前后结合起来设计的,不得不感叹CPU设计师的伟大,其后面分别是其余7种异常向量,每种异常向量都占有四个字节,正好是一条指令的大小,最后一个异常是快速中断异常,将其安装在此也有它的意义,在0x0000001C地址处可以直接存放快速中断的处理程序,不用设置跳转指令,这样可以节省一个时钟周期,加快快速中断处理时间。

存储器映射地址0x00000000是为向量表保留的。在有些处理器中,向量表可以选择定位在高地址0xFFFF0000处【可以通过协处理器指令配置】,当今操作系统为了控制内存访问权限,通常会开启虚拟内存,开启了虚拟内存之后,内存的开始空间通常为内核进程空间,和页表空间,异常向量表不能再安装在0地址处了。

比如Cortex-A8系统中支持通过设置CP15的C12寄存器将异常向量表的首地址放置在任意地址。

5. 在Linux中与外设的通信是层次化的,请画出外设寻址的分层模型。

本题有点没整明白在问什么,如果分析有误,欢迎给我留言。

Linux下一切皆文件,应用程序访问外设都需要通过驱动来操作外设。

Linux下设备类型分为:字符设备、块设备、网络设备。

架构图参考下图:

此外题目问画出外设寻址的分层模型,我想可能是想问如何访问SDRAM。

如下图所示,CPU要访问SDRAM或者flash需要先通过AHB总线,然后再通过外存接口控制器对外存寻址,然后进行数据的读写。

访问外存

6. 中断是嵌入式中重要的组成部分,中断服务程序通常需要满足哪些要求?

中断是嵌入式系统中重要的组成部分,很多外设和cpu的交互都是通过中断的方式进行。衡量一个OS的实时性很重要的一个特性就是中断的响应时间,长时间处于中断状态所以中断反应。一旦进入中断状态,cpu是在占用的,所以必须快速的出中断,否则会影响整体性能。

中断服务程序需要满足如下要求:

  1. 不能返回值;
  2. 不能向ISR传递参数;
  3. ISR应该尽可能的短小精悍;
  4. 要尽快出中断;
  5. 耗时的中断要放到中断的底半部;
  6. 中断不要调用会因其休眠的函数;
  7. 通常中断中不做浮点操作;
  8. 中断函数中不可调用不可重入的函数,会引起意想不到的问题。

7. 使用共享资源时,为了使之满足互斥条件,通常有哪些方法?

共享资源也叫临界资源,在进程和线程、内核下都有自己的同步互斥机制, 仅考虑互斥的话,分开来看:

进程:信号量(值设置为1) 线程:互斥体、信号量(也叫信号灯) 内核:原子操作,自旋锁,信号量,互斥锁

8. 嵌入式操作系统有哪些同步通信服务?

Linux进程间通信方式主要有

  1. 信号
  2. 信号量
  3. 管道
  4. 消息队列
  5. 共享内存
  6. 套接字(本地的还有域套接字)

9. 请举例说明什么是可重入函数与不可重入函数。

1. 不可重入函数

在实时系统的设计中,经常会出现多个任务调用同一个函数的情况。如果有一个函数不幸被设计成为不可重入这样:那么不同任务调用这个函数时可能修改其他任务调用这个函数的数据,从而导致不可预料的后果。这样的函数是不安全的函数,也叫不可重入函数。

满足下列条件的函数多数是不可重入的

  1. 函数体内使用了静态的数据结构;
  2. 函数体内调用了malloc()或者free()函数(malloc和free为不可重入函数);
  3. 函数体内调用了标准I/O函数。

2. 可重入函数

可重入函数可以被一个以上的任务调用,而不必担心数据被破坏。可重入函数任何时候都可以被中断,一段时间以后又可以运行,而相应的数据不会丢失。可重入函数或者只使用局部变量,即保存在CPU寄存器中或堆栈中;或者使用全局变量,则要对全局变量予以保护

如何写出可重入函数在函数体内不访问那些全局变量,不使用静态局部变量,坚持只使用缺省态(auto)局部变量,写出的函数就将是可重入的。如果必须访问全局变量,记住利用互斥信号量来保护全局变量。或者调用该函数前关中断,调用后再开中断。Linux常见的可重入函数

3. 举例

A) 可重入函数

void strcpy(char * dest, char * src) {
 while(*dest++=*src++);
 *dest = 0;
}

B) 不可重入函数1

char temp;//全局变量
void swapchar(char * x, char * y) {
 temp = *x;
 *x=*y;
 *y=temp;//访问了全局变量
}

C) 不可重入函数2

void swapchar(char * x, char * y) {
 char temp;//局部变量
 temp = *x;
 *x=*y;
 *y=temp;//使用了全局变量
}

4. 不可重入函数的使用注意事项

int Exam = 0;  
unsigned int exampleint para )   
{   
    unsigned int temp;  
    Exam = para; // (**)  
    temp = Square_Exam( );  
    return temp;  

Exam 是 int 型全局变量,函数 Squre_Exam() 返回 Exam 平方值,所以函数example()不具有可重入性。 

此函数若被多个进程调用的话,其结果可能是未知的,因为当 Exam = para语句刚执行完后,另外一个使用本函数的进程可能正好被激活,那么当新激活的进程执行到此函数时,将使 Exam 赋与另一个不同的 para 值,所以当控制重新回到 “temp = Square_Exam( )” 后,计算出的temp很可能不是预想中的结果。

此函数应如下改进:

int Exam = 0;  
unsigned int exampleint para )   
{  
    unsigned int temp;  
    [申请信号量操作] //(1)  加锁  
    Exam = para;  
    temp = Square_Exam( );  
    [释放信号量操作] //     解锁   
    return temp;  

申请不到“信号量”,说明另外的进程正处于给 Exam 赋值并计算其平方过程中(即正在使用此信号),本进程必须等待其释放信号后,才可继续执行。

若申请到信号,则可继续执行,但其它进程必须等待本进程释放信号量后,才能再使用本信号。

5. 可重入函数

可重入函数

10. int *fun(void)与int (*fun)(void)区别?

int *fun(void) fun是一个函数名,该函数的参数是void型,返回值是 int *

int (*fun)(void) fun是一个函数指针,该指针用于指向一个函数,函数的参数是void型,返回值是 int 即类型如下:

int function(void)
{
 return 0;
}

11. 32位系统上有如下C程序:

struct person
{

 int a;
 unsigned short int m;
 char b;
 char *q;
 char c;
};
char str[]="yikoulinux";
char *p = str;
int n = 10;

则sizeof(str)、sizeof(p)、sizeof(n)、sizeof(int)、sizeof(struct person)的值分别是:

编写测试程序

  1 #include <stdio.h>
  2 
  3 int main(int argc, const char *argv[])
  4 
{
  5     struct person
  6     {

  7         int a;
  8         unsigned short int m;
  9         char b;
 10         char *q;
 11         char c;
 12     };
 13     char str[]="yikoulinux";
 14     char *p = str;
 15     int n = 10;
 16 
 17     struct person pe;
 18 
 19     printf("sizeof(str):%d sizeof(p):%d sizeof(n):%d sizeof(int):%d sizeof(struct person):%d\n",si
 20 
 21     printf("%p\n %p\n %p\n %p \n %p \n",
 22             &pe.a,&pe.m,&pe.b,&pe.q,&pe.c);
 23     return 0;
 24 }

编译执行:

sizeof(str):11 sizeof(p):4 sizeof(n):4 sizeof(int):4 sizeof(struct person):16
 0xbf917d18
 0xbf917d1c
 0xbf917d1e
 0xbf917d20 
 0xbf917d24 

解释:

类型 解释
sizeof(str) 11 这是计算数组str的大小,因为没有设置数组大小,以赋值字符串大小为准,而常量字符串在后一个位置会补一个空字符'\0',所以一共11个字节
sizeof(p) 4 p是一个指针,32位机的指针都是32位,4个字节
sizeof(n) 4 n是一个整型变量,所以是4个字节
sizeof(int) 4 计算int 类型占用的内存大小,是4个字节
sizeof(struct person) 16 默认情况下结构体成员会字节对齐,详细分布见下图
 
------------ END ------------


推荐阅读


【1】C语言实现MD5加密,竟如此简单!必读
【2】【粉丝问答11】如何在内网搭建TCP服务器并能被外网直接访问 必读
【3】手把手教Linux驱动10-platform总线详解必读
【4】基于Linux的tty架构及UART驱动详解必读
【5】 你好,李焕英 必读
【6】1万字30张图说清TCP协议 必读
【7】 一键获取linux内存、cpu、磁盘IO等信息脚本编写,及其原理详解 必读
【8】 自己DIY一个mp3播放器
【9】 从Linux源码看Socket(TCP)的bind
【10】 【粉丝问答12】如何计算函数的执行时间? 必读

 


 

进群,请加一口君个人微信,带你嵌入式入门进阶。


在公众号内回复「1024」,即可免费获取学习资料,期待你的关注~


一口Linux 写点代码,写点人生!
评论
  • 一、SAE J1939协议概述SAE J1939协议是由美国汽车工程师协会(SAE,Society of Automotive Engineers)定义的一种用于重型车辆和工业设备中的通信协议,主要应用于车辆和设备之间的实时数据交换。J1939基于CAN(Controller Area Network)总线技术,使用29bit的扩展标识符和扩展数据帧,CAN通信速率为250Kbps,用于车载电子控制单元(ECU)之间的通信和控制。小北同学在之前也对J1939协议做过扫盲科普【科普系列】SAE J
    北汇信息 2024-12-11 15:45 108浏览
  • 天问Block和Mixly是两个不同的编程工具,分别在单片机开发和教育编程领域有各自的应用。以下是对它们的详细比较: 基本定义 天问Block:天问Block是一个基于区块链技术的数字身份验证和数据交换平台。它的目标是为用户提供一个安全、去中心化、可信任的数字身份验证和数据交换解决方案。 Mixly:Mixly是一款由北京师范大学教育学部创客教育实验室开发的图形化编程软件,旨在为初学者提供一个易于学习和使用的Arduino编程环境。 主要功能 天问Block:支持STC全系列8位单片机,32位
    丙丁先生 2024-12-11 13:15 61浏览
  • RK3506 是瑞芯微推出的MPU产品,芯片制程为22nm,定位于轻量级、低成本解决方案。该MPU具有低功耗、外设接口丰富、实时性高的特点,适合用多种工商业场景。本文将基于RK3506的设计特点,为大家分析其应用场景。RK3506核心板主要分为三个型号,各型号间的区别如下图:​图 1  RK3506核心板处理器型号场景1:显示HMIRK3506核心板显示接口支持RGB、MIPI、QSPI输出,且支持2D图形加速,轻松运行QT、LVGL等GUI,最快3S内开
    万象奥科 2024-12-11 15:42 83浏览
  • 时源芯微——RE超标整机定位与解决详细流程一、 初步测量与问题确认使用专业的电磁辐射测量设备,对整机的辐射发射进行精确测量。确认是否存在RE超标问题,并记录超标频段和幅度。二、电缆检查与处理若存在信号电缆:步骤一:拔掉所有信号电缆,仅保留电源线,再次测量整机的辐射发射。若测量合格:判定问题出在信号电缆上,可能是电缆的共模电流导致。逐一连接信号电缆,每次连接后测量,定位具体哪根电缆或接口导致超标。对问题电缆进行处理,如加共模扼流圈、滤波器,或优化电缆布局和屏蔽。重新连接所有电缆,再次测量
    时源芯微 2024-12-11 17:11 106浏览
  • 习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习笔记&记录学习习笔记&记学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记
    youyeye 2024-12-11 17:58 80浏览
  • 首先在gitee上打个广告:ad5d2f3b647444a88b6f7f9555fd681f.mp4 · 丙丁先生/香河英茂工作室中国 - Gitee.com丙丁先生 (mr-bingding) - Gitee.com2024年对我来说是充满挑战和机遇的一年。在这一年里,我不仅进行了多个开发板的测评,还尝试了多种不同的项目和技术。今天,我想分享一下这一年的故事,希望能给大家带来一些启发和乐趣。 年初的时候,我开始对各种开发板进行测评。从STM32WBA55CG到瑞萨、平头哥和平海的开发板,我都
    丙丁先生 2024-12-11 20:14 66浏览
  • 全球知名半导体制造商ROHM Co., Ltd.(以下简称“罗姆”)宣布与Taiwan Semiconductor Manufacturing Company Limited(以下简称“台积公司”)就车载氮化镓功率器件的开发和量产事宜建立战略合作伙伴关系。通过该合作关系,双方将致力于将罗姆的氮化镓器件开发技术与台积公司业界先进的GaN-on-Silicon工艺技术优势结合起来,满足市场对高耐压和高频特性优异的功率元器件日益增长的需求。氮化镓功率器件目前主要被用于AC适配器和服务器电源等消费电子和
    电子资讯报 2024-12-10 17:09 98浏览
  • 铁氧体芯片是一种基于铁氧体磁性材料制成的芯片,在通信、传感器、储能等领域有着广泛的应用。铁氧体磁性材料能够通过外加磁场调控其导电性质和反射性质,因此在信号处理和传感器技术方面有着独特的优势。以下是对半导体划片机在铁氧体划切领域应用的详细阐述: 一、半导体划片机的工作原理与特点半导体划片机是一种使用刀片或通过激光等方式高精度切割被加工物的装置,是半导体后道封测中晶圆切割和WLP切割环节的关键设备。它结合了水气电、空气静压高速主轴、精密机械传动、传感器及自动化控制等先进技术,具有高精度、高
    博捷芯划片机 2024-12-12 09:16 77浏览
  • 在智能化技术快速发展当下,图像数据的采集与处理逐渐成为自动驾驶、工业等领域的一项关键技术。高质量的图像数据采集与算法集成测试都是确保系统性能和可靠性的关键。随着技术的不断进步,对于图像数据的采集、处理和分析的需求日益增长,这不仅要求我们拥有高性能的相机硬件,还要求我们能够高效地集成和测试各种算法。我们探索了一种多源相机数据采集与算法集成测试方案,能够满足不同应用场景下对图像采集和算法测试的多样化需求,确保数据的准确性和算法的有效性。一、相机组成相机一般由镜头(Lens),图像传感器(Image
    康谋 2024-12-12 09:45 69浏览
  • 近日,搭载紫光展锐W517芯片平台的INMO GO2由影目科技正式推出。作为全球首款专为商务场景设计的智能翻译眼镜,INMO GO2 以“快、准、稳”三大核心优势,突破传统翻译产品局限,为全球商务人士带来高效、自然、稳定的跨语言交流体验。 INMO GO2内置的W517芯片,是紫光展锐4G旗舰级智能穿戴平台,采用四核处理器,具有高性能、低功耗的优势,内置超微高集成技术,采用先进工艺,计算能力相比同档位竞品提升4倍,强大的性能提供更加多样化的应用场景。【视频见P盘链接】 依托“
    紫光展锐 2024-12-11 11:50 66浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦