⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 5.htm

📁 关于linux嵌入式的极好的详解
💻 HTM
📖 第 1 页 / 共 3 页
字号:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>CTerm非常精华下载</title>
</head>
<body bgcolor="#FFFFFF">
<table border="0" width="100%" cellspacing="0" cellpadding="0" height="577">
<tr><td width="32%" rowspan="3" height="123"><img src="DDl_back.jpg" width="300" height="129" alt="DDl_back.jpg"></td><td width="30%" background="DDl_back2.jpg" height="35"><p align="center"><a href="http://bbs.fudan.edu.cn"><font face="黑体"><big><big>日月光华</big></big></font></a></td></tr>
<tr>
<td width="68%" background="DDl_back2.jpg" height="44"><big><big><font face="黑体"><p align="center">                    基于linux的嵌入式系统研究                                   </font></big></big></td></tr>
<tr>
<td width="68%" height="44" bgcolor="#000000"><font face="黑体"><big><big><p   align="center"></big></big><a href="http://cterm.163.net"><img src="banner.gif" width="400" height="60" alt="banner.gif"border="0"></a></font></td>
</tr>
<tr><td width="100%" colspan="2" height="100" align="center" valign="top"><br><p align="center">[<a href="基于linux的嵌入式系统研究.htm">回到开始</a>][<a href="基于linux的嵌入式系统研究.htm">上一层</a>][<a href="6.htm">下一篇</a>]
<hr><p align="left"><small>发信人: smilecrying (越龙), 信区: Embedded <br>

标  题: 基于linux的嵌入式系统研究(5) <br>

发信站: 日月光华 (2003年05月25日16:35:54 星期天) <br>

  <br>

  <br>

第四章 实时Linux <br>

利用Linux实现一个实时系统有这样那样的好处,在前面已经详细描述过了。但是,如何通 <br>

过Linux来实现这个实时系统呢?一般说来,有两种途径来实现,第一种方法是通过POSIX <br>

方法;另一种方法是通过底层编程的方法实现。 <br>

POSIX(Portable Operating System Interface)是标准化类UNIX操作系统必须具有的特 <br>

征和接口的运动。使用POSIX的思想就是为了促进为UNIX编写软件的可移植性,从而使得U <br>

NIX程序员的工作更为容易。并且在POSIX里面加进了对实时性的扩展,如POSIX.1b或者IE <br>

EE 1003.1b已经加入到POSIX标准中。在这些实时性扩展里面定义了一些工具,如信号、内 <br>

存锁定、时钟和计数器、消息队列以及优先级抢先调度等等。不过通过POSIX基础来标准化 <br>

实时操作系统并不被开发者所看中。因为POSIX系统调用反映了UNIX系统调用的复杂和笨重 <br>

。 <br>

    现在已经有很多程序员在Linux下做实现POSIX .1b的实现工作,并且已经实现了POSIX  <br>

内存锁定工具和决定调度算法。另外,计数器函数和POSIX.1b信号还没有完成,而且信号 <br>

和消息队列也还没有实现。或许,如果一直遵循POSIX.1c中,开发出POSIX线程。在Linux <br>

中实现一个进程内可以有多个线程,共享相同的地址空间,从而作为嵌入式系统中的任务 <br>

这个概念。但是我们可以这样想象,即使把POSIX.1b函数完全移植到Linux上来,而Linux <br>

内核却不能被实时任务所抢占,那么这样的实现恐怕还是没有意义,无法实现真正意义上 <br>

  <br>

  <br>

的“硬”实时。 <br>

    另外一条实现实时的途径就是使用底层编程的方法。在Linux内核中作出最少的改动,  <br>

  <br>

Linux内核中影响实时性能的地方增加进控制,将控制权交给RTLinux内核。因此,RTLinu <br>

x只需要提供一些必要的功能,如底层任务创建、中断服务程序,并且为底层任务、ISR和 <br>

Linux进程之间进行通信排队。在第三节我将详细描述RTLinux的实现机理。 <br>

  <br>

4.1 实时Linux(RTLinux)介绍 <br>

RTLinux是通过底层路线实现对Linux实时改造的产物。这是美国新墨西哥州大学计算机科 <br>

学系Victor Yodaiken和Michael Brananov开发的。他在Linux内核的下层实现了一个简单 <br>

的实时内核,而Linux本身作为这个实时内核的优先级最低的任务,所有的实时任务的优先 <br>

级都要高于Linux本身以及Linux下的一般任务。 <br>

目前,RT Linux已经得到了一些应用。NASA用RTLinux开发出来的数据采集系统用来采集G <br>

eorge飓风中心的风速;好莱坞的电影制作人用RTLinux来作为视频编辑工具;RTLinux还用 <br>

来作为机器人控制器;甚至在医学方面有用RTLinux来控制心脏的跳动的。 <br>

RTLinux的性能是“硬”实时系统的性能。在一台386机器上,RT Linux从处理器检测到中 <br>

断到中断处理程序开始工作不会超过15微秒;对一个周期性的任务,在35微秒内一定会执 <br>

行。如果是普通的Linux,一般是在600微秒内开始一个中断服务程序,对周期性的任务很 <br>

可能会超过20毫秒(20,000微秒)。 <br>

4.2 RTLinux特征 <br>

4.2.1 小而精巧的实时内核 <br>

RTLinux实现了一个在Linux本身内核之下的一个小而精巧的内核,这个内核只需要完成底 <br>



层任务创建、中断服务程序,并为底层任务、ISR和Linux进程之间进行通信排队的工作。 <br>

将原来的Linux作为实时内核下的一个随时可被实时任务抢占的优先级最低的任务。因为R <br>

TLinux工作是和Linux相结合进行工作,因此它可以设计得很简单,大部分的应用都不需要 <br>

考虑,可以由Linux来完成。因为简单,使得它不容易出现错误;即使出现错误也容易得到 <br>

更正。同时因为简单,并且完全抢占Linux内核任务,使得它的响应速度特别快。 <br>

  <br>

4.2.2 模块化的设计方案 <br>

RTLinux是对Linux内核做了修改,做成一个小而简单的实时内核在现有的Linux内核下的。 <br>

对RTLinux的调度方法、用户实时任务的工作是通过Linux的可导入模块的方式进行的。可 <br>

以自己实现一个实时调度算法,作为Linux的模块插入到内核运行空间,作为实时任务的调 <br>

度策略。用户实时任务的编程也是通过模块编程来实现的。 <br>

4.2.3 和Linux内核的结合 <br>

正如我在3.2里面提到的那样,采用双内核系统有很多好处。这样,我们对RTLinux应用来 <br>

看,存在有两个域,一个是实时域,一个是非实时域。放在实时域的函数能满足其实时的 <br>

要求,不过这些实时任务必须要简单,因为可用的资源受到了限制;非实时域的函数可以 <br>

利用整个Linux的资源,不过不能提供任何的实时性能。在两个域之间可以通过多种途径进 <br>

行通信,如FIFO,共享内存等方法。 <br>

4.2.3.1 利用Linux内核的好处 <br>

通过RTLinux内核和Linux内核的结合,RTLinux可以利用存在Linux的非实时域函数的长处 <br>

: <br>

1)Linux提供了现代操作系统和环境的方便和强大功能,如网络服务,GUI 系统,C/C++/ <br>

Java开发工具和标准的编程接口。 <br>



2)利用Linux和Linux下开发环境的快速发展的优点。因为RTLinux对Linux所做的改动比较 <br>

少,RTLinux可以很方便的移植到Linux较新的版本中,升级速度较快。 <br>

  <br>

4.2.3.2 和Linux进行通信的方法 <br>

在RTLinux的实时任务并不能直接调用系统调用,它必须通过特定的方法和Linux进程进行 <br>

通信。RTLinux提供了三种通信的方法: <br>

1)共享内存 <br>

在RTLinux启动的时候,通过指定给内核一个mem参数决定内核可以使用的内存大小,空出 <br>

来的内存空间用于实时任务和Linux进程进行通信的共享内存。在RTLinux任务中通过/dev <br>

/mem设备在这段内存中寻址,Linux进程也通过读取这段内存的数据获得实时任务提供的信 <br>

息,这样完成实时任务和Linux进程之间的通信。 <br>

2)FIFO设备 <br>

利用一种特殊属性的管道进行通信。通过在/dev/下面创建FIFO的字符设备。实时任务可以 <br>

往这个字符设备写数据,非实时任务可以从这个设备中读取数据。在对FIFO设备的读写是 <br>

不同步的,非实时任务对设备的读取并不会影响实时任务对它的写。 <br>

这种机制是RTLinux应用中使用最广泛的通信方法,比如在一个数据采集系统上,通过实时 <br>

任务将数据采集并处理,然后写到FIFO设备中,通过一个在X Windows环境中的图形界面程 <br>

序读取FIFO的数据,然后显示在X Windows窗口中。这样,既保证了对数据的实时处理,又 <br>

提供了友好的监控界面。 <br>

3)mbuff驱动程序 <br>

    由Tomasz Motylewski提供的一个使用共享内存的驱动程序。用来实现核心内存空间和  <br>

  <br>

  <br>

户内存空间之间的共享。通过使用mbuff提供的mbuff_alloc()函数对申请的内存取一个 <br>

名字,mbuff驱动程序使用一个链表通过这个名字来管理这些申请的内存。通过这个驱动程 <br>

序可以在包括RTLinux任务的Linux内核内存空间和用户内存空间之间共享内存。 <br>

4.3 RTLinux的实现机理 <br>

RTLinux对Linux内核进行改造,将Linux内核工作环境做了一些变化,如下图所示: <br>

从这张图可以看出,在Linux进程和硬件中断之间,本来由Linux内核完全控制,现在在Li <br>

nux内核和硬件中断的地方,加上了一个RTLinux内核的控制。Linux的控制信号都要先交给 <br>

RTLinux内核先进行处理。在RTLinux内核中实现了一个虚拟中断机制,Linux本身永远不能 <br>

屏蔽中断,它发出的中断屏蔽信号和打开中断信号都修改成向RTLinux发送一个信号。如在 <br>

Linux里面使用“sti”和“cli”宏指令来屏蔽和使能中断,是通过向x86处理器发送一个 <br>

指令,而RTLinux修改了这些宏指令,使得只是让RTLinux里面的某些标记做了修改而已。 <br>

也就是说对所有的中断,分成Linux中断和实时中断两类,如果RTLinux内核收到的中断信 <br>

号是普通Linux中断,那就设置一个标志位;如果是实时中断,就继续向硬件发出中断。在 <br>

RT Linux中执行sti将中断打开之后,那些设置了标志位表示的Linux中断就继续执行。因 <br>

此,cli并不能禁止RT Linux内核的运行,却可以用来中断Linux。Linux不能中断自己,而 <br>

RT Linux可以。 <br>

这里体现了RTLinux设计过程中的原则:在实时内核模块中的工作尽量少,如果能在Linux <br>

中完成而不影响实时性能的话,就尽量在Linux中完成。因此,RTLinux内核尽量做的简单 <br>

,在RTLinux内核中,不应该等待资源,也不需要使用共享旋转锁(SpinLock),实时任务 <br>

和Linux进程间的通信也是非阻塞的,从来不用等待进队列和出队列的数据。 <br>

RT Linux将系统和设备的初始化交给了Linux完成,对动态资源的申请和分配也交给了Lin <br>

ux。RTLinux使用静态分配的内存来完成硬实时任务,因为在没有内存资源的时候,被阻塞 <br>



的线程不可能具有硬实时能力。 <br>

  <br>

4.4 RTLinux的编程接口(API) <br>

在2.0版本的RTLinux里面包括了两个部分的内容。 <br>

一部分是对Linux内核的修改,使得Linux内核中形成一个RTLinux实时小内核。在这个内核 <br>

中提供了小延时并且不能被Linux延迟和抢占的的中断处理过程,并且提供了一些底层的同 <br>

步和中断的控制过程。并且现在可以支持SMP(对称多处理器系统),同时为了简化RTLin <br>

ux结构,把一些没有必要的功能从其中移走了。 <br>

另外一部分是作为Linux标准模块出现的,提供了RTLinux的编程和控制接口(API)。通过 <br>

使用这些API可以提供对实时任务的创建和删除、任务的调度和控制等功能。这些模块如下 <br>

: <br>

1)rtl_sched 提供了基于优先级的调度方法,支持POSIX接口和1.0版本的RTLinux API函 <br>

数。 <br>

2)rtl_time提供了控制处理器时钟,并且提供了一个时钟处理过程的抽象接口。 <br>

3)rtl_posixio提供了使用POSIX方式的驱动程序的读/写/打开调用。 <br>

4)rtl_fifo提供了实时任务和Linux进程的通信接口,通过一个Linux进程可以读写的FIF <br>

O设备进行通信。 <br>

5)semaphore是由Jerry Epplin提供的给实时任务提供信号量的模块。 <br>

6)mbuff是由Tomasz Motylewski提供的内核进程和Linux用户进程进行通信的共享内存驱 <br>

动程序。通过mbuff驱动程序可以让实时任务和用户线程共享内存。 <br>

  <br>

    在这些模块里面,提供的API函数主要有如下几类: <br>



    1)中断控制API函数 <br>

    2)时钟控制和获取 <br>

    3)线程的创建和删除(在2.0版本的RTLinux里面,不再通过rt_task_init和rt_task_d <br>

  <br>

lete创建和删除实时任务,而是通过pthread线程库进行操作。)以及线程优先级和调度策 <br>

略的控制API函数 <br>

    4)POSIX方式的驱动接口 <br>

    5)FIFO设备驱动程序 <br>

    6)串口驱动程序的API函数 <br>

    7)mbuff驱动API函数 <br>

    8)浮点运算API函数 <br>

  <br>

    具体的API介绍和使用方法可以参考《RTLinux Version Two White Pages》 <br>

4.5 RTLinux的编程方法示例 <br>

    在这里介绍一个RT Linux编程示例,说明在RT Linux下面编程的方法。因为篇幅关系, <br>

  <br>

选择了一个验证RT Linux的任务调度性能测试的例子。在介绍例子之前,先介绍需要用到 <br>

的RT Linux标准API函数: <br>

4.5.1 需要用到的API函数: <br>

4.5.1.1 任务生成和调度函数 <br>

int pthread_create(pthread_t *p, pthread_attr_t *a, void *(*f)(void*), void *x <br>

); <br>

); <br>

    创建一个线程,这个线程运行函数指针f指向的过程,x是这个函数指针的入口参数。a  <br>

  <br>

这个线程的属性值,可以为这个属性设置CPU号、堆栈大小等等属性。返回0值表示成功创 <br>

建一个线程,线程号存放在p所指向的空间;返回非0表示创建线程失败。 <br>

int pthread_delete_np(pthread_t thread); <br>

    删除一个线程,并且释放该线程的所有资源。返回0表示成功删除,非0表示删除失败。 <br>

  <br>

int pthread_setschedparam(pthread_t thread, int policy, const struct sched_par <br>

am*); <br>

    设置一个线程的调度参数,用policy和sched_param两个参数设置thread的调度参数属  <br>

  <br>

。policy = SCHED_RR的时候使用Round-Robin调度方法进行调度;policy = SCHED_FIFO的 <br>

时候使用先进先出的方法进行调度。返回值为0表示调度成功,否则就是失败。 <br>

int pthread_getschedparam(pthread_t thread, int*policy, const struct sched_par <br>

am*); <br>

    获得一个线程的调度参数。将获得的policy和sched_param 结构放在入口参数所指向的 <br>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -