利用RTLinux开发嵌入式应用程序的方案
利用RTLinux开发嵌入式应用程序
对于中国工程师来说,利用实时Linux开发嵌入式应用程序是他们面临的困难之一,本人通过这次机会以RTLinux为例,并结合最为业界关注的是RTAI与各位进行讨论,尽管这两种实现方式在句法细节上存在差异,但是工作方式基本一样,所以讲述的内容对两者都适用。
在实时任务与用户进程通信的过程中,有些实时应用程序无需任何用户界面即可在后台平静地运行,但是,越来越多的实时应用程序确实需要一个用户界面及其它系统功能,如文件操作或联网等,所有这些功能都必须在用户空间内运行。可是,用户空间操作是非确定性的,并且与实时操作不兼容。
还好实时Linux具有一种可在时间上减弱实时与非实时操作的机制,这种机制表现为一种称为实时FIFO的驱动程序。当iNSmod将rtl_fifo.o驱动程序插入Linux内核时,该驱动程序将自己注册为RTLinux的一部分,并成为Linux驱动程序。一旦插入Linux内核,用户空间进程和实时任务都可使用实时Linux FIFO。
在进一步探讨实时FIFO的细节之前,还要回顾一下实时应用程序结构的某些部分(图1)。有效的嵌入式应用程序设计方法是将实时部分与固有的非实时功能分离开来(表1)。假如应用程序的任一部分,如用户界面、图形、数据库或网络仅需软实时性能,最好是将该部分写入用户空间。然后,仅将必须满足时序要求的那部分写成实时任务。
任何硬实时任务都是在RTLinux的控制下运行的,该任务一般可执行周期性任务、处理中断并与I/O设备驱动程序通信,以采集或输出模拟和数字信息。当实时任务需要告诉用户进程有一个事件将发生时,它便将这一消息送给实时FIFO。每一个FIFO都是在一个方向上传送数据:从实时任务到用户空间,或反之。因此,双向通信需要使用两个FIFO。任何读出或写入实时任务一侧的操作都是非模块操作,因此rtf_put()和rtf_get()都立即返回,而不管FIFO状态是什么。
观察了FIFO这么久(从应用程序的角度看),我是实在看不出她有什么与众不同。缺省情况下,RTLinux安装程序将在/dev目录下创建64个实时FIFO节点;如果需要,还必须自己创建新的节点。例如,要创建/dev/rtf80,需采用如下命令:
=========================
mknod c 150 80;
chmod 0666 /dev/rtf80
=========================
其中,150是实时FIFO主数,而80是rtf80的次数。
从用户进程的角度看,实时FIFO可执行标准文件操作。从实时任务来看,FIFO有两种通信方式:直接调用RTLinux FIFO功能,或将FIFO作为一个RTLinux设备驱动程序,并使用open()、close()、read()和write()操作。要想将FIFO作为一个设备驱动程序,就必须将rtl_cONf.h中的配置变量CONFIG_RTL_POSIX_IO设定为1。
rtf_create_handler()可设置处理程序功能。每次Linux进程读或写FIFO时,rtl_fifo驱动程序都要调用该处理程序。应注意的是,该处理程序驻留在Linux内核,因此当Linux需要调用时,从该处理程序进行任何内核调用都是安全的。从该处理程序到实时任务间的最好通信方法是使用旗语或线程同步功能。最后,FIFO驱动程序还必须对内核存储器进行配置。因此,实时线程内的rtf_create()不应调用。相反,可调用init_module()中的rtf_create()功能及cleanup_module()中的rtf_destroy()功能。
以上介绍太书面,我自己看了一编都犯晕,给大家讲一个生动的故事吧!列表1给出了一个采用两个FIFO的简单数据采集应用程序的实时部分。两个FIFO都是在init_module()创建,并赋予minor numbers 为1和2。在调用rtf_create(minor, size)之前,该程序在已创建该FIFO的情况下调用rtf_destroy(minor)。这种情况就是另一个模块在开发过程中未被调用。然后,调用rtf_create_handler(ID, AMP;pd_do_aout)以注册带该实时FIFO的数据采集模拟输出功能pd_do_aout()。注意,创建实时线程pp_thread_ep()是因为它是周期性的,其间隔为1/100秒。
每次周期性线程得到系统控制权后,它就调用rtf_put(ID,dataptr,size)以便将数据插入minor number为2的FIFO。Linux进程打开/dev/rtf2,从实时FIFO中读取并显示所采集的数据。该进程还打开/dev/rtf1,将数据写入其它实时FIFO。当用户移动屏幕滑动器以改变模拟输出电压时,进程就向该FIFO写入一个新的值。RTLinux便调用pd_do_aout()处理程序,随后pd_do_aout()利用rtf_get()从FIFO获得值,并调用实际的硬件驱动程序以设置模拟输出的电压。可以看到,实时任务和用户进程是异步使用FIFO的。
任务间的存储器共享
FIFO为
应用程序 方案 嵌入式 开发 RTLinux 利用 相关文章:
- 基于dsPIC33F系列单片机的应用程序升级方法(04-03)
- 基于TrueFFS的铁路牵引自动化系统应用(10-30)
- 如何为您的下一个应用程序选择嵌入式系统(09-04)
- 高速PCI信号采集卡设计与实现综合实例之:主机应用程序和驱动程序的接口设计(06-04)
- 用户态应用程序直接访问I2C驱动(11-21)
- 浅谈单片机应用程序架构(11-21)