嵌入式操作系统.docx
《嵌入式操作系统.docx》由会员分享,可在线阅读,更多相关《嵌入式操作系统.docx(21页珍藏版)》请在冰点文库上搜索。
嵌入式操作系统
嵌入式操作系统
问答题
1.什么是嵌入式系统,它由哪几部分组成?
嵌入式系统是指操作系统和功能软件集成于计算机硬件系统之中。
简单的说就是系统的应用软件与系统的硬件一体化,类似与BIOS的工作方式。
具有软件代码小,高度自动化,响应速度快等特点。
特别适合于要求实时的和多任务的体系。
根据IEEE的定义:
嵌入式系统是“用于控制、监视或者辅助操作机器和设备的装置”。
简单地讲就是嵌入到对象体中的专用计算机系统。
嵌入式系统一般有3个主要的组成部分:
硬件、实时操作系统以及应用软件。
图1.1嵌入式系统三个组成部分
硬件:
包括处理器、存储器、输入输出设备、其他部分辅助系统等。
实时操作系统:
用于管理应用软件,并提供一种机制,使得处理器分时地执行各个任务并完成一定的时限要求.应用软件:
实现具体业务逻辑功能。
2.嵌入式系统的三要素是什么?
嵌入式系统的三要素是嵌入、专用、计算机;其中嵌入性指的是嵌入到对象体系中,有对象环境要求;专用性是指软、硬件按对象要求裁减;计算机指实现对象的智能化功能。
广义地说一个嵌入式系统就是一个具有特定功能或用途的计算机软硬件集合体。
即以应用为中心、以计算机技术为基础、软件硬件可裁剪、适应应用系统对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统。
3.列举五种以上的嵌入式实时操作系统?
嵌入式实时操作系统是指操作系统本身要能在一个固定时限内对程序调用(或外部事件)做出正确的反应,亦即对时序与稳定性的要求十分严格。
目前国际较为知名的有:
VxWorks、NeutrinoRTOS、NucleusPlus、OS/9、VRTX、LynuxOS,RTLinux、BlueCatRT等。
4.嵌入式系统一般由几层组成?
简单介绍其作用?
嵌入式系统一般由硬件层、中间层、软件层和功能层组成。
其作用分别如下:
(1)硬件层:
由嵌入式微处理器、外围电路和外设组成。
外围电路有:
电源电路、复位电路、调试接口和存储器电路,就构成一个嵌入式核心控制模块。
操作系统和应用程序都可以固化在ROM或者Flash中。
为方便使用,有的模块在此基础上增加了LCD、键盘、USB接口,以及其他一些功能的扩展电路。
(2)中间层:
硬件层与软件层之间为中间层,也称为BSP(BoardSupportPackage,板级支持包)。
作用:
将系统软件与底层硬件部分隔离,使得系统的底层设备驱动程序与硬件无关;功能:
一般应具有相关硬件的初始化、数据的输入/输出操作和硬件设备的配置等功能。
BSP是主板硬件环境和操作系统的中间接口,是软件平台中具有硬件依赖性的那一部分,主要目的是为了支持操作系统,使之能够更好地运行于硬件主板上。
(3)软件层:
主要是操作系统,有的还包括文件系统、图形用户接口和网络系统等。
操作系统是一个标准的内核,将中断、I/O、定时器等资源都封装起来,以方便用户使用。
(4)功能层:
由基于操作系统开发的应用程序组成,用来完成对被控对象的控制功能。
功能层是面向被控对象和用户的,为了方便用户操作,往往需要具有友好的人机界面。
5.简述嵌入式系统中非占先式与占先式调度算法的区别?
非占先式调度法也称作合作型多任务,各个任务彼此合作共享一个CPU。
中断服务可以使一个高优先级的任务由挂起状态变为就绪状态。
但中断服务以后控制权还是回到原来被中断了的那个任务,直到该任务主动放弃CPU的使用权时,那个高优先级的任务才能获得CPU的使用权。
当系统响应时间很重要时,要使用占先式内核。
最高优先级的任务一旦就绪,总能得到CPU的控制权。
当一个运行着的任务使一个比它优先级高的任务进入了就绪态,当前任务的CPU使用权就被剥夺了,或者说被挂起了,那个高优先级的任务立刻得到了CPU的控制权。
6.硬实时操作系统,软实时操作系统以及两者的区别?
在实时系统中,如果系统在指定的时间内未能实现某个确定的任务,会导致系统的全面失败,这样的系统被称为强实时系统或硬实时系统。
强实时系统响应时间一般在毫秒或微秒级。
在弱实时系统中,虽然响应时间同样重要,但是超时却不会发生致命的错误。
其系统响应时间在毫秒至秒的数量级上,其实时性的要求比强实时系统要差一些。
7.嵌入式系统的设计步骤有哪些?
各部分主要工作是什么?
(1)需求分析阶段,罗列出用户的需求;
(2)体系结构设计阶段,描述系统的功能如何实现;(3)详细设计阶段,进行硬件系统与软件系统的分类划分,以决定哪些功能用硬件实现,哪些用软件实现;(4)系统集成,把系统的软件、硬件和执行装置集成在一起,进行调试,发现并改进在设计过程中的错误;(5)系统测试,对设计好的系统进行测试,看其是否满足给定的要求。
8.1)cd~user:
改变目录位置至用户的工作目录2)cd:
/user:
改变目录位置至相对路径user的目录下3)ls/root/-l:
查看当前目录下的文件4)cat/root/.bash_profile:
查看文件.bash_profile的内容5more/etc/innittab:
分页查看inittab文件内容6)cp/tmp/file1file2:
将目录/tmp下的文件file1复制到当前目录下,文件名为file27)mvfile1dir1:
将文件file1移到目录dir1下,文件名仍为file18)mkdirdir1:
建立一新目录dir19)rmdirdir1:
删除目录dir1,但dir1下必须没有文件存在,否则无法删除10)rmfile:
删除文件名中有五个字符且前四个字符为file的所有文件11)$catconfig:
文件config的内容依次显示到屏幕上12)morefile1:
以分页方式查看文件名file1的内容13)catfile1|more:
以分页方式查看文件名file1的内容14)du-sdir1:
显示目录dir1的总容量15)chmod755dir1:
对于目录dir1,设定成任何使用者皆有读取及执行的权利,但只有所有者可做修改16)chmod700file1:
对于文件file1,设定只有所有者可以读、写和执行的权利17)ln-sfile3file4:
将文件file4链接至文件file318)grepabcfile1:
寻找文件file1中包含字符串abc所在行的文本内容。
19)find/-namefile1-print:
自根目录下寻找文件file1的路径。
20)diff-rdir1dir2:
比较目录dir1与dir2内各文件的不同之处。
9.利用GDB进行调试时,可通过step或next命令进行单步执行
10.VI三种模式:
命令模式末行模式输入模式
11.使用GCC编译C程序生成可执行文件有时似乎是一步完成的,但实际要经历四步:
预处理、编译、汇编和连接
12.Linux内核的编译菜单有好几个版本,运行:
1)makeconfig:
进入命令行,可以一行一行的配置,但使用不十分方便。
2)makemenuconfig:
大多数开发人员使用的Linux内核编译菜单,使用方便。
3)makexconfig:
在2.4.X以及以前版本中xconfig菜单是基于TCL/TK的图形库的。
13.在完成内核的裁减之后,内核的编译就只要执行以下几条命令:
makeclean编译内核之前先把环境给清理干净。
有时你也可以用makerealclean或makemrproper来彻底清除相关依赖,保证没有不正确的.o文件存在。
makedep编译相关依赖文件makezImage创建内核镜像文件
makemodules创建内核模块,若不创建内核模块,这步可以不要。
makeinstall把相关文件拷贝到默认的目录。
在给嵌入式设备编译时这步可以不要。
因为具体的内核安装还需要你手工进行。
14.何为虚拟内存?
虚拟内存的管理有何作用?
使用虚拟地址寻址整个系统的主存和辅存的方式在现代操作系统中被称为虚拟内存。
MMU便是实现虚拟内存的必要条件。
嵌入式处理器如果存在MMU,由于在MMU具备内存地址映射和寻址功能,操作系统会使用它完成从虚拟地址到物理地址的转换,所有的应用程序只需要使用虚拟地址寻址数据。
虚拟内存的管理方法使系统既可以运行体积比物理内存还要大的应用程序,也可以实现“按需调页”策略,既满足了程序的运行速度,又节约了物理内存空间。
15.进程内存区域涉及哪几种数据段?
进程内存区域涉及到5种数据段,即:
①代码段:
代码段是用来存放可执行文件的操作指令,也就是说是它是可执行程序在内存中的镜像②数据段:
数据段用来存放可执行文件中已初始化全局变量,换句话说就是存放程序静态分配的变量和全局变量③BSS段:
BSS段包含了程序中未初始化的全局变量,在内存中BSS段全部置零④堆:
堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。
当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上;当利用free等函数释放内存时,被释放的内存从堆中被剔除⑤栈:
栈是用户存放程序临时创建的局部变量,也就是说函数括弧“{}”中定义的变量。
除此以外,在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。
16.简述内核空间和用户空间的区别。
在Linux系统中,内核在最高级执行,也称为“系统态”,在这一级任何操作都可以执行。
而应用程序则执行在最低级,即所谓的“用户态”。
在这一级处理器禁止对硬件的直接访问和对内存的未授权访问。
模块是在所谓的“内核空间”中运行的,而应用程序则是在“用户空间”中运行的。
它们分别引用不同的内存映射,也就是程序代码使用不同的“地址空间”。
17.简述共享内存的作用。
共享内存区域是被多个进程共享的一部分物理内存。
如果多个进程都把该内存区域映射到自己的虚拟地址空间,则这些进程就都可以直接访问该共享内存区域,从而可以通过该区域进行通信。
共享内存是进程间共享数据的一种最快的方法,一个进程向共享内存区域写入了数据,共享这个内存区域的所有进程就可以立刻看到其中的内容。
这块共享虚拟内存的页面,出现在每一个共享该页面的进程的页表中。
但是它不需要在所有进程的虚拟内存中都有相同的虚拟地址。
18.简述内存管理与虚拟文件系统之间的关系。
内存管理利用虚拟文件系统支持交换,交换进程(swapd)定期由调度程序调度,这也是内存管理依赖于进程调度的唯一原因。
当一个进程存取的内存映射被换出时,内存管理向文件系统发出请求,同时,挂起当前正在运行的进程。
19.线程的同步方式有互斥量,信号灯和条件变量等,分析以上几种同步方式可在什么场合下使用。
Mutex互斥量,用于操作某个临界资源时对该资源上锁,以实现互斥地对独占资源的使用。
(3分)
Semophore信号灯,信号灯内有一计数器,可以用于对多个同类资源的分配。
当资源用完时,申请资源的线程会在信号量上睡眠,有线程释放资源时,再将该线程唤醒继续运行。
(3分)
Condition条件变量,条件变量用于等待信号。
当一个线程需要等待某个信号时,就可到条件变量上等待,当信号具备时,系统会唤醒该线程继续运行。
(4分)
20.进一步考虑当两个进程处于不同机器上时,需要采用的通信方式?
本地:
共享内存+信号量,适合于大量数据传输。
Linux支持系统V和POSIX的共享内存和信号量。
(5分)
远程:
Socket+应用协议。
适合于跨网络的(大量)数据传输。
Linux支持BSD的socket。
应用层协议需要自行设计。
21.程序,进程,线程有何区别和联系程序是编译后形成的可执行代码,是静止的。
进程是程序的一次执行,是活动的。
线程是进程的可执行单元,同一进程的不同线程共享进程的资源和地址空间。
22.多线程有几种实现方法,线程间同步有几种实现方法,分别都是什么?
两种,一种是继承Thread,另外一种是实现接口Runnable。
同步的实现方法有两种,分别是synchronized,wait与notify。
用synchronized可以对一段代码、一个对象及一个方法进行加锁。
用wait与notify可以使对象处于等待及唤醒方式导致同步,因为每个对象都直接或间接的继承了Object类。
23.Linux执行进程调度一般是在以下情况发生的:
1)正在执行的进程运行完毕;
(2)正在执行的进程调用阻塞原语将自己阻塞起来进入等待状态;(3)正在执行的进程调用了P原语操作,从而因资源不足而被阻塞;或调用了V原语操作激活了等待资源的进程队列;(4)执行中的进程提出I/O请求后被阻塞;(5)系统分配的时间片已经用完;以上都是CPU为不可剥夺方式下的引起进程调度的原因。
在CPU方式是可剥夺时,还有下面的原因:
(6)就绪队列中的某个进程的优先级变得高于当前运行进程的优先级,从而也将引起进程调度。
编程题:
1.已知C语言程序有主程序模块prog.c,prog.h,其中调用了另一模块subr.c,subr.h中的功能。
试写出一个可将这两个模块编译成可执行文件pr1的Makefile.参考答案:
pr1:
prog.osubr.ogcc–opr1prog.osubr.o
prog.o:
prog.cprog.hgcc–c–oprog.oprog.c
subr.o:
subr.csubr.hgcc–c–osubr.osubr.c
2.
(1)编写Makefile文件,最终的目标文件为hello,交叉编译器为arm-linux-gcc
hello:
main.olist.osymbol.otable.ogcc-oprogmain.olist.osymbol.otable.o
main.o:
main.ctable.hsymbol.hlist.hgcc-c-omain.omain.c
list.o:
list.clist.hgcc-c-olist.olist.c
symbol.o:
symbol.csymbol.hgcc-c-osymbol.osymbol.c
table.o:
table.ctable.hsymbol.hlist.hgcc-c-otable.otable.c
clean:
rmhello*.o
(2)在目标上上通过网络文件系统挂载/mnt到宿主机上的/home/arm目录。
mount–tnfs–onoclock192.168.0.10:
/home/armtest/hello/mnt
3.在Linux操作系统下,编程实现以下功能
(1)主程序hello.c(打印HELLOWORLD)
(2)主程序通过头文件hello.h调用message函数。
(3)头文件hello.h(声明message函数)
(4)message函数由message.c定义(打印“Thisisamessage!
”)
hello.c:
#include#include#include#include"hello.h"
intmain(intargc,char*argv[])
{ printf("HelloWorld!
\n"); message(); return0;}
hello.h:
voidmessage(void);message.c:
#include
voidmessage(void){ printf("Thisisamessage!
\n")}
4.阅读下面的shell程序,写出执行结果
Tomismyfriend。
JackismyfriendHarryismyfriend
5.对下列shell程序加注释,并说明程序的功能和调用方法。
(1)程序注释
#!
/bin/sh定义实用的shell#
#/etc/rc.d/rc.httpd注释行,凡是以星号开始的行均为注释行。
#
#Start/stop/restarttheApachewebserver.#
#TomakeApachestartautomaticallyatboot,makethis
#fileexecutable:
chmod755/etc/rc.d/rc.httpd#
case"$1"in#case结构开始,判断“位置参数”决定执行的操作。
本程序携带一个“位置参数”,即$1'start')#若位置参数为start
/usr/sbin/apachectlstart;;#启动httpd进程
'stop')#若位置参数为stop
/usr/sbin/apachectlstop;;#关闭httpd进程
'restart')#若位置参数为stop
/usr/sbin/apachectlrestart;;#重新启动httpd进程
*)#若位置参数不是start、stop或restart时
echo"usage$0start|stop|restart";;#显示命令提示信息:
程序的调用方法
esac#case结构结束
(2)程序的功能是启动,停止或重新启动httpd进程(3)程序的调用方式有三种:
启动,停止和重新启动。
6.用Shell编程,判断一个文件是不是字符设备文件,如果是将其复制到、dev目录下。
#!
/bin/shFILENAME=echo“Inputfilename:
”
readFILENAMEif[-c"$FILENAME"]thencp$FILENAME/devfi
7.用shell编程,求两个数之和
#/bin/bashtypesetfirstsecond
read-p"Inputtefirstnumber:
"first
read-p"Inputthesecondnumber:
"secondon个
result=$[$first+$second]echo"resultis:
$result"exit0
8、设计一个Shell程序,在/userdata目录下建立50个目录,即user1-user50,并没有设置每个目录的权限,其中其他用户的权限为:
读;文件所有者的权限为:
读,写,执行、文件所有者所在组的权限为:
读,执行。
#!
/bin/shi=1
while[i-le50]do
if[-d/userdata];thenmkdir-p/userdata/user$i
chmod754/userdata/user$iecho"user$i"
let"i=i+1"(或i=$(($i+1))else
mkdir/userdatamkdir-p/userdata/user$ichmod754/userdata/user$i
echo"user$i"let"i=i+1"(或i=$(($i+1))
FiDone
1.编写一个主函数,完成动态配置10个structtest空间
#include structtest
{ inta[10];charb[20]; }
intmain(){structtest*ptr=calloc(sizeof(structtest),10); }
9.编写一个程序,利用mmap()来读取/etc/passwd文件的内容
#include#include#include
#include#include
main() {intfd;void*start; structstatsb;
fd=open(“/etc/passwd”,O_RDONLY);
fstat(fd,&sb); start=mmap(NULL,sb.st_size,PROT_READ,MAP_PRIVATE,fd,0);
if(start==MAP_FAILED) return; printf(“%s”,start);
munma(start,sb.st_size); closed(fd); }
10.用C语言编写一个源程序main.c,实现以下功能。
(1)打开当前目录下的文件“test.txt”,如果没有则创建该文件,并使其具有读写属性
Voidmain(void)
{intfid;fid=open(“./test.txt”,O_RDWR|O_CREAT);if(fid==-1)
{Printf(“openorcreateerror\n”);exit(0);}
Close(fid);}
(2)编写一个makefile实现自动编译,生成可执行文件main
objects=main.oexec=main
all:
$(objects)gcc–o$(exec)$(objects)
main.o:
main.cgcc–cmain.c
clean:
rm–r$(exec)$(objects)
11.编写程序,实现把一个文件的内容复制到另一个文件中
#include#include#include
#include#include#include
#defineBUFFER_SIZE1024int main(int argc,char **argv)
{ int from_fd,to_fd;int bytes_read,bytes_write;
char buffer[BUFFER_SIZE]; char *ptr;
if(argc!
=3) {fprintf(stderr,"Usage:
%s fromfile tofile\n\a",argv[0]);
exit
(1);}
if((from_fd=open(argv[1],O_RDONLY))==-1){
fprintf(stderr,"Open %s Error:
%s\n",argv[1],strerror(errno));
exit
(1);}
if((to_fd=open(argv[2],O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR))==-1){
fprintf(stderr,"Open %s Error:
%s\n",argv[2],strerror(errno));exit
(1);
}
/*以下代码是一个经典的拷贝文件的代码*/
while(bytes_read=read(from_fd,buffer,BUFFER_SIZE)){
if((bytes_read==-1)&&(errno!
=EINTR)) break; else if(bytes_read>0){
ptr=buffer;
while(bytes_write=write(to_fd,ptr,bytes_read)){
if((bytes_write==-1)&&(