《嵌入式操作系统(共12页).doc》由会员分享,可在线阅读,更多相关《嵌入式操作系统(共12页).doc(12页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、精选优质文档-倾情为你奉上问答题1什么是嵌入式系统,它由哪几部分组成?嵌入式系统是指操作系统和功能软件集成于计算机硬件系统之中。简单的说就是系统的应用软件与系统的硬件一体化,类似与BIOS的工作方式。具有软件代码小,高度自动化,响应速度快等特点。特别适合于要求实时的和多任务的体系。根据IEEE的定义:嵌入式系统是“用于控制、监视或者辅助操作机器和设备的装置”。简单地讲就是嵌入到对象体中的专用计算机系统。嵌入式系统一般有3个主要的组成部分:硬件、实时操作系统以及应用软件。图1.1 嵌入式系统三个组成部分硬件:包括处理器、存储器、输入输出设备、其他部分辅助系统等。实时操作系统:用于管理应用软件,并
2、提供一种机制,使得处理器分时地执行各个任务并完成一定的时限要求.应用软件:实现具体业务逻辑功能。2嵌入式系统的三要素是什么?嵌入式系统的三要素是嵌入、专用、计算机;其中嵌入性指的是嵌入到对象体系中,有对象环境要求;专用性是指软、硬件按对象要求裁减;计算机指实现对象的智能化功能。广义地说一个嵌入式系统就是一个具有特定功能或用途的计算机软硬件集合体。即以应用为中心、以计算机技术为基础、软件硬件可裁剪、适应应用系统对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统 。3列举五种以上的嵌入式实时操作系统?嵌入式实时操作系统是指操作系统本身要能在一个固定时限内对程序调用(或外部事件)做出正确的反应
3、,亦即对时序与稳定性的要求十分严格。目前国际较为知名的有:VxWorks、NeutrinoRTOS、Nucleus Plus、 OS/9、VRTX、LynuxOS,RTLinux、BlueCat RT等。4嵌入式系统一般由几层组成?简单介绍其作用?嵌入式系统一般由硬件层、中间层、软件层和功能层组成。其作用分别如下:(1)硬件层 :由嵌入式微处理器、外围电路和外设组成。外围电路有:电源电路、复位电路、调试接口和存储器电路,就构成一个嵌入式核心控制模块。操作系统和应用程序都可以固化在ROM或者Flash中。为方便使用,有的模块在此基础上增加了LCD、键盘、USB接口,以及其他一些功能的扩展电路。(
4、2)中间层 :硬件层与软件层之间为中间层,也称为BSP(Board Support Package,板级支持包)。作用:将系统软件与底层硬件部分隔离,使得系统的底层设备驱动程序与硬件无关;功能:一般应具有相关硬件的初始化、数据的输入/输出操作和硬件设备的配置等功能。BSP是主板硬件环境和操作系统的中间接口,是软件平台中具有硬件依赖性的那一部分,主要目的是为了支持操作系统,使之能够更好地运行于硬件主板上。(3)软件层 :主要是操作系统,有的还包括文件系统、图形用户接口和网络系统等。操作系统是一个标准的内核,将中断、I/O、定时器等资源都封装起来,以方便用户使用。(4)功能层 :由基于操作系统开发
5、的应用程序组成,用来完成对被控对象的控制功能。功能层是面向被控对象和用户的,为了方便用户操作,往往需要具有友好的人机界面。5简述嵌入式系统中非占先式与占先式调度算法的区别?非占先式调度法也称作合作型多任务,各个任务彼此合作共享一个CPU。中断服务可以使一个高优先级的任务由挂起状态变为就绪状态。但中断服务以后控制权还是回到原来被中断了的那个任务,直到该任务主动放弃CPU的使用权时,那个高优先级的任务才能获得CPU的使用权。当系统响应时间很重要时,要使用占先式内核。最高优先级的任务一旦就绪,总能得到CPU的控制权。当一个运行着的任务使一个比它优先级高的任务进入了就绪态,当前任务的CPU使用权就被剥
6、夺了,或者说被挂起了,那个高优先级的任务立刻得到了CPU的控制权。6硬实时操作系统,软实时操作系统以及两者的区别?在实时系统中,如果系统在指定的时间内未能实现某个确定的任务,会导致系统的全面失败,这样的系统被称为强实时系统或硬实时系统。强实时系统响应时间一般在毫秒或微秒级。在弱实时系统中,虽然响应时间同样重要,但是超时却不会发生致命的错误。其系统响应时间在毫秒至秒的数量级上,其实时性的要求比强实时系统要差一些。7嵌入式系统的设计步骤有哪些?各部分主要工作是什么?(1)需求分析阶段,罗列出用户的需求; (2)体系结构设计阶段,描述系统的功能如何实现; (3)详细设计阶段,进行硬件系统与软件系统的
7、分类划分,以决定哪些功能用硬件实现,哪些用软件实现; (4)系统集成,把系统的软件、硬件和执行装置集成在一起,进行调试,发现并改进在设计过程中的错误; (5)系统测试,对设计好的系统进行测试,看其是否满足给定的要求。 8. 1)cduser:改变目录位置至用户的工作目录 2)cd:/user:改变目录位置至相对路径user 的目录下 3)ls/root/-l:查看当前目录下的文件 4)cat/root/.bash_profile:查看文件.ba sh_profile的内容 5more/etc/innittab:分页查看inittab文件内容 6)cp/tmp/file1 file2:将目录/t
8、mp 下的文件file1 复制到当前目录下,文件名为f i l e 2 7)mv file1 dir1:将文件file1移到目录dir1 下,文件名仍为file1 8)mkdir dir1:建立一新目录d i r 1 9)rmdir dir1:删除目录dir1,但dir1 下必须没有文件存在,否则无法删除 10)rm file:删除文件名中有五个字符且前四个字符为file 的所有文件 11)$ cat config:文件config的内容依次显示到屏幕上 12)more file1:以分页方式查看文件名file1 的内容 13)cat file1| more:以分页方式查看文件名file1 的
9、内容 14)du -s dir1:显示目录dir1 的总容量 15)chmod 755 dir1:对于目录d i r 1,设定成任何使用者皆有读取及执行的权利,但只有所有者可做修改 16)chmod 700 file1:对于文件f i l e 1,设定只有所有者可以读、写和执行的权利 17)ln -s file3 file4:将文件file4 链接至文件f i l e 3 18)grep abc file1:寻找文件f i l e 1中包含字符串abc 所在行的文本内容。 19)find/-name file1 -print:自根目录下寻找文件file1 的路径。 20)diff -r dir
10、1 dir2:比较目录dir1 与dir2 内各文件的不同之处。9 利用GDB进行调试时,可通过step或next命令进行单步执行 10VI三种模式:命令模式 末行模式 输入模式11使用GCC编译C程序生成可执行文件有时似乎是一步完成的,但实际要经历四步:预处理、编译、汇编和连接12.Linux 内核的编译菜单有好几个版本,运行: 1)make config:进入命令行,可以一行一行的配置,但使用不十分方便。 2)make menuconfig:大多数开发人员使用的Linux 内核编译菜单,使用方便。 3)make xconfig:在2.4.X 以及以前版本中xconfig 菜单是基于TCL/
11、TK 的图形库的。13.在完成内核的裁减之后,内核的编译就只要执行以下几条命令:make clean 编译内核之前先把环境给清理干净。有时你也可以用make realclean 或make mrproper 来彻底清除相关依赖,保证没有不正确的.o 文件存在。make dep 编译相关依赖文件 make zImage 创建内核镜像文件make modules 创建内核模块,若不创建内核模块,这步可以不要。make install 把相关文件拷贝到默认的目录。在给嵌入式设备编译时这步可以不要。因为具体的内核安装还需要你手工进行。14.何为虚拟内存?虚拟内存的管理有何作用? 使用虚拟地址寻址整个系
12、统的主存和辅存的方式在现代操作系统中被称为虚拟内存。MMU 便是实现虚拟内存的必要条件。嵌入式处理器如果存在MMU ,由于在MMU具备内存地址映射和寻址功能,操作系统会使用它完成从虚拟地址到物理地址的转换, 所有的应用程序只需要使用虚拟地址寻址数据。 虚拟内存的管理方法使系统既可以运行体积比物理内存还要大的应用程序,也可以实现“按需调页”策略,既满足了程序的运行速度,又节约了物理内存空间。15.进程内存区域涉及哪几种数据段? 进程内存区域涉及到5种数据段,即:代码段:代码段是用来存放可执行文件的操作指令,也就是说是它是可执行程序在内存中的镜像数据段:数据段用来存放可执行文件中已初始化全局变量,
13、换句话说就是存放程序静态分配的变量和全局变量BSS段:BSS段包含了程序中未初始化的全局变量,在内存中 BSS段全部置零堆:堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上;当利用free等函数释放内存时,被释放的内存从堆中被剔除栈:栈是用户存放程序临时创建的局部变量,也就是说函数括弧“”中定义的变量。除此以外,在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。16.简述内核空间和用户空间的区别 。 在Linux系统中,内核在最高级执行,也称为
14、“系统态”,在这一级任何操作都可以执行。而应用程序则执行在最低级,即所谓的“用户态”。在这一级处理器禁止对硬件的直接访问和对内存的未授权访问。模块是在所谓的“内核空间”中运行的,而应用程序则是在“用户空间”中运行的。它们分别引用不同的内存映射,也就是程序代码使用不同的“地址空间”。17.简述共享内存的作用。 共享内存区域是被多个进程共享的一部分物理内存。如果多个进程都把该内存区域映射到自己的虚拟地址空间,则这些进程就都可以直接访问该共享内存区域,从而可以通过该区域进行通信。共享内存是进程间共享数据的一种最快的方法,一个进程向共享内存区域写入了数据,共享这个内存区域的所有进程就可以立刻看到其中的
15、内容。这块共享虚拟内存的页面,出现在每一个共享该页面的进程的页表中。但是它不需要在所有进程的虚拟内存中都有相同的虚拟地址。18.简述内存管理与虚拟文件系统之间的关系。 内存管理利用虚拟文件系统支持交换,交换进程(swapd)定期由调度程序调度,这也是内存管理依赖于进程调度的唯一原因。当一个进程存取的内存映射被换出时,内存管理向文件系统发出请求,同时,挂起当前正在运行的进程。19.线程的同步方式有互斥量,信号灯和条件变量等,分析以上几种同步方式可在什么场合下使用。 Mutex互斥量,用于操作某个临界资源时对该资源上锁,以实现互斥地对独占资源的使用。(3分)Semophore信号灯,信号灯内有一计
16、数器,可以用于对多个同类资源的分配。当资源用完时,申请资源的线程会在信号量上睡眠,有线程释放资源时,再将该线程唤醒继续运行。(3分)Condition条件变量,条件变量用于等待信号。当一个线程需要等待某个信号时,就可到条件变量上等待,当信号具备时,系统会唤醒该线程继续运行。(4分)20.进一步考虑当两个进程处于不同机器上时,需要采用的通信方式?本地:共享内存+信号量, 适合于大量数据传输。Linux支持系统V和POSIX的共享内存和信号量。(5分)远程:Socket+应用协议。适合于跨网络的(大量)数据传输。Linux支持BSD的socket。应用层协议需要自行设计。21.程序,进程,线程有何
17、区别和联系 程序是编译后形成的可执行代码,是静止的。进程是程序的一次执行,是活动的。线程是进程的可执行单元,同一进程的不同线程共享进程的资源和地址空间。22.多线程有几种实现方法,线程间同步有几种实现方法,分别都是什么? 两种,一种是继承Thread,另外一种是实现接口Runnable。 同步的实现方法有两种,分别是synchronized, wait与notify。用synchronized可以对一段代码、一个对象及一个方法进行加锁。用wait与notify可以使对象处于等待及唤醒方式导致同步,因为每个对象都直接或间接的继承了Object类。23.Linux执行进程调度一般是在以下情况发生的
18、: 1)正在执行的进程运行完毕;(2)正在执行的进程调用阻塞原语将自己阻塞起来进入等待状态;(3)正在执行的进程调用了P原语操作,从而因资源不足而被阻塞;或调用了V原语操作激活了等待资源的进程队列;(4)执行中的进程提出I/O请求后被阻塞;(5)系统分配的时间片已经用完;以上都是CPU为不可剥夺方式下的引起进程调度的原因。在CPU方式是可剥夺时,还有下面的原因:(6)就绪队列中的某个进程的优先级变得高于当前运行进程的优先级,从而也将引起进程调度。编程题:1已知C语言程序有主程序模块prog.c,prog.h,其中调用了另一模块subr.c,subr.h中的功能。试写出一个可将这两个模块编译成可
19、执行文件pr1的Makefile.参考答案:pr1: prog.o subr.o gcc o pr1 prog.o subr.o prog.o: prog.c prog.h gcc c o prog.o prog.csubr.o: subr.c subr.h gcc c o subr.o subr.c2. (1) 编写Makefile文件,最终的目标文件为hello,交叉编译器为arm-linux-gcc hello: main.o list.o symbol.o table.o gcc -o prog main.o list.o symbol.o table.omain.o: main.c
20、table.h symbol.h list.h gcc -c -o main.o main.clist.o: list.c list.h gcc -c -o list.o list.csymbol.o: symbol.c symbol.h gcc -c -o symbol.o symbol.ctable.o: table.c table.h symbol.h list.h gcc -c -o table.o table.cclean: rm hello *.o(2) 在目标上上通过网络文件系统挂载/mnt到宿主机上的/home/arm目录。mount t nfs o noclock 192.1
21、68.0.10:/home/armtest/hello /mnt3. 在Linux操作系统下,编程实现以下功能(1)主程序hello.c(打印HELLO WORLD)(2)主程序通过头文件hello.h调用message函数。(3)头文件hello.h(声明message函数)(4)message函数由message.c定义(打印“This is a message!”)hello.c:# include # include # include # include hello.hint main (int argc,char *argv)printf(Hello World!n); messa
22、ge(); return 0; hello.h: void message(void); message.c: # include void message (void) printf(This is a message!n) 4. 阅读下面的shell程序,写出执行结果Tom is my friend。 Jack is my friend Harry is my friend5. 对下列shell程序加注释,并说明程序的功能和调用方法。(1)程序注释#!/bin/sh 定义实用的shell # /etc/rc.d/rc.httpd 注释行,凡是以星号开始的行均为注释行。 # Start/st
23、op/restart the Apache web server. # To make Apache start automatically at boot, make this # file executable: chmod 755 /etc/rc.d/rc.httpd #case $1 in #case结构开始,判断“位置参数”决定执行的操作。本程序携带一个“位置参数”,即$1 start) #若位置参数为start/usr/sbin/apachectl start ; #启动httpd进程stop) #若位置参数为stop/usr/sbin/apachectl stop ; #关闭ht
24、tpd进程restart) #若位置参数为stop/usr/sbin/apachectl restart ; #重新启动httpd进程*) #若位置参数不是start、stop或restart时echo usage $0 start|stop|restart ; #显示命令提示信息:程序的调用方法esac #case结构结束(2)程序的功能是启动,停止或重新启动httpd进程(3)程序的调用方式有三种:启动,停止和重新启动。6.用Shell编程,判断一个文件是不是字符设备文件,如果是将其复制到、dev目录下。#!/bin/sh FILENAME= echo “Input file name:”
25、 read FILENAME if -c $FILENAME then cp $FILENAME /dev fi7. 用shell编程,求两个数之和#/bin/bash typeset first secondread -p Input t e first number: firstread -p Input the second number: secondon个result=$first+$second echo result is : $result exit 08、设计一个Shell程序,在/userdata目录下建立50个目录,即user1-user50,并没有设置每个目录的权限,其
26、中其他用户的权限为:读;文件所有者的权限为:读,写,执行、文件所有者所在组的权限为:读,执行。#!/bin/sh i=1while i -le 50 doif -d /userdata ;then mkdir -p /userdata/user$ichmod 754 /userdata/user$i echo user$ilet i = i + 1 (或i=$($i1) elsemkdir /userdata mkdir -p /userdata/user$i chmod 754 /userdata/user$iecho user$i let i = i + 1 (或i=$($i1)Fi Do
27、ne1.编写一个主函数,完成动态配置10个struct test空间#include struct test int a10; char b20; int main()struct test *ptr=calloc(sizeof(struct test),10);9编写一个程序,利用mmap()来读取/etc/passwd文件的内容#include #include #include#include #includemain() int fd; void *start; struct stat sb;fd=open(“/etc/passwd”,O_RDONLY);fstat(fd,&sb);
28、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”,如果没有则创建该文件,并使其具有读写属性Void main(void)int fid; fid = open(“./test.txt”,O_RDWR|O_CREAT); if(fid=-1)Printf(“ope
29、n or create error n”); exit(0); Close(fid); (2)编写一个makefile实现自动编译,生成可执行文件mainobjects = main.o exec = main all:$(objects) gcc o $(exec) $(objects)main.o:main.c gcc c main.c clean: rm r $(exec) $(objects)11.编写程序,实现把一个文件的内容复制到另一个文件中#include #include #include #include #include #include #define BUFFER_SI
30、ZE 1024 intmain(intargc,char*argv) intfrom_fd,to_fd; intbytes_read,bytes_write; charbufferBUFFER_SIZE; char*ptr; if(argc!=3) fprintf(stderr,Usage:%sfromfiletofilena,argv0);exit(1); if(from_fd=open(argv1,O_RDONLY)=-1) fprintf(stderr,Open%sError:%sn,argv1,strerror(errno); exit(1); if(to_fd=open(argv2,
31、O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR)=-1) fprintf(stderr,Open%sError:%sn,argv2,strerror(errno);exit(1); /* 以下代码是一个经典的拷贝文件的代码 */ while(bytes_read=read(from_fd,buffer,BUFFER_SIZE) if(bytes_read=-1)&(errno!=EINTR)break; elseif(bytes_read0) ptr=buffer; while(bytes_write=write(to_fd,ptr,bytes_read) if(bytes_
32、write=-1)&(errno!=EINTR)break; elseif(bytes_write=bytes_read)break; elseif(bytes_write0) ptr+=bytes_write; bytes_read-=bytes_write if(bytes_write=-1)break; close(from_fd); close(to_fd); exit(0); 12从键盘上输入两个学生的基本信息,然后 写入一个到文件中,最后读出这两个学生的数据,并显示在屏幕上。#include struct student char name10; Int age; ;int mai
33、n() FILE *fp; int i;struct student boya2, boyb2, *pp, *qq;if(fp = fopen(7-6.txt,w+)= NULL) printf(Can not open file, exit .n);return -1; pp = boya; qq = boyb; printf(please input data:n); for (i = 0; i name, &pp-age); pp = boya;fwrite(pp, sizeof(struct student), 2, fp); rewind(fp); fread(qq, sizeof(
34、struct student), 2, fp); printf(namettagen); for(i = 0; i name, qq-age); fclose(fp); return 0; 13父进程和子进程之间创建了一个管道,建立之间的通信 (1) 将数据缓冲区清0 memset(buf_r,0,sizeof(buf_r) (2) 创建管道 if(pipe(pipe_fd)0) (6) 关闭子进程读描述符 close(pipe_fd0) (7) 父进程运行控制语句 else if(pid0) (8) 关闭父进程的读描述符close(pipe_fd0) (9) 将数据写入缓冲区 if(writ
35、e(pipe_fd1,”hello”,5)!=-1) (10) 关闭父进程写描述符 close(pipe_fd1) 14编程创建一个特定的IPC结构的关键字和一个信号量,建立此信号量的索引,修改索引指向的信号量的值,最后清除信号量。void main() key_t unique_key; int id; struct sembuf lock_it;union semun options; int i; unique_key = ftok(., a); id = semget(unique_key, 1, IPC_CREAT | IPC_EXCL | 0666);printf(semaphor
36、e id=%dn, id); options.val = 1; semctl(id, 0, SETVAL, options); i = semctl(id, 0, GETVAL, 0);printf(value of semaphore at index 0 is %dn, i);lock_it.sem_num = 0; lock_it.sem_op = -1; lock_it.sem_flg = IPC_NOWAIT; if (semop(id, &lock_it, 1) = -1) printf(can not lock semaphore.n);exit(1);i = semctl(id
37、, 0, GETVAL, 0);printf(value of semaphore at index 0 is %dn, i);semctl(id, 0, IPC_RMID, 0);15守护进程编程。守护进程实例包括两部分:主程序test.c和初始化程序init.c。主程序每隔一分钟向/tmp目录中的日志test.log报告运行状态;初始化程序中init_daemon函数负责生成守护进程。可以利用init_daemon函数生成自己的守护进程。(1)init.c清单 #include #include #include #include #include void init_daemon(voi
38、d) int pid; int i; if(pid=fork() exit(0); else if(pid 0) exit(1); setsid(); if(pid=fork()exit(0); else if(pid 0) exit(1);for(i=0;i NOFILE;+i) close(i); chdir(/tmp); umask(0);return; (2) test.c清单 #include #include void init_daemon(void);main() FILE *fp; time_t t; init_daemon();while(1) sleep(60); if(
39、fp=fopen(test.log,a) =0) t=time(0); re at %sn,asctime(localtime(&t) ); fclose(fp); 编译:gcc -g -o test init.c test.c 查看进程:ps -ef 进程的各种特性满足上面的要求。16.实现父进程和子进程间的通信。程序包括;创建无名管道、子进程向父进程写数据及关闭管道的读端、父进程从管道读取子进程写的数据及关闭管理的写端、读有名管道和写有名管道 #define INPUT 0 #define OUTPUT 1void main() int file_descriptors2; pid_t p
40、id; char buf256;int returned_count; pipe(file_descriptors);if(pid = fork() = -1) printf(Error in forkn); exit(1); if(pid = 0) printf(in the spawned (child) process.n);close(file_descriptorsINPUT);write(file_descriptorsOUTPUT, test data, strlen(test data); exit(0); else printf(in the spawning (parent
41、) process.n);close(file_descriptorsOUTPUT);returned_count = read(file_descriptorsINPUT, buf, sizeof(buf);printf(%d bytes of data received from spawned process: %sn,returned_count, buf); 17.在Linux系统下,有名管道可由两种方式创建:命令行方式mknod系统调用和函数mkfifo。下面的两种途径都在当前目录下生成了一个名为myfifo的有名管道:方式一:mkfifo(myfifo,rw); 方式二:mkno
42、d myfifo p生成了有名管道后,就可以使用一般的文件I/O函数如open、close、read、write等来对它进行操作。下面即是一个简单的例子,假设我们已经创建了一个名为myfifo的有名管道。/* 进程一:读有名管道*/#include #include void main() FILE * in_file; int count = 1;char buf80; in_file = fopen(mypipe, r); if (in_file = NULL) printf(Error in fdopen.n); exit(1); while (count = fread(buf, 1,
43、 80, in_file) 0)printf(received from pipe: %sn, buf); fclose(in_file); /* 进程二:写有名管道*/#include #include void main() FILE * out_file; int count = 1;char buf80; out_file = fopen(mypipe, w); if (out_file = NULL) printf(Error opening pipe.); exit(1);sprintf(buf,this is test data for the named pipe examplen);fwrite(buf, 1, 80, out_file);fclose(out_file);8.8编写一个程序,实现以下功能(1) 父进程使用系统调用pipe()建立一个管道。(2) 创建两个子进程,分别向管道发下面一条信息后结束。This is the first message!This is the second message!(3) 父进程从管道中分别接受两个子进程发来的消息并显示该消息,然后父进程结束。两个子进程的发送没有先后要求。源程序如下:#include #include #include main()Int p1,p2,fd2;