物联网嵌入式系统练习题1.docx
《物联网嵌入式系统练习题1.docx》由会员分享,可在线阅读,更多相关《物联网嵌入式系统练习题1.docx(18页珍藏版)》请在冰点文库上搜索。
物联网嵌入式系统练习题1
一、单项选择题
1.PXA270处理器是多少位的嵌入式处理器()。
A.8位B.16位C.32位D.64位
2.ARM处理器属于下列哪种嵌入式处理器()。
A.MCUB.EMPUC.DSPD.SOPC
3.下列几种ARM工作模式中属于正常模式的是()。
A.系统模式B.数据中止模式
C.未定义模式D.快速终端模式模式
4.下列几种ARM异常中优先级最高的是()。
A.外部中断(IRQ)B.数据中止
C.预取指令中止D.未定义指令
5.ARM汇编语句“STMIAR0,{R3-R10}”的作用是()。
A.R0开始的连续8个字数据分别加载到R3-R10
B.R0地址指向的1个字数据分别重复加载到R3-R10
C.R0开始的连续8个字节数据分别加载到R3-R10
D.R3-R10中的8个字数据存储到R0开始的连续存储单元
6.寄存器R14除了可以做通用寄存器外,还可以做()。
A.程序计数器B.链接寄存器
C.栈指针寄存器D.基址寄存器
7.下列不是ARM伪指令可定义的变量的是()。
A.数值型变量B.逻辑型变量
C.布尔型变量D.字符型变量
8.嵌入式系统Bootloader的stage1引导启动时在哪个存储器件中运行()。
A.硬盘B.RAMC.ROMD.存储卡
9.下列进行内核配置的命令中使用已有配置文件.config进行配置的是()。
A.makeconfigB.makemenuconfig
C.makeoldconfigD.makexconfig
10.下列嵌入式文件系统中仅适用于NAND型Flash的是()。
A.jffs2B.yaffsC.cramfsD.NFS
11.Linux内核提供了内核与用户空间传递数据的专用函数,其中用于实现用户系统调用write的是()。
A.copy_to_user(void*from,void*to,intn)
B.copy_to_user(void*to,void*from,intn)
C.copy_from_user(void*from,void*to,intn)
D.copy_from_user(void*to,void*from,intn)
12.以下关于设备号的说法不正确的是()。
A.设备号有主设备号和从设备号
B.主设备号说明设备的属性,比如字符设备或块设备,从设备号说明设备类型。
C.可用MINOR从设备号中分理处从设备号。
D.设备号的申请可以静态申请,也可以动态申请,静态申请是申请指定的设备号。
13.ARM处理器的Thumb工作状态是()。
A.16位字对齐B.32位字对齐
C.16位半字对齐D.16位字节对齐
14.若R1=2000H,(2000H)=0x86,(2008H)=0x39,则执行LDRR0,[R1]!
,#8后R0的值为()。
A.0x2000B.0x86C.0x2008D.0x39
15.寄存器R15除了可以做通用寄存器外,还可以做()。
A.程序计数器B.链接寄存器
C.栈指针寄存器D.基址寄存器
16.ARM汇编语句“ADDR0,R2,R3,LSL#1”的作用是()。
A.R0=R2+(R3<<1)B.R0=(R2<<1)+R3
C.R3=R0+(R2<<1)D.(R3<<1)=R0+R2
17.下列不是ARM伪指令可定义的变量的是()。
A.数值型变量B.逻辑型变量
C.字符串变量D.字符型变量
18.通常所说的移植嵌入式Linux系统的过程不包括()。
A.移植BootloaderB.编写驱动程序
C.加载文件系统D.下载内核映像
19.编译配置Linux内核时进入基于图形窗口界面使用的命令是()。
A.MakeconfigB.Makemenuconfig
C.MakexconfigD.Makeoldconfig
20.Linux内核启动函数是()。
A.call_kernel()B.setup_arch()C.start_kernel()D.init()
21.下列内核打印函数printk的日志级别最高的是()。
A.KERN_EMERGB.KERN_ALERT
C.KERN_CRITD.KERN_WARNING
三、填空题
1.常见的嵌入式系统架构有ARM、(MIPS)、(PowerPC)和(DSP)。
(任意写出三个即可)
2.常见的嵌入式操作系统有Linux、()、()和()。
(任意写出三个即可)
3.ARM处理器共有()个寄存器,其中()个通用寄存器,()个状态寄存器。
4.ARM寄存器中()可用作堆栈指针SP,()用作子程序链接寄存器LR,(R15)可用作程序指针寄存器PC。
5.ARM的工作模式由CPSR的()位来表明。
工作状态由该寄存器的()位来表明,标志位由该寄存器的()位来说明。
6.ARM处理器有()种工作模式,其中()和()是正常工作模式。
7.交叉开发中程序的编译是在(),而程序的运行是在()。
8.Bootloader存储的起始地址一般为(),它一般分为两个阶段,其中()主要用汇编代码编写,它负责为加载()准备RAM空间。
9.Bootloader存储的起始地址一般为(),它一般分为两个阶段,其中(stage2)主要用C语言编写,它负责为加载()准备RAM空间。
10.内核配置时将某项配置编译进内核则在该项上输入(),如果编译成模块则输入()。
11.编译开发板的Linux内核时,应先在顶层的Makefile中设置ARCH=(),CROSS_COMPILE=()。
12.配置Busybox时选择()则将编译静态库,在()选项中输入busybox编译后的安装路径,安装busybox的命令是()。
13.Linux文件系统中,用户目录通常是(/home),外围设备挂载点的目录是(/mnt)。
14.Linux文件系统中,存放设备文件的目录是(/dev)存放操作系统启动时所用到的程序的目录是(/boot)。
15.可使用宏()将主设备号从设备号中分离,使用宏()将主次设备号合并。
16.申请设备号可以动态申请也可以静态申请,静态申请使用函数(register_chrdev_region),动态申请使用函数(alloc_chrdev_region)。
17.Linux驱动程序可用()函数动态分配设备号,用()命令创建设备文件。
18.字符设备文件和普通文件的区别在于字符设备在文件读写时只能()。
四、简答题
1.解释下列指令完成的功能及其产生的结果。
(1)LSL;
(2)LDMIA;(3)TEQ;(4)ADC;(5)BXL;
(6)GBLA;(7)ENTRY;(8)DCW;(9)IMPORT;(10)GET。
(11)ASR;(12)LDMFD;(13)TST;(14)ADCS;(15)BL;
(16)LCLA;(17)ENTRY;(18)EQU;(19)EXTERN;(20)GET
(21)LSR;(22)LDMIB;(23)TST;(24)ADDS;(25)BLX;
(26)GBLS;(27)ENTRY;(28)DCB;(29)CMP;(30)GET
2.简述哈佛结构与冯诺依曼结构的区别。
答:
冯诺依曼体系结构是将程序指令存储器和数据存储器合并在一起的存储器结构,提取指令和数据是通过一个单一的内部数据总线进行的。
哈佛体系结构是将程序指令存储和数据存储分开的存储器结构,它有两个或者更多的数据总线,这就允许同时访问指令和数据。
3.简述CPSR寄存器条件码标志位的意义。
答:
CPSR的高4位伪条件码标志位,由高到低依次为N、Z、C、V。
(1分)其中N=0表示运算结果位正,N=0表示结果为负;Z=1表示结果为0,Z=0表示结果为非0;C=1表示有进位或借位;V=1表示有溢出。
4.简述UBoot移植的基本步骤。
答:
UBoot移植的步骤如下:
(1)在UBoot代码的顶层Makefile中为开发板添加新的配置选项;
(2)在board目录中创建一个属于新开发板的目录;(3)为开发板添加新的配置文件;(4)选择板级配置;(5)执行makeCROSS_COMPILE=arm-linux-命令,编译UBoot;(6)烧写UBoot到开发板。
5.简述Bootloader的两种工作模式。
答:
大多数Bootloader都包含两种不同的工作模式,即“启动模式”和“下载模式”。
启动模式中,Bootloader从目标机的某个固态存储设备上将操作系统加载到RAM中运行,整个过程中并没有用户介入,这种模式是Bootloader的正常工作模式,因此在嵌入式产品发布时,Bootloader必须工作在这种模式下;在下载模式下,目标机上的Bootloader通过串口或网络等通信手段从主机下载文件,然后控制启动流程,主要用于开发人员调试系统。
6.简述内核配置与编译的基本步骤。
答:
内核配置与编译的步骤:
(1)拿到内核代码后,首先要清楚中间文件、临时文件和配置文件,方法是输入makedistclean;
(2)确定软硬件配置和型号情况,需要参考硬件手册;(3)输入makemenuconfig进入配置内核界面对内核进行配置,参考软硬件平台的选型;(4)配置好内核后保存,之后进行编译,输入makebzImage;(5)上一步编译出的内核映像文件下载到嵌入式开发板。
7.简述进入配置内核选项的四种命令及其区别。
答:
配置内核有四种命令,即makeconfig,makemenuconfig,makexconfig和makeoldconfig。
其中makeconfig进入基于字符的内核配置界面;makemenuconfig进入基于菜单的内核配置界面;makexconfig进入基于图形界面的内核配置界面;mekeoldconfig使用已有的.config文件作为内核配置的选项。
8.说明汇编程序伪指令的作用及其与指令的区别。
答:
伪指令是用于告诉汇编程序如何进行汇编的指令。
它既不控制机器的操作也不被汇编成机器代码,只能为汇编程序所识别并指导汇编如何进行。
指令是在执行阶段发挥作用的,由CPU(Intel、AMD等)来执行。
伪指令是在编译阶段发挥作用的,由汇编器(MASM、TASM等)来解释。
9.说明ARM汇编伪操作的类型。
答:
伪操作的类型包括:
符号定义伪操作,数据定义伪操作,汇编控制伪操作,数据帧描述伪操作,信息报告伪操作以及其他杂项伪操作。
10.简述满递减堆栈、空递增堆栈的意义。
11.简述XScale架构相对StrongARM处理器的优势。
12.简要说明嵌入式处理器的种类及其典型处理器。
五、程序题(每小题10分,共20分)
1.已知有8个32位无符号随机数6,3,12,7,5,0,20,8存储在数据段src为起始地址的连续32个字节的存储单元中,编写汇编程序求这8个数的平均值,放到寄存器R1中。
要求写出完整的ARM汇编程序代码。
2.已知内存数据段src1开始的内存地址处有字符串“Hello”,src2开始的内存地址处有字符串“World!
”,编写程序将它们依次复制到数据段dst开始的内存地址处,并拼接为“HelloWorld!
”。
要求写出完整的ARM汇编程序代码。
3.已知有10个随机数6,3,12,7,5,0,20,8存储在数据段src为起始地址的连续40个字节的存储单元中。
编写汇编程序将这10个数按由大到小的顺序排序。
4.有下面一段驱动程序代码,根据注释填写空白处补全代码。
并按题号顺序填写。
#defineMEMDEV_SIZE4096/*设备文件大小为MEMDEV_SIZE字节*/
staticmem_major=254;/*要申请的设备号为254*/
structmem_dev*mem_devp;/*设备结构体指针*/
structcdevcdev;
intmem_open(structinode*inode,structfile*filp)/*文件打开函数*/
{……}
intmem_release(structinode*inode,structfile*filp)/*文件释放函数*/
{return0;}
staticssize_tmem_read(structfile*filp,char__user*buf,size_tsize,loff_t*ppos)/*读函数*/
{unsignedlongp=*ppos;/*文件读写位置指针*/
unsignedintcount=size;/*读取数据大小*/
intret=0;
structmem_dev*dev=filp->private_data;/*获得设备结构体指针*/
……/*判断读位置是否有效*/
if((7))/*读数据到用户空间*/
{ret=-EFAULT;}
else
{*ppos+=count;
ret=count;
printk(KERN_INFO"read%dbytes(s)from%d\n",count,p);}
returnret;}
/*写函数*/
staticssize_tmem_write(structfile*filp,constchar__user*buf,size_tsize,loff_t*ppos){unsignedlongp=*ppos;/*文件读写位置指针*/
unsignedintcount=size;/*写入数据大小*/
structmem_dev*dev=filp->private_data;/*获得设备结构体指针*/
……/*判断写位置是否有效*/
if(copy_from_user(dev->data+p,buf,count))/*从用户空间写入数据*/
ret=-EFAULT;
else{……}}
staticloff_tmem_llseek(structfile*filp,loff_toffset,intwhence)/*seek文件定位函数*/
{loff_tnewpos;
switch(whence){
case0:
newpos=offset;/*SEEK_SET*/
break;
case1:
newpos=(8);/*SEEK_CUR*/
break;
case2:
newpos=(9);/*SEEK_END*/
break;
default:
/*can'thappen*/
return-EINVAL;}
filp->f_pos=newpos;
returnnewpos;}
staticconststructfile_operationsmem_fops=/*文件操作结构体*/
{.owner=THIS_MODULE,
.llseek=(5),
.read=(6),
.write=mem_write,
.open=mem_open,
.release=mem_release,};
staticintmemdev_init(void)/*设备驱动模块加载函数*/
{intresult;
inti;
dev_tdevno=MKDEV(mem_major,0);
if(mem_major)
result=
(1);/*静态申请设备号*/
else{result=
(2);/*动态分配设备号*/
mem_major=MAJOR(devno);}
if(result<0)
returnresult;
(3);/*初始化cdev结构*/
cdev.owner=THIS_MODULE;
cdev.ops=&mem_fops;
(4);/*从次设备号为0开始注册两个字符设备*/
……}
staticvoidmemdev_exit(void)/*模块卸载函数*/
{……}
MODULE_LICENSE("GPL");
module_init(memdev_init);
module_exit((10));
5.有如下某驱动程序,试编写其驱动程序测试用例,要求打开设备文件,写入字符串“HelloWorld!
”,之后读出数据并打印输出,看读出数据是否与写入的一致,最后关闭文件。
(注:
设备文件路径和文件名为"/dev/memdev0")。
驱动代码:
#defineMEMDEV_SIZE4096/*设备文件大小为MEMDEV_SIZE字节*/
staticmem_major=254;/*要申请的设备号为254*/
structmem_dev*mem_devp;/*设备结构体指针*/
structcdevcdev;
intmem_open(structinode*inode,structfile*filp)/*文件打开函数*/
{……}
intmem_release(structinode*inode,structfile*filp)/*文件释放函数*/
{return0;}
staticssize_tmem_read(structfile*filp,char__user*buf,size_tsize,loff_t*ppos)/*读函数*/
{……}
/*写函数*/
staticssize_tmem_write(structfile*filp,constchar__user*buf,size_tsize,loff_t*ppos){……}
staticloff_tmem_llseek(structfile*filp,loff_toffset,intwhence)/*seek文件定位函数*/
{……}
staticconststructfile_operationsmem_fops=/*文件操作结构体*/
{.owner=THIS_MODULE,
.llseek=mem_llseek,
.read=mem_read,
.write=mem_write,
.open=mem_open,
.release=mem_release,};
staticintmemdev_init(void)/*设备驱动模块加载函数*/
{……}
staticvoidmemdev_exit(void)/*模块卸载函数*/
{……}
MODULE_LICENSE("GPL");
module_init(memdev_init);
module_exit(memdev_exit);
5.答:
程序代码如下:
#include
intmain()
{
FILE*fp0=NULL;
charBuf[4096];
strcpy(Buf,"Helloworld!
");
printf("BUF:
%s\n",Buf);
fp0=fopen("/dev/memdev0","r+");
if(fp0==NULL)
{
printf("OpenMemdev0Error!
\n");
return-1;
}
fwrite(Buf,sizeof(Buf),1,fp0);
fseek(fp0,0,SEEK_SET);
strcpy(Buf,"BufisNULL!
");printf("BUF:
%s\n",Buf);
fread(Buf,sizeof(Buf),1,fp0);
/*检测结果*/
printf("BUF:
%s\n",Buf);
return0;
}
6.写一段完整的ARM汇编程序:
循环累加队列中的所有元素,直到碰上零值元素,结果放在r4。
源程序末尾处声明队列:
array
DCD0x11
DCD0x22
DCD0
r0指向队列头:
ADRr0,array
使用命令LDRr1,[r0],#4来装载,累加至r4之中,循环直到r1为0,用死循环停止。
答:
AREAexample,CODE
ENTRY
MOVr4,#0;设置初始值
ADRr0,array
Loop
LDRr1,[r0],#4;基址指针r0自动增加
ADDr4,r4,r1
CMPr1,#0
BNEloop;r1为0时中断循环
Stop
Bstop;死循环
Array
DCD0x11;声明队列
DCD0x22
DCD0
END
7.下面程序是操作6个八段数码管驱动程序的部分代码。
(省略号部分代码与解题无关,故略去,并给出注释)仔细阅读代码,完成标号
(1)-(7)空白处的程序代码。
MODULE_PARM(LED_MODULE,"b");
#defineDEVICE_NAME"emdoor_8seg"
#defineSEG_CS10x10200000
#defineSEG_CS20x10300000
#defineSEG_CS30x10400000
staticintSegMajor=0;
unsignedlong*cs1_address,*cs2_address,*cs3_address;
structseg
{charled1_val;
charled2_val;
charled3_val;
charled4_val;
charled5_val;
charled6_val;
charnegative;
};
staticvoidUpdateled(structseg*seg_7)
{unsignedshortbuff=0x00;
buff=seg_7->led1_val;
buff=buff|(seg_7->led2_val<<8);
writew(buff,cs1_address);
buff=0x00;
buff=seg_7->led3_val;
buff=
(1)
(2)
……//第三个数码管地址的写入
return;
}
void