嵌入式Linux实时操作系统习题总结

2024-10-16

嵌入式Linux实时操作系统习题总结(共9篇)

嵌入式Linux实时操作系统习题总结 篇1

改进嵌入式Linux系统实时性新方案

时间:2009-05-12 23:31来源:Linux Website 作者:尚观 点击: 7

3次

对嵌入式Linux进行实时性改进是嵌入式操作系统领域的一个研究热点。本文在分析了现有嵌入式操作系统实时性不足的基础上,提出了一种新型的改进方案(将RTAI和uClinux相结合),并给出

对嵌入式Linux进行实时性改进是嵌入式操作系统领域的一个研究热点。本文在分析了现有嵌入式操作系统实时性不足的基础上,提出了一种新型的改进方案(将RTAI和uClinux相结合),并给出具体的工控应用实例,进一步对这种系统的功能进行有效验证。

图1:双内核实时系统嵌入式实时Linux架构。嵌入式Linux以代码开放、价格低廉、功能强大又易于移植的特性正在被广泛应用,为嵌入式操作系统提供了一个极具吸引力的选择。但许多实际应用,譬如多媒体通信、生产过程控制、在线事务处理等等都要求对外部事件在限定的时间内做出反应。因而嵌入式系统实时性问题越来越受到关注,对嵌入式Linux进行实时性改进也成为嵌入式操作系统领域的一个研究热点。

本文提出了一种基于uClinux的嵌入式实时操作系统方案。将RTAI和uClinux相结合,既满足了嵌入式应用的需求,同时又保证了系统的硬实时性。此外,还有强大的网络功能、易升级性、易移植性等优点。最后结合基于这一操作系统开发的重大装备远程监控系统的应用案例,进一步从功能和性能上对其进行验证。

现有嵌入式操作系统应用中存在的问题 一个优秀的嵌入式操作系统是嵌入式系统成功的关键。它除了具备一般操作系统最基本的功能,如任务调度、同步机制、中断处理、文件功能等,还需要具有以下特点:1.更好的硬件适应性,也就是良好的移植性;2.占有更少的硬件资源;3.高可靠性;4.提供强大的网络功能,支持TCP/IP协议及其他协议;5.有些应用要求具有实时性能。

现有的嵌入式操作系统大致可分为商用型和免费型两类:商用型操作系统由于功能稳定、可靠,有完善的技术支持和售后服务,在嵌入式市场占有一定的份额。但它同时也存在价格昂贵、需要版权、源代码不公开等一系列问题;免费型操作系统(如Linux)源码公开,有价格方面的优势,但在严格满足嵌入式实时应用需求方面还有欠缺。

图2:实时内核实现机理

RTAI对Linux的实时性改进

现有几种针对Linux的实时系统解决方案,实现方法主要包括两种:1)直接修改Linux内核、增加实时性,如:Montavista;2)在普通Linux内核之上增加实时模块、双内核结构,如:RTLinux或RTAI。

Montavista可以满足用户的软实时要求,RTLinux或RTAI着重增强Linux的硬实时特性。软实时系统的时限是柔性灵活的,它可以容忍偶然的超时错误。失败造成的后果并不严重,仅仅是轻微地降低了系统的吞吐量。硬实时系统有一个刚性的、不可改变的时间限制,它不允许任何超出时限的错误。超时错误会带来损害甚至导致系统失败、或者导致系统不能实现它的预期目标。

RTAI采用双内核方法,不直接使用Linux的任何功能,而是把需要高度时间精度的工作写成一个驱动程序的形式,然后直接用PC时序芯片所产生的中断调用这个驱动程序。RTAI与NMTRT-Linux的最大不同之处在于,它在Linux上定义了一组实时硬件抽象层(RTHAL)。RTHAL将RTAI需要在Linux中修改的部分定义成一组程序界面,RTAI只使用这组界面和Linux沟通。这样做的好处在于,用户可以将直接修改的Linux核心程序代码减至最小,这有可能使得将RTHAL移植到新版Linux的工作量减至最低。但是,RTAI虽然满足了硬实时性要求,却没有被裁减为足够小且适用于嵌入式系统。

RTAI+uClinux的实时方案

uClinux是为嵌入式应用设计的,它本身并没有更多地关注实时问题。uClinux经过小型化改造,形成了一个高度优化、代码紧凑的嵌入式Linux,并保留了Linux大多数的优点。它专门针对无MMU的CPU,去除了普通Linux内核中的虚拟内存管理部分。更重要的是,uClinux提供了完整的TCP/IP协议栈,并支持大量其他的网络协议,为嵌入式系统提供了强大的网络支持。而从前面的分析可以看出,RTAI是基于普通Linux内核,相对于嵌入式应用其内核过于庞大;而uClinux本身并没有更多地关注实时问题。因此,可以将RTAI和uClinux相结合,采用双内核的设计方案,既满足了嵌入式应用的需求,又保证了系统的硬实时性。

1.硬件抽象层

图3:系统中断处理流程图

系统的实现基础是硬件抽象层,通过硬件抽象层进行硬件管理,把基本内核和实时内核结合在一起,其中一个内核的改变,不会影响另一个内核的执行。硬件抽象层定义了本系统同硬件之间的抽象接口,主要用来截取硬件中断,并且依据实时内核调度器的需求,重定向为基本内核任务或是实时任务。RTHAL包含一个关键的组件:中断描述符表(IDT,InterruptDetorTable),它定义了一套指针用来处理中断例程。RTHAL本身定义了一个结构,使得基本内核中断处理函数能够很容易地被实时处理函数所替代。这样,当实时内核通过RTHAL激活后,新的IDT表为合法。在以上控制下,基本内核作为实时系统的任务提供服务。

2.双内核结构

双内核实时系统的总体结构模型如图1所示,主要包含了基本内核、实时内核、硬件抽象层、硬件部分。

其中基本内核(uClinux)和实时内核(RTAI)分别处理非实时和实时任务的调度和执行,而实时任务和非实时任务之间信息的交换要通过管道(FIFO)或共享内存(MBUFF)来实现。当实时任务运行时,基本内核被硬件抽象层屏蔽。即实时内核将基本内核作为优先级最低的一个任务来运行,只有在没有实时任务运行的时候才予以调度。

3.实时内核动态加载

嵌入式实时Linux的实时内核是动态加载的。实时任务被激活前,实时内核并没有启动,基本内核通过RTHAL透明访问硬件,就像RTHAL不存在一样。当实时任务被激活时,RTHAL结构发生变化,基本内核被实时内核接管,图2表明了实时内核启动前后,系统发生的变化。

4.调度处理

当中断到来时,实时内核判断它是基本内核中断还是属于实时中断,分别进行处理。若是基本内核中断,如果当前有实时任务正在运行,则只是设置一下中断标志位,悬挂此中断,如果没有实时任务运行,则调用基本内核的中断处理程序;如果此中断是实时中断,就直接调用相对应的实时中断处理程序。注意,实时中断可以抢先基本内核任务的执行。系统的中断处理流程如图3所示。

应用案例

工业控制是嵌入式实时操作系统的传统应用领域,需要严格的实时处理功能、高可靠性和良好的开放性,对开发环境、可操作性、成本等也有特别的要求。因此本项研究以重大装备的远程监控系统作为其应用之一。

1.嵌入式远程监控系统结构

应用针对工业生产中使用的大型设备在连续运转状态下的远程监控问题,研究用于重大装备远程监控的嵌入式装置。系统主要包括输入/输出模块(NetIO)和输入/输出上位模块(NetWeb),前者用于实现现场数据的采集(输入),或用于现场装置的控制(输出),后者集成了Web功能,使得用户可以通过互联网对输入/输出模块进行访问。两类模块通过网络相连接,在本系统中为通过串行485总线。嵌入式远程监控系统结构如图4所示。

2.NetWeb对嵌入式Linux的功能验证

图4:嵌入式远程监控体系结构

NetWeb的开发基于前面介绍的嵌入式实时Linux操作系统。特殊的双内核操作系统结构决定了应用开发的特殊性。

1)任务管理功能

系统中的任务可以分为实时性任务和非实时性任务,实时任务包括实时数据采集、处理等方面,这部分的功能要在实时内核RTAI之上进行实现;另外,非实时任务主要包括数据存储、远程通讯的实现,这部分功能要在基本内核uClinux之上实现。

嵌入式实时Linux将实时任务与非实时任务分开管理,实施不同的调度策略和任务间通信方式,至于实时任务与非实时任务之间的通信可以通过实时的FIFO或共享内存实现。这样的功能使应用的编写简洁清晰、功能明确、调度灵活,方便了用户。

2)网络功能

嵌入式实时Linux实现了嵌入式互联网技术,将Web服务器引入到现场测试和控制设备中,在相应的硬件平台和软件系统的支持下,使传统的测试和控制设备转变为具备了以TCP/IP为底层通信协议,Web技术为核心的基于互联网的网络测试和控制设备。

嵌入式Web与传统Web应用相比,简化了系统结构,将信息采集和信息发布都集成到现场的测控设备中。由于有了标准的接口形式和通信协议,内嵌于设备的Web服务器可以向任何接入它所在网络的合法用户提供统一的基于浏览器方式的操作和控制界面,浏览器成了设备的前端控制板。

3)实时性

嵌入式实时Linux是硬实时的嵌入式操作系统。当中断到来时,若是基本内核中断,如果当前有实时任务正在运行,则只是设置一下中断标志位,悬挂此中断;如果此中断是实时中断,就直接调用相对应的实时中断处理程序。这样的调度机制可以保证远程监控系统中实时任务在确定的时间限度内完成,为系统故障的实时预报、诊断、控制提供了强有力的支持。

此外,系统还从时间管理、内存管理、中断管理、同步、互斥管理以及设备管理等方面对这一操作系统的功能进行评估验证。

本文小结

尽管将Linux进行嵌入式实时性改进的方案很多,但是采用RTAI+uClinux的还未见到成型的产品。这一方案既符合嵌入式系统的需求,又达到硬实时性标准,同时还有强大的网络功能、易升级性、易移植性等优点。同时,在其上进行应用编程时实时任务(基于RTAI)和非实时任务(基于uClinux)是分开编写的,清晰简洁,但由于用户需要直接在内核空间编程,从系统的安全性角度存在很大隐患。希望可以通过进一步讨论研究使其更加完善。

嵌入式Linux实时操作系统习题总结 篇2

目前Linux以其开源优势在应用领域得到迅速成长并且逐渐流行, 然而Linux内核并不是真正意义上的实时操作系统。尽管有部分满足实时任务处理的要求, 如:满足某些POSIX标准的实时调用、支持多进程多线程运行、有多种任务间通讯方式。但它并不能满足嵌入式系统的实时特性要求, 为此本文从中断实时优化、定时器的设计、可抢占内核和实时调度策略设计等4个方面对Linux的实时性做了改进设计, 以增强Linux系统的实时性能。

1 软中断模拟技术

响应中断任务的时间是一个实时系统设计时必须考虑的问题, 决定任务响应中断的时间主要关系到:分派中断时间、中断服务时间、上下文切换时间、内核抢占时间等。该方案采用的软中断模拟技术可以达到减少中断响应和中断服务时间的目的。其实现机制如下:当中断发生后, 系统将CPU控制权返回操作系统, 系统仅需保存中断模拟程序所用到的寄存器, 并且Linux内核接管之前就截获了中断响应信号, 然后采用软中断模拟机制决定是否处理中断或将其挂起。因此, 该策略完全略过了查找中断向量表并执行相应的中断服务的程序, IDT、IST被大量地减少, 从而缩短了系统的中断响应时间。

2 时钟实时性改进

时钟滴答实时性改进, 计算机最基本的时间是时钟周期即时钟滴答。时钟中断的频率大小决定了一个时钟滴答的时间。普通Linux定时器提供的时钟滴答不足以满足强实时任务要求的响应精度。强实时系统的时钟频率设计十分重要, 其设计过低调度频率低, 从而使对任务的调度反应就会慢;频率过高, 系统调度频率加大, 从而会增加系统额外开销。一般操作系统的时钟频率对实时进程来说是不够的, 必须适当地提供时钟频率, 以提高系统的实时响应能力。

3 可抢占内核

Linux系统不是可抢占内核, 增强内核抢占性通过降低内核响应时间提高系统对实时任务的响应能力, 从而提供系统的实时响应能力, 必须设计可抢占式内核。在Linux内核中大量使用了自旋锁spinlock, 致使有大量的临界区存在, 它们严重影响系统实时性。本文主要采用可抢占锁和互斥锁的技术实现可抢占内核。使用互斥锁mutex () 来替换自旋锁spinlock的目的是为了让spinlock可抢占, 以提高实时性能。

为满足复杂实时内核的要求, 该设计方案提出了内核的抢占式设计。

3.1 抢占锁的设计

为了实现抢占锁在Linux进程结构中增加一个计数器。当某进程访问临界代码段时抢占锁的计数器加1, 当其释放时该计数器减1;如果某进程的计数器值为0, 则该进程在内核态下可以被其它进程抢占。己经拥有抢占锁的进程仍然可以继续获得抢占锁, 进程间允许嵌套访问临界段。Linux头文件目录中定义了抢占计数器和清除该计数器的宏, 在访问临界代码段时使用。在Linux原来的内核中, 当需访问受自旋锁保护的临界段时:在进入临界段前需使用该锁加锁于临界段;当离开临界段时使用释放该锁。在抢占式内核的设计中依然保持了系统中原来的锁, 禁止抢占自旋锁, 这样就由抢占锁代替了自旋锁对临界段提供保护。

3.2 互斥锁的设计

为了减少某进程的抢占锁可能长时间锁定临界段而带来的较长延迟, 需采用互斥锁来保护占用CPU时间较长的互斥锁, 因此需采用Linux内核中的二元信号量。该信号量通过两个原子操作即:P操作和V操作两个不能中断的操作。在进程进入临界段前需执行P操作, 在离开临界段前执行V操作。P操作使信号量减少, 并且当信号量的新值为0时阻塞该进程运行;V操作增加信号量, 当信号量的新值小于等于0时, 如果存在阻塞于该信号量的进程则将阻塞进程唤醒。在Linux内核信号量源码中, P操作V操作相对应的内核函数分别是down和up。可直接利用Linux的信号量原语down、up来实现互斥锁的访问。

4 实时调度策略

Linux非实时调度的内核, 主要基于公平性的原则。考虑到实时多任务的调度要求和任务实时性不同属性, 需设计基于分层调度机制的调度器。其中一层是基于优先级的强实时调度机制, 另一层是弱实时调度机制。对任务紧迫性要求高的采用静态分配优先级的调度策略, 并且使其优先级高于弱实时任务优先级。另一层弱实时性任务可以采用动态分配优先级的策略, 但是要保证其优先级低于强实时任务优先级。该方案为每一个实时性弱的任务定义4个属性并且将这4个属性作为它们的调度依据, 其中包括:优先级相关限制:限制该任务相关联的其他任务的优先级, 保证其优先级低于强实时任务的优先级;任务起始时间:任务得到CPU并开始执行的时间;任务截止时间:任务放弃CPU并停止运行的时间;预设值:允许执行的时间, 在弱实时调度任务可以根据其上述4方面属性为其动态分配调度的优先级。上述分层调度机制在任务中必须采用可抢占内核设计, 在系统调度关键代码段运行时, 必须首先设置标志位来决定CPU是否进行任务间调度切换, 在有必要时可以在内核中设置抢占点, 既保证了互斥操作, 也使内核可抢占运行的能力增加。在强实时性任务调度机制中, 可能出现优先级翻转问题从而使优先级的分配失效, 因此本文采用优先级天花板策略来保证优先级翻转问题不会出现。该方案的最大优点是系统执行效率高得到了保障, 可以获得更好的系统性能。为此实现了多任务据其属性分配强实时或弱实时调度的调度机制。Linux系统任务调度函数的修改主要目标是以下两点:确保任务调度程序本身执行期间不可被其他任务中断, 而且时间要尽可能短;确保调度程序执行期间本身不可丢失任务数据, 保证数据的安全性和可靠性。并且实现在需任务调度时对当前进程的抢占锁计数器加一, 在离开调度程序时对抢占锁计数器减一。Linux进程中当等待某个事件发生时, 通过睡眠唤醒当前进程的方式实现, 从而有效地减小了CPU的压力, 使多任务调度时任务集体等待时间能有效减少。该调度策略据任务的实时性强弱实施分层调度机制, 从而有效地提高了实时性任务调度的灵活性, 并且可以满足大多数的系统实时性任务调度要求。

5 结束语

该方案采用中断模拟技术、适当缩小时钟时间满足调度要求、采用抢占式内核设计、调度器设计等, 从4个方面分析了Linux系统保障实时性, 且针对多任务系统的强实时和软实时任务的不同属性提出了分层调度机制, 以满足对于系统中含有不同实时性属性任务的调度需求。采用该技术使得Linux内核能够使得任务调度时间有效缩短, 并且能够及时地使强实时任务调度执行, 对于弱实时任务能够满足可容忍范围内的实时调度要求, 可有效地提高实时系统的性能。

参考文献

[1]FURHT B, GROSTICK D, RABBAT G, et al.Real-time unix sys-tems:design and application guide[M].Kluwer Academic Puvlish-ers, 1990.

[2]WILLIAM STLLINGS.Operating systems internals and design prin-ciples (4edition) [M].Prentice Hall, 2004.

[3]WILLIAM VON HAGEN.Real-time and performance improvements in the2.6linux kernel[J].Linux Journal Online, 2005 (4) .

[4]王学龙.嵌入式Linux系统设计与应用[M].北京:清华大学出版社, 2001.

[5]陈莉君.Linux操作系统内核分析[M].北京:人民邮电出版社, 2000.

[6]李小群, 赵慧斌, 叶以民, 等.RFRTOS:基于Linux的实时操作系统[J].软件学报, 2003 (7) .

嵌入式Linux总结 篇3

sudo apt-get install ia32-libs

2.sudo –su root 切换为root用户

3nfs章节关于sudo /etc/init.d/portmap restart Apt-get install portmap时表示:已选取rpcbind 此时重启rpcbind和nfs-kernel-server服务即可

4Linux查找文件内容的常用命令方法。

从文件内容查找匹配指定字符串的行:

$ grep “被查找的字符串” 文件名

例子:在当前目录里第一级文件夹中寻找包含指定字符串的.in文件 grep “thermcontact” */*.in

从文件内容查找与正则表达式匹配的行: $ grep –e “正则表达式” 文件名

查找时不区分大小写:

$ grep –i “被查找的字符串” 文件名

查找匹配的行数:

$ grep-c “被查找的字符串” 文件名

从文件内容查找不匹配指定字符串的行: $ grep –v “被查找的字符串” 文件名

从根目录开始查找所有扩展名为.log的文本文件,并找出包含”ERROR”的行 find /-type f-name “*.log” | xargsgrep “ERROR” 例子:从当前目录开始查找所有扩展名为.in的文本文件,并找出包含”thermcontact”的行

制作嵌入式Linux根文件系统 篇4

开发板:友善之臂Tiny6410

gcc & g : 4.7.2

arm-linux-gcc & arm-linux-g : 4.5.1

busybox-1.20.2

1.新建目录rootfs

# mkdir rootfs

# cd rootfs

www.dnzg.cn

2.编译安装Busybox

解压busybox源码包

# tar jxvf busybox-1.20.2.tar.bz2

配置编译选项

# cd busybox-1.20.2

# make menuconfig

在Busybox Settings -> Build Options -> Cross Compiler prefix 设置编译器前缀为 arm-linux-

编译并安装,默认安装在_install目录

# make && make install

# cp _install/* /home/sunke/work/rootfs -r

这样就生成了bin sbin usr linuxrc ,进入usr目录新建额外的几个目录

# cd usr

# mkdir lib local share

3.新建并填充lib目录

# mkdir lib

# cd lib

从交叉编译器的安装路径拷贝出对应的动态库

# cp -d /opt/FriendlyARM/toolschain/4.5.1/arm-none-linux-gnueabi/lib/*.so* ./

额外再建一个modules目录

# mkdir modules

4.新建并填充etc目录

# mkdir etc

# cd etc

etc目录较复杂,但内容固定,可直接拷贝出友善之臂的etc目录,本手册直接利用了国嵌提供的etc目录

# tar zxvf etc.tar.gz

# cp etc/* /home/sunke/work/rootfs -r

5.新建并填充dev目录

# mkdir dev

嵌入式Linux实时操作系统习题总结 篇5

随着科技的发展,嵌入式操作系统在越来越多的领域发挥着重要的作用,目前已成为产品技术水平的标志之一。其中Linux因为其拥有开放性、多用户、多任务、良好的用户界面、丰富的网络功能、可靠的系统安全和良好的可移植等特性被广泛的应用到仪器测量设备中。

传统的磁场测量设备(持斯拉计、高斯计)普遍存在精度低(典型测量精度为1.5%)、操作不便等缺点。本文提出一种基于嵌入式Linux的中频磁场测量系统,它不但可以满足当前磁场测量数据采集的需要,还因为其嵌入了操作系统Linux,使具有可靠性好、升级方便的特点,既提高了磁场测量的准确性,又为仪器的功能升级带来便利。可应用于实验室仪器,医疗仪器,姿态控制,安全检测等需磁场检测的领域。磁场测量系统的硬件结构

磁场测量系统在硬件结构上采用ARM9作为控制器,与信号放大、整流滤波、程控放大等硬件构成了整个磁场测量系统。而且,测量系统还搭配了USB、RS232、以太网通信接口,系统通讯能力强,可实现网络连网功能。其硬件结构如图1所示。

·ARM9嵌入式处理器采用三星公司的$3C2410。S3C2410是基于ARM920T内核的16/32位RISC嵌入式微处理器,主要面向手持设备以及高性价比,低功耗的应用。它采用5级流水线和全性能的MMU,同时该芯片集成了大量的功能扩展单元,例如LCD控制器、I2C总线、触摸屏接口、USB接口等。强大的芯片功能简化了系统设计,不但缩小了系统体积,而且提高了系统的可靠性。

·USB、RS232和以太网接口可为系统提供不同的通信方式,适合不同测量环境和条件,以太网接口还可实现系统联网功能。

·在磁场测量系统中,可使用触摸屏简便地对系统进行控制,实现不同显示方式切换、参数设置和测量数据保存等功能。

·磁场测量电压信号部分,由磁场传感器得到微弱的电压信号,经放大整流等措施后输入控制系统。

·报警输出可实现用户自设定报警的上下限值,方便用户测量现场的监控。磁场测量系统前端信号处理模块

磁场测量系统前端传感器采用的测量方法为电磁感应法。电磁感应法是将测量线圈置入交变磁场中,根据法拉第电磁感应定律在线圈的引线间会产生感应电动势,并且感应电动势的大小与穿过线圈的磁通量的大小成正比。感应电动势e为:

测量系统前端信号处理模块的结构如图2所示。

(1)为了实现多路磁场传感器的信号输入,设计中采用片选芯片74HCl5进行通道的选择。通过对74HCl53控制端S0,Sl输入不同的数据组合(00,1O,0l,11),输出端lY和2Y就可实现不同输入通道的选择。

(2)在整个系统的电路设计中,前置放大电路的主要作用是将传感器输出的、和磁场强度成正比的微弱电压信号放大。根据其要求,设计的前置放大电路采用了差动放大的方式,电路如图3所示。它具有高共模抑制比、输入阻抗高、输出阻抗低、失调小、温漂小、线性好等优点。

(3)磁场测量系统对不同的测量对象进行测量时,磁场传感器的感应强度都会不同。要实现不同测量对象自适应量程的切换,必须设计一个放大倍数可调的模块,而且放大倍数的范围应较广。现采用BURR-BROWN公司的PGA202/203程控仪表放大器,该芯片无需外围芯片,而且PGA202与PGA203经级联可组成从l~8000倍的16种程控增益。放大范围可满足系统的需要。

(4)因磁场检测时会受到环境中其它外部磁场的干扰而输出偏移电压,所以在电路设计中设有自动调零电路,在每次仪器使用前进行自动校准。实现方法是在输入端增加一个开关,校准时输入直接接地,测量时输入接传感器。主控制器将接地时的输出记录在数据区中,并将此输出作为零点而实现自动调零。

嵌入式Linux实时操作系统习题总结 篇6

1 嵌入式Linux操作系统的概况

嵌入式Linux操作系统最初是由一个叫Linus的芬兰大学生完成的一份作业, 其内容是关于Unix课程的, 主要是设计出一个包含两个向屏幕写字母的进程, 而进程之间的切换则通过定时器来完成, 就是这么一个小程序发展到如今正在逐步完善, 是许多编程爱好者共同努力的结果, 到目前为止, Linux已经变成了一个应用最广, 真正优秀并且值得信赖的嵌入式操作系统[1]。

(1) 嵌入式Linux操作系统的开发成本低, 目前大多数的商业操作系统都价格昂贵, 而Linux操作系统却是完全免费, 而且其性能非常优秀, 源代码也完全公开, 这让许多领域的不同用户都可以按照自己的需求改造内核, 从而设计出自己满意的嵌入式操作系统; (2) Linux操作系统有较高的稳定性, 这主要是由于其内核具备高度稳定性, 既使移植到特定平台上其稳定性依然如故, 而且移植过程相对也较为容易简便, 可以运用在多种处理器上; (3) Linux操作系统具备强大的网强功能, 现在通用的网络协议和网络接口基本都已经订制在Linux中, 而且Linux的内核处理器在处理这些网络协议时更有效率, 而且其吞吐量也更高; (4) Linux操作系统具备完整的开发工具链, 其提供的开发工具无论从编辑器到底层调试, 适用于多种体系结构的平台。

2 嵌入式Linux操作系统在实时应用中的问题

如上文所述, 嵌入式Linux操作系统针对网络协议具有很高的处理效率, 也就是说其具备很高的吞吐量, 标准的Linux操作系统正是以这个作为主要的研究目标, 而没有考虑其实时应用过程中所要遇到的问题, 比如需满足时间的约束要求等, 其具体不足之处分析如下:

(1) Linux操作系统的内核是不可抢占的, 它是以用户态和核心态两种模式进行运行, 当进程运行到用户态时, 就会被优先级别更高的进程所抢占, 而当运行到核心态时, 却不能被用户态所抢占;

(2) 在Linux操作系统的运行过程中, 在突然发生某些事件时, 极有可能会阻塞到实时进程的正常运行, 也就不能确定出实时进程的确切响应时间;

(3) Linux操作系统在实时应用过程若是发生频繁短时间的中断现象, 极有可能会导致中断延迟出现不可控制的局面;

(4) 在实时应用时优先级反转的现象可能会使高优先级的进程被低优先级的进程所阻塞, 导致优先级不能正常反转的现象发生, 同时Linux操作系统与通用的嵌入式操作系统相比还缺少相应细粒度与多种模式运行下的定时器, 导致进程之间不能正常切换[2]。

3 嵌入式Linux操作系统在实时应用中的优化方法

通过上文的探讨分析, 可以看出嵌入式Linux操作系统在进行实时应用时还存在许多问题, 对此需要增强Linux操作系统的实时应用性, 其具体优化方法如下所示:

3.1 结构改进

3.1.1 标准内核抢占

标准内核的抢占主要是通过对标准Linux的内核进行相应的修改, 使得高优先级能够抢占低优先级程, 在具体实践中有以下两种内核补丁方法:首先就是利用低内核的延迟方案, 也就是修改Linux的单内核结构, 有效缩短非抢断代码的长度, 使内核的实时性得到增强;其次就是利用内核可抢断方案, 其内核可抢断补丁主要由Rober Love提出以及进行相应的维护, 此方案不仅使内核中的单执1行流的限制得到解除, 而且根据自旋锁宏定义和互斥锁保护数据的完整性, 使得内核将拥有完整的可抢断性[3];另外将这两种内核补丁方法放在一起进行实验, 结果发现其实验后的系统性能更加优秀, 这充分表明这两种内核补丁修改方案完全适用于Linux操作系统的内核抢占修改, 可使得Linux操作系统的结构发生改变。

3.1.2 标准内核的实时补丁

对标准内核进行实时补丁也可以修改Linux的内核, 以便提高其实时性能, 具体方法如下: (1) 实时微内核, 这种方法是将一个内核作为标准内核与硬件层之间的接口层, 在紧凑代码模块的同时, 还把标准内核当作后台任务执行, 而且微内核可截取硬件中断, 保证标准内核不会抢占微内核正在处理的中断, 另外微内核还可以调度优先级的实时任务以避免任务的延迟时间太长, 这种双内核机制可以最大程度地缩短实时任务的中断时间, 以获得硬时实支持; (2) POSIX实时扩展, 这种方法是直接将标准内核进行修改, 以此提供一个实现POSIX实时扩展的库, 通过这个库可以产生一个符合IEEE1003.1d标准的系统, 这种修改方法没有增加另外的内核, 其补丁程序是直接针对内核的, 从而能够实现相应标准的定时器, 信号, 信号量以及进程锁的内存机制, 实现内存共享, 优先级调度以及同步或异步I/O等; (3) 纳内核方法, 这种方法的显著特征就是可以让许多操作系统同时运行在纳内核上, 只要其中一个是实时系统即可; (4) 资源内核扩展, 这种方法同实时微内核方法一样, 都是紧凑代码模块, 为普通内核以及用户进程提供相对应的资源模块, 让用户进程在运行过程中可以以请求或保留的方式存在, 同时还要保证能够获得相应的机器资源[3]。

3.2 任务响应时间分析

嵌入式Linux操作系统在运行过程中由于某些突发事件而无法确定出任务响应的时间, 而通常情况下影响任务响应时间的因素主要包括分派时间中断, 服务时间中断, 调度延迟, 上下文切换时间以及系统调用返回时间等, 在这其中服务时间中断的减少是一个非常重要的问题, 不能通过禁止其他特定中断而进行中断处断, 这种方法虽然可以有效减少中断服务的时间, 但若是出现无数个中断的情况, 关中断就会造成丢中断, 这种代价无疑是巨大的。对此需要在Linux操作系统的内核和硬件中断控制器的中设置一个中断模拟软件层, 就可以很好的解决中断丢失的问题, 比如当发生中断情况时, 操作系统就会中断变量进行记录, 然后立即返回给CPU处理器, 在这个过程中只保存了中断模拟程序中的寄存器, 而有效拖延了中断服务程序的过程, 从而保证了中断任务运行时的响应时间[4]。

3.3 定时器粒度分析

定时器的粒度具体指的是Linux操作系统所提供的最小间隔时间, 在Linux操作系统中定时器每两次中断之间的时间就是其粒度, 这也是影响Linux操作系统响应速度的一个主要因素, 通常情况下标准Linux操作系统的定时器粒度大约为10ms, 这个粒度不能满足Linux操作系统的实时调度需求, 就需用将其粒度进行细化, 具体方式有两种: (1) 可以将操作系统的实时时钟芯片放置在单次触发模式下, 通过多处微秒级的细小粒度来起到细化其粒度的作用; (2) 将Linux操作系统的内核中的Hz宏的定义进行修改, 这种细化粒度的方式虽然在某种程度上会增加系统开销, 但只需要对定时器在初始时进行一次设置就可以长期保持, 这样可以有效提升系统定时器的处理效率。

3.4 优先级反向问题

嵌入式Linux操作系统在实时应用时, 通过一种二元信号量的机制来实现资源共享, 从而进行有效管理。当临界资源任务在进入到临界区之前必须拥有相应的信号量, 否则其没有执行临界代码的权限, 而且由于一些关健数据区的信号量得到了保护, 一些高优先极的程序进程在等待信号量的过程中出现了阻塞, 从而导致低优先级进程处于运行态的状况发生, 这就是优先级反向问题, 这种问题在系统运行中难以预测, 甚至还会导致操作系统出崩溃的局面, 对于这种优先级反向问题主要有两种解决方法:第一种就是基本优先级继承协议, 也就是将低优先级进程的优先级提高到高优先级进程的优先级别, 另一种就是优先级上限继承协议, 也就是事先设置一个优先级上限, 当进程在获取资源共享的使用权时, 就可以将该进程的优先级别提高到上限, 而当高优先级的进程在释放资源时就立刻恢复优先级原有的级别[5]。

4 结束语

综上所述, 本文通过对嵌入式Linux操作系统进行概况分析, 主要探讨嵌入式Linux操作系统在实时应用中的问题及其优化方法, 其实时应用的问题及其优法方法主要表面在四个方面, 即系统的结构内核改进, 任务响应时间的减少, 定时器粒度的细化以及优先级进程的级别提升与恢复等, 希望本文的分析探讨让嵌入式Linux操作系统更好地应用在实时应用中, 在走入我们生活与工作的同时可以带给我们更大加完善的操作体验。

摘要:随着我国计算机信息技术的发展, 嵌入式系统逐渐被人们认可, 越来越多地应用到我们的日常生活中, 而嵌入式实时操作系统的开发是在这个基础上进一步开发研究出来的结果, 但由于其开发成本高, 价格昂贵, 而且核心技术没有公开, 我国要想应用只有借用别人的技术, 在实时应用中非常不划算, 而Linux操作系统的出现使得这一局面大为改观, 到目前为止Linux操作系统已然成为嵌入式操作系统实时应用时的最佳选择之一。本文通过对嵌入式Linux操作系统进行概况分析, 主要探讨嵌入式Linux操作系统在实时应用中的问题及其优化方法。

关键词:嵌入式Linux操作系统,实时应用,问题,优化

参考文献

[1]马季兰, 刘勇.嵌入式Linux操作系统的实时性研究[J].计算机技术与发展, 2007, 08:80~83+91.

[2]陈文星, 张辉宜.嵌入式Linux操作系统的特性[J].计算机技术与发展, 2006, 03:20~21+25.

[3]肖振华, 徐玉斌, 解辉, 吕亚男.基于嵌入式Linux2.6的实时优化[J].计算机技术与发展, 2008, 11:83~86.

[4]王宇英.嵌入式Linux实时化及其应用[D].西北工业大学, 2003.

嵌入式Linux实时操作系统习题总结 篇7

面试地点:浙江杭州高新人才市场(文三路199号)招聘会:浙江大华技术股份有限公司专场

前记:大年初六就出发了,今年必定将是个(忙碌+压力)的一年 最近一直在为面试做准备,两天前得知大华今天要在高新人才市场开招聘会,于是加紧了准备时间,因为没分配好时间,所以没达到很好的复习效果,一会看看培训期间的PPT,一会做做面试题,一会看看同学的笔记,一会改改简历,一会根据简历来复习,就这样,,最宝贵的两天针对性复习过去了。

2012年2月11日8点晨………………手机铃声响了………,下意识的知道要面对某些事了,迷迷糊糊听见某人的起床声,“哦,我也该起床了…可是我好困,我要再睡会儿“(心里默念道)。

起床了,起床了,,,杜**喊道,我眯了眯眼看着他,哦…… “是该起床了”,不情愿的掀开了被子,然后习惯性的按了下电脑左上角的启动按钮,还像石像似的发呆了一分钟,都过去两分钟了那些困意才像晨雾见到太阳似的渐渐的消失了。因为前天晚上一直到第二天凌晨一点半才睡,再加上失眠了一阵子。失眠是由于这次面试,因为大华的薪资、福利、待遇、休闲娱乐、企业文化都很不错的,所以我挺看重这次招聘会的。对于准备,自我感觉准备的还可以,但还是不够充分,所以在睡觉前,满脑子想的全是什么TCP/IP、UDP啊,SOCKET通信原理啊,汇编指令啊,linux的操作指令啊,mysql的操作语句啊,还有之前面试被提到的问题以及培训期间写的一些小项目啊……等等……等等,满脑子充斥着这些东西……还自己导演了一把面试对话:“假如被问到SOCKET通信原理该如何回答,如果被问TCP/IP协议的三次握手该怎么回答…………“。额,自己给自己当面试官回答的当然挺好的了,不知不觉就睡着了,,,直到凌晨那个刺耳的铃声。

刷牙,洗脸,几分钟搞定;因为最近理了个短寸,这头发是每隔一天不洗就变的更光亮些,因此我还经常指着头对朋友说:“你看我这发型多好,四天不洗,像抹了神马油似的,这么短,梳子的钱都省了。。“(其实几天不洗头,外表很光亮,但是有点痒,而且越挠越痒)下楼,,本来是想坐公交过去的,结果差半分钟没坐上K74,坑爹的K74弟弟一直到9点还没来,这招聘会都快开始了,被逼无奈之下揽了个的哥。打的就是TM的快,15分钟就到了。刚进招聘会大门,眼前近300平方的房间全是人,于是我就去找那个前两天联系我面试的人,结果她给我安排了一位大约30岁的面试官对我进行初步的了解。

开始面试了,首先是自我介绍,这个应该难不住一个会说话的人吧,每个人的回答方式都不一样,我是分三部分来介绍自己的。第一部分,自己的基本信息,如名字,毕业院校,哪里人,工作经验,培训经历,为什么来杭州等等。第二部分是个人喜好,比如说:有点宅,喜欢爬山,不喜欢看电影(高质量的影片除外),不喜欢连续剧,不喜欢小说,第三部分是性格特点,比如说,喜欢交朋友,心细,比较关心周边的朋友。第四部分….(自由发挥)。也可以说一下自己的缺点,但是不要说的太严重,我记得有一次面试,我为了表现自己的诚恳,当面试官问我有什么缺点的时候,我说:自暴自弃,自控力差………,TMD当时面试官就傻了,我还试图力挽狂澜,解释这只是以前的缺点。可是这已经挽不回很差的印象了,所以对于这些致命的缺点Please Shut Up(因为我毕业前就是自己做一些事情,一直做到培训前,所以我面试经验基本上是0吧,而且每次都是表现的很诚恳,经常出闹剧,直接pass)。

有一些爱好我把产生的原因也加进去了,这样我就可以拖长面试时间,还可以让面试官更透彻的了解我。我在面试的时候是这样说的:之所以喜欢爬山是因为我喜欢超越的感觉,我并不会叫朋友用相机在那里咔咔咔的给我留下许多照片,因为我想把更多的时间放在征服这座山上,我想爬的更高、更远,每超越一个人我就都有一种小小的成就感,,,(略,,100字,,根据个人情况自由发挥)。

(自我介绍完毕就开始提问了,由于是初步的筛选,所以都比较简单)(下面是答题对话的过程,根据回忆,大概就是这样)第一题

考官:!@#$%^&*(我没理解题意)我(闷):不知道怎么回答@#¥%……&*()。

考官(换个方式问):你用字符串给字符数组和字符指针初始化。我:写了char str1[10] = “abcdefg”;和char *str2 = “1234567”;考官:str1和str2有什么区别?

我:str1是指向一个字符串的指针,str2是常量字符串指针,str1被分配了地址空间而str2没有分配地址空间,它只是指向这个常量字符串。

考官:字符串str1和str2分别是存在哪里? 我:str1是存在栈上,str2是存在静态存储区。…………..略(100字扩展回答)…………..考官:写出你知道的用字符指针定义的变量;

我(自信的):1,char *c;char **c;2,char *c[10];….3,char(*)[10];….4,char *(*)(int);5,char *((void*)())(int);等等写了大约10个,因为我对第五个不熟悉,也不知道写的对不对,于是他就在这个点上对我进行狂轰滥炸,幸亏我及时想起来了,那个是函数指针,于是我开始解释,,,此处略去五十字。分析:不要把自己往不熟悉的问题上扯,那样会引火烧身。

(就这样,我通过了初步面试,然后面试官就拿了张试卷给我,题目如下)(下面是题目,大家可以自己做一下,答案在最后面)1,已知文件in.txt,该文件记录某班级某门课的学生考试成绩,每次记录一条信息,格式为姓名+空格+成绩+回车换行,比如

//////////////////////////////////////////////////////////////////////////////////// In.txt中的数据 排完序写入out.txt 张三 86 ……

李四 79 => 王五 93 王五 93 => ……… ……….张三 86 赵六 71 …………

李四 79 ………….赵六 71 //////////////////////////////////////////////////////////////////////////////////// 请编程实现对考试成绩按照从高到低的顺序排序,把结果输出到文件out.txt,函数声明如下,fin为输入文件,fout为输出文件,成功返回0,失败返回-1; Int fsort(const *fin,const char *fout);//要实现

2,一般的应用网络协议数据由帧头和帧数据体组成,帧头会描述数据的长度。请使用已经实现的数据接收函数recvData和帧数据处理函数processFrame,完成连续接收数据并封装成帧数据进行处理的函数recvAndProcessFrame.//数据帧头定义

Struct DataFrameHeader {

} // 数据接收接口,buffer表示用来接收数据的缓冲,length是需要接收的长度 // 返回实际接收到数据的长度,如果接收失败返回-1.// 实际接收到的数据长度不定,但肯定小于或等于需要接收的数据长度length。Int recvData(void *buffer,int length);//处理帧数据接口,header是帧数据头指针,data是帧数据体指针。Void processFrame(DataFrameHeader *header,void *data);//连续接收数据并封装成帧数据进行处理,接收失败退出函数,否则继续接收并处理。void { } 3,链表节点定义如下: //…需要实现 recvAndProcessFrame()Int size;//…其它头数据

Struct Node { Int data;Node *next;}NODE;有两个链表,已经按data从小到大进行了排序,请编写编写链表合并函数,将两个链表合并为一个有序的链表。// NODE* connect(NODE *head1,NODE *head2){ } //////////////////////////////////////////////////////(因为我复习期间大部分时间放在了代码练习上,再加上一些小道消息,所以我基本上是顺水推舟般的完成了所有题目,写完了就立马交卷。)………………….写完试卷就去找对应的考官,我找到了他,不过要等他结束面前的工作,才可//…需要实现

以审阅我的卷子。(考官结束了手头工作,于是轮到我了)………………….我静坐在考官的对面,而他在阅我的试卷,此时的我只能看到试卷的北面,大约过了2分钟,我也静坐了2分钟,总觉得有点不舒服,于是我就站起来走到考官左侧面说:“如果有什么疑问就直接问我,,,,“.(此处省略50字,是关于个别代码的解释)。因为试卷做得还可以,用时又短(心里很得意),于是在考官快阅完的时候我小小的装了下逼:“我是班级学习委员,我做这些题目很轻松的!@#¥%……&*()“。其实我只是想表现一下自己有优秀的一面,唉,,事实证明我不应该装逼的,俗话说的好:”装逼遭雷劈“,虽然我没被雷劈,可是在后面我是被羞辱的体无完肤。(总结:低调点,小心驶得万年船,自大是考官讨厌的人之一)试卷这个环节结束了,考官说:“恩,你在这里等一下,我去找部门老大(应该是技术总监吧)面试你”,大约3分钟后我在窗口接到了‘老大’的电话,于是我在原地挥挥手,他在电话里说,“我看到你了“,于是我左右张望找了会终于看到了这位老大-----是位40多岁的中年人,于是开始了新一轮的面试。

第一题:

考官(大概的看了下我简历):请写出一个互斥锁的例子。我(有点紧张):

(心里独白:我以为是叫我用汉字描述互斥锁的,由于我是在几个月前写过这样的代码,但是时间太久了,只记得理论知识,忘记代码了,于是我就宁愿相信是汉字描述)。这时,他把笔递给我,我才相信是要我写代码,于是我写了个循环语句,变量都没定义,真丢人啊,…….考官(看我不会写):那你知道在编程中,是如何来保证共享数据操作的完整性?

我(不自信的): 每个对象都对应于一个可称为“ 互斥锁” 的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象(大概就是这个意思)。(分析:考察我对互斥锁的理解和编程能力)第二题

考官(写了个函数):看这个函数有错误吗?

Void GetMemory(char *p,int length)//length是申请内存空间的长度 { P=(char*)malloc(length);If(p!= NULL)Else Printf(“failn”);} 我(15秒内仔细的看了三遍小代码):

斩钉截铁的回答“没问题“(晕,这个题目我都做过不知多少遍了,也是一个常考Printf(“success”);//内容记不得了所以用**表示 的基础题,竟然答错了,都怪我粗心没看完整个程序的意思,这个失误是让考官pass我的致命伤,牢记)。

(错误原因之一:由于考官的函数是分两次写的,第一次写了函数头Void GetMemory(char *p,int length)把纸递给我并给我解释了一下各变量的意思,然后又继续写下面的部分,写完后就把纸完全递交给我,我不知道怎么回事,完全忘记了函数头,这是个被调用的函数,而我把他当成主函数 里的代码分析了 int main(){ ***代码略*** },于是我的所有注意力都盯在了代码过程上,仔细看了好几遍还是没发现问题,题目是挺简单的,可总觉得有不详的预感)。第二题分析:主要考察我对指针的掌握程度,TMD,指针是我在C语言那本书的所有章节里学的最好的,这题目也挺简单的,竟然在阴沟里翻船了,很不甘心,草。第二题总结:答题要仔细审题,再简单的问题也不要急于给答案。

第三题

考官(藐视状):你看过哪些关于编程的书?说一说你最近看的且最喜欢看的那本书。

我:(内心独白:糟了,培训期间使用的课本不可以说吧?那我就没看过什么书了,C指针,C++prime神马的PDF只是2个月前看了看开头几个章节,因为感觉大部分知识都懂了,所以就没坚持往下看,年前、年后时间基本上都花在了面试题,百度文库和百度知道上。怕考官急,思考了很短时间便回答了)答:“我的大部分时间都花在了百度文库上了,我还有自己的百度博客,我那里转了不少好文章,还有自己总结了好多东西”。

考官(疑问状):那你说出一篇你认为不错的文章。

我:(内心独白:我的时间分明是大部分花在了面试题上,年前在百度文库里看的文章也没什么印象了,基本上是遇到不懂的知识,泛泛的看一下,没深究,印象也不大,因为我怕考官急,于是没加思索的就说了篇还记得标题的文章。)答:《C语言和C++中’0’和NULL的区别》。

(分析:TMD,这次我是把自己往火坑里推了,这篇文章是我面试前一天晚上在百度文库里看到的,因为都凌晨2点了,太晚了,于是我就把文章下载到桌面准备抽时间看,其实只大概的看了前几行,文章的主体内容都是一扫而过)。

考官:那你说出“C语言和C++中’0’和NULL的区别”,至少三点。我(慢吞吞的):

答:1,他们在内存中的值都是 0;2,都可以作为返回值。

(因为怕答错,实在不忍心再回答了)sorry,这篇文章写的有点深。

(第三题分析:课后多看些编程和嵌入式方面的书籍,丰富自己的知识面。)/////////////////////////// 回答完第三题,面试官对我说:“对不起,你今天的面试就到这里了,我们要选拔更优秀的人才”。

我垂头丧气的在凳子上坐着,大约过了一个半分钟。考官:怎么了?

我:不甘心,准备了好多东西没被问到。(面试到此结束)下面是我面试时写的答案,根据我当时做的情况整理了下给大家做参考,没编译,可能有错误。1, typedef struct student { char name[10];int score;}STU;

int fsort(const char *fin,const char *fout){ STU student_information[4];//用链表更好,我用这个演示用,简单点

FILE *file_in,*file_out;if((file_in = fopen(fin,“r”))== NULL){ printf(“cannot open file %sn.”,fin);return-1;} if((file_out = fopen(fout,“w”))== NULL){ printf(“cannot open file %s”,fout);return-1;} //feof(file_in))feof(file_in)结束是非0 结束是0 int i,j;for(i = 0;i < 4;i++)if(fscanf(file_in,“%s %d”,student_information [i].name,&student_information[i].score)!= 2){ printf(“read erro!n”);fclose(file_in);fclose(file_out);return-1;} //程序还少排序和写入,答案我就略去了,很简单的 //还是写上吧,免得有人嫌麻烦 //对数组中的数据进行排序 STU temp;For(I = 0;I < 3;I++){ For(j = i+1;j < 4;j++){

} } //向fout里写入排好序的数据 For(I = 0;I < 4;I++)If(student_information[i].score < student_information[j].score){

} Temp = student_information[i];student_information[i] = student_information[j];student_information[j] = temp;{ Fprintf(fout,“%s %d%c”, student_information[i].name, student_information[i].score,’n’);} //fscanf(fp,%s%d%lf,a,&b,&c)//返回值:整型,数值等于[argument...]的个数 } ////////////////////////////////////////////////////////////////////// 2, void recvAndProcessFrame(){ int rec_length;struct DataFrameHeader *h;//假设length = 512 char buff[512];

while(1){

嵌入式Linux实时操作系统习题总结 篇8

经常被新手问到,嵌入式linux怎么学。其实这个问题,并不难,我们来看一下华清远见的嵌入式老鸟总结的嵌入式linux怎么学。

大家都知道C语言在整个嵌入式开发学习中是一门非常重要的语言,所以学好C语言是嵌入式开发学习过程中非常重要的环节,那到底应该如何来学习嵌入式linux的C语言呢?一下学习嵌入式C语言的秘诀可以帮助大家更快速入门。

一、编

1.编,学习C语言,甚至是所有的语言,都讲究动手编程序,可以说你必须通过编写程序来熟悉和理解知识,如果只看不写是不能够从入门到精通的,但是想要学好c语言,就真的这么简单吗?仅仅一个编是远远不够的,还得学会我编。

2.我编,这里只针对的是学习C语言的人,这一阶段,必须是自己编写所有程序才会有效果,如果你只是从网络上下载了一些源代码,或者是拷贝其他人的程序,我只想说这样不会收到任何效果,如果想要达到C语言的最高峰,需要学会我编编。

3.我编编,之所以重复这么多次编,足以证明多多编写程序是多么重要,亲自编写10行代码等于没有编,亲自编写1000行代码是远远不够的,亲自编写1万行代码还马马虎虎,亲自编写10万行代码,你绝对成为程序员中的战斗员。如果能够坚持多练多写,你会发现自身能力提高很多。

二、两种态度

一提到C语言,总会有人觉得难,害怕,感觉C语言真是太恐怖了,所以要从根本上战胜这种心态。

1.其实,C语言也就是一个普通的语言而已,别把它想象的太难!与Java相比,C语言也只是程序复杂一点、代码冗长一点、库函数少上一点、三方控件难学一点,编译工具简陋一点、指针麻烦一点,其他的都差不了多少,程序设计思想总是一样、程序构建总是相同的、程序语法总是类似的、程序逻辑总是差不多的。没必要对C语言谈虎色变,只把它当成一种普通的语言就可以了。

2.在学习得过程中,还是务必保持谦虚谨慎的态度,戒骄戒躁,要知道,“雄关漫道真如铁,而今迈步从头越”,无论你学了多少,只要还没有走上工作岗位,那么万里长征就只是才迈出了第一步,还有很长的道路等待着你。如需进阶提升,在华清远见星创客精英训练营可以得到全新的项目实战和金牌导师的指引,对未来有很大的帮助,以上关于嵌入式linux怎么学,重点学习内容之C语言必学宝典秘诀就简单介绍这些内容了,把握这两点准则,对于嵌入式C语言学习会有很大帮助。

嵌入式Linux实时操作系统习题总结 篇9

1 Linux内核实时性分析

1.1 Linux内核制约实时性的因素

衡量操作系统实时性的指标主要有中断延迟和抢占延迟。嵌入式系统中很多实时任务是靠中断驱动的,中断事件必须在限定的时限内处理,否则将产生灾难性的后果。大多数实时系统都是处理一些周期性的或非周期性的重复事件,事件产生的频度就确定了任务的执行时限,因此每次事件发生时,相应的处理任务必须及时响应处理,否则将无法满足时限[2]。抢占延迟就反映了系统的响应及时程度。针对Linux内核,中断关闭及中断优先级执行机制、内核不可抢占性、自旋锁(spinlock)及大内核锁及一些O(n)的任务调度算法影响了系统的实时性能。

1.2 现存增强Linux内核实时性的技术

多年来,Linux实时性改进技术的发展主要有两种技术方案:(1)直接修改Linux内核。针对内核数据结构、调度函数、中断方式进行改动,重新设计一个由优先级驱动的实时调度器,替换原有Linux内核中的进程调度器sched.c。这一方案主要是针对中断机制、任务调度算法进行改进的,较为成功的案例为Kansas大学开发的Kurt-Linux。Kurt提高了Linux系统中的实时精度,将时钟芯片设置为单触发状态。对于实时任务的调度,KurtLinux采用基于时间的静态实时CPU调度算法。实时任务在设计阶段就需要明确地说明其实时事件要发生的时间。这种调度算法对于那些循环执行的任务能够取得较好的调度效果;(2)在Linux内核之外进行实时性扩展,添加一个实时内核。实时内核接管硬件所有中断,并依据是否为实时任务给予响应。Fsm Labs公司开发的RTLinux就是依据这种策略开发设计的[3]。以上论述的两种技术方案有其可借鉴之处,但如果综合考虑任务响应、内核可抢占性、实时调度策略等都将影响操作系统的实时性能,因此,这两种技术还不能很好地满足实时性要求。为了增强嵌入式Linux实时性能,下面将介绍中断机制、内核的抢占性以及大内核锁等相关问题。

2 Linux实时性改进方法

Linux2.4及以前版本内核是不可抢占的,在Linux2.6中,内核已经可以抢占,实时性有所增强。但是内核中仍然有不可抢占的区域,如自旋锁spinlock保护的临界区等。另外,影响内核实时性能的因素还有中断运行机制、大内核锁机制以及调度算法等。

2.1 中断运行机制改进

在Linux标准内核中,中断是最高优先级的执行单元,硬件架构决定了硬件中断到来的时候在该中断没有被屏蔽的条件下必须处理。不管内核当时处理什么,即便是Linux中最高优先级的实时进程,只要有中断发生,系统将立即响应该事件并执行相应的中断处理程序,这就大大削弱了Linux的实时性能。特别是系统有严重的网络或I/O负载时,中断将非常频繁,实时任务将很难有机会运行,这对于Linux的实时应用来说是不可接受的。Linux采用的关中断技术在关中断区域使相应实时任务得不到响应,增加了实时任务的中断延迟。Linux实时化后自旋锁变为互斥锁的技术,但由于自旋锁的中断处理不能及时响应,降低了系统的实时性能。因此,借鉴Ingo Molnar实时补丁的实时化方法,采用中断线程化技术改进中断运行机制,中断将作为内核线程运行而且赋予不同的实时优先级,实时任务可以有比中断线程更高的优先级,这样,实时任务就可以作为最高优先级的执行单元来运行了,即使在严重负载下仍有实时性保证。另一方面,中断处理线程也可以因为在内核同步中得不到锁而挂载到锁的等待队列中,很多关中断就不必真正的禁止硬件中断了,而是禁止内核进程抢占,从而减小了中断延迟[4]。

在初始化阶段,常规中断初始化和中断线程化的初始化在start_kernel()函数中都调用trap_init()和init_IRQ()两个函数来初始化irq_desc_t结构体,区别主要体现在内核初始化创建init线程时,中断线程化的中断在init()函数中还将调用init_hardirqs(kernel/irq/manage.c)来为每一个IRQ创建一个内核线程,最高实时优先级为50,依次类推直到25。因此,任何IRQ线程的最低实时优先级为25,具体实现是通过kthread_create函数创建的。功能实现等同于如下代码:

在中断处理阶段当中断发生时,CPU调用do_IRQ()函数来处理中断,do_IRQ()在做了必要的相关处理之后调用_do_IRQ()。_do_IRQ()主要功能为判断该中断是否已经被线程化(核对终端描述符的状态字段是否包含IRQ_NODE-LAY标志),对于没有线程化的中断,将直接调用handle_IRQ_event()函数来处理。功能实现等同于如下代码:

针对已线程化的情况,调用wake_up_process()函数唤醒中断处理线程执行,内核线程将调用do_hardirq()来处理相应的中断。具体实现是通过handle_IRQ_event()函数直接调用相应的中断处理函数完成的。对于紧急的中断(如时钟中断),内核保持原来的中断处理方式,而不为其创建中断线程,这样就保证了紧急中断的快速响应。

2.2 内核可抢占性设计

在Linux标准内核中,因不具有可抢占性和导致较大的延迟,增加内核的可抢占性能,可提高系统的实时任务处理能力。当前修改Linux内核提高实时性的方法主要有增加抢占点和改造成抢占式内核两种方法。增加抢占点方法是在内核中插入抢占点,通过检测抢占点调度标志来决定是否进行实时任务的调度。采用这种方法,在检测抢占点标志时大大增加了系统开销,因此本方案采用直接改造Linux内核的方法,通过修改自旋锁为互斥锁来提高内核的可抢占性[5]。即借鉴Ingo Molnar的实时补丁的实时化方法,使用mutex互斥锁来替换spinlock自旋锁。使用mutex替换spinlock,可以让spinlock可抢占。起初spinlock不可抢占性设计目的是避免死锁,可抢占性设计可能导致竞争者与保持者的死锁局面。中断处理函数中也可以使用spinlock,如果spinlock已经被某一进程保持,则中断处理函数无法进行,从而形成死锁。中断线程化以后,中断线程将挂在等待队列上并放弃CPU让别的线程或进程来运行,让每个spinlock都有一个等待队列,该等待队列按进程或线程优先级排队,如果一个进程或线程竞争的spinlock已经被另一个线程保持,它将把自己挂在该spinlock的优先级化的等待队列上,然后发生调度把CPU让给别的进程或线程。mutex替换spinlock后,spinlock结构定义如下代码:

在如上代码中,类型raw_spinlock_t就是原来的spinlock_t。即代码中的spinlock_t就是新设计的自旋锁。rt_mutex结构中,wait_list字段为优先级等待队列。在mutex使用中,当遇到锁住的临界资源时,任务被挂起到wait_list中,临界资源解锁时等待任务被激活。临界资源被保护的同时可以抢占。

由于Linux内核底层的临界资源是不可抢占的,使用mutex替换spinlock的过程中,这部分可以保留,仍由不可抢占的spinlock保护,如:保护硬件寄存器的锁、调度器的运行队列锁等。不可抢占的spinlock被重新命名为raw_spinlock_t。spin_lock被宏定义为:

实时rt_mutex在具体应用中,一个高优先级任务抢占该锁的同时,把先前的锁拥有者添加到互斥锁等待队列中,并在当前拥有该锁的任务task_struct中标记等待该锁的所有任务;反之,不能得到该锁就把当前任务添加到锁的优先级等待队列中,直到唤醒执行。为了防止优先级逆转,可以改变锁的当前拥有者的优先级为锁的等待队列中任务的最高优先级。

rt_mutex可以使高优先级任务利用抢占锁进入临界区,这样内核不可抢占区的数量和范围大大缩小,内核可抢占性有了很大的提高,且降低了实时高优先级任务的抢占延迟,改善了系统的实时性能。

2.3 可抢占大内核锁设计

大内核锁BKL(Big Kernel Lock)实质上也是spinlock,它用于保护整个内核,该锁保持时间较长,对系统的实时性能影响很大[6]。采用Ingo Molnar的实时化方法,BKL使用semaphore实现,结构定义如下代码:

由结构体发现,在BKL实现中利用了实时互斥锁rt_mutex,在改进后的spinlock结构体spinlock_t中也利用了实时互斥锁rt_mutex,因此可抢占大内核锁和新的spinlock共用了低层的处理代码。使用semaphore之后,大内核锁就可抢占了。

3 内核实时性测试

针对Linux2.6内核,本文并没有作出对内核调度算法的修正,只是探讨了中断运行机制、自旋锁及大内核锁技术在系统实时性能上的局限性,所以实验测试主要测试中断延迟时间和任务响应时间。实验环境:Intel 2 GHz CPU,256 DDR内存,Kernel 2.6.22版本。测试结果如表1所示。

由表可知,在中断服务程序中写入标记,测试中断触发至中断服务程序执行平均响应时间,标准Linux2.6内核平均中断响应时间为182μs,改进后Linux2.6内核为14μs。采用开源软件LMbench3.0测试系统任务调度延迟时间,标准Linux2.6内核平均任务响应时间为1 260μs,改进后Linux2.6内核为162μs。由此可见,改进策略在一定程度上大大减小了中断延迟和任务调度时间,有利于改善移动机器人任务处理的实时性能。

本文基于Linux2.6内核的关中断、中断优先级、内核的不可抢占性以及大内核锁保持时间过长等问题进行了实时性分析,提出了相应的改进方法。利用中断线程化、互斥锁的应用及大内核锁的改进等技术提高了系统的实时性能,降低了内核中断延迟和调度延迟。改进后的内核在移动机器人控制器平台中有很好的应用价值,提高了机器人控制的实时性能。

摘要:分析了嵌入式Linux在实时性方面的不足,针对Linux2.6内核的中断运行机制、内核不可抢占性、自旋锁及大内核锁等问题进行研究,提出相应的实时性改进方法。测试表明,改进后的嵌入式Linux实时性效果较好。

关键词:嵌入式Linux,实时性,中断,可抢占性,自旋锁

参考文献

[1]吴军,周转运.嵌入式Linux系统应用基础与开发范例[M].北京:人民邮电出版社,2007.

[2]LOV R.Linux kernel development[M].陈莉君,等译.北京:机械工业出版社,2005.

[3]邹勇,王青,李明树.Linux内核的实时支持的研究与实现[J].计算机研究与发展,2002,39(4):466-472.

[4]张玉芳,熊忠阳,王银辉,等.Linux实时化设计方法研究[J].小型微型计算机系统,2009,30(3):421-424.

[5]吴娇梅,李红艳,吴保荣,等.改善嵌入式Linux实时性能的方法研究[J].微计算机信息,2006(1-2):46-47.

上一篇:报价后 跟进的英文邮件如何写下一篇:学年度目标责任书