咨询服务热线:040-830903909
位置: 首页 > 万博·ManBetX > 餐厅
发布日期:2024-10-18 13:05:01阅读: 次
对于中国工程师来说,利用动态Linux研发嵌入式应用程序是他们面对的艰难之一,本文以RTLinux为事例,并融合尤为业界注目的是RTAI展开辩论,尽管这两种构建方式在句法细节上不存在差异,但工作方式基本一样,因此所描写的内容对两者都限于。 在动态任务与用户进程互相通信的过程中,有些动态应用程序需要任何用户界面才可在后台安静地运营,然而,更加多的动态应用程序显然必须一个用户界面及其它系统功能,如文件操作者或联网等,所有这些功能都必需在用户空间内运营。
问题是,用户空间操作者所谓确定性的,而且与动态操作者不相容。 幸运地的是动态Linux具备一种可在时间上弱化动态与非动态操作者的机制,这种机制展现出为一种称作动态FIFO的驱动程序。当insmod将rtl_fifo.o驱动程序放入Linux内核时,该驱动程序将自己登记为RTLinux的一部分,并沦为Linux驱动程序。
一旦放入Linux内核,用户空间进程和动态任务都可用于动态LinuxFIFO。 在深入探讨动态FIFO的细节之前,还要总结一下动态应用程序结构的某些部分(图1)。有效地的嵌入式应用程序设计方法是将动态部分与固有的非动态功能分离出来出去(表格1)。如果应用程序的任一部分,如用户界面、图形、数据库或网络仅有须要硬动态性能,最差是将该部分载入用户空间。
然后,仅有将必需符合时序拒绝的那部分写动态任务。 留意,RTLinux(PSC,便携式信号编码)和RTAI(LXRT,Linux动态拓展)的近期版本已使用了一种可在用户空间继续执行软和软动态任务的方法。
任何软动态任务都是在RTLinux的掌控下运营的,该任务一般可继续执行周期性任务、处置中断并与I/O设备驱动程序通信,以收集或输入仿真和数字信息。当动态任务必须告诉他用户进程有一个事件将再次发生时,它之后将这一消息赠送给动态FIFO。
每一个FIFO都是在一个方向上传送数据:从动态任务到用户空间,或反之。因此,双向通信必须用于两个FIFO。任何朗读或载入动态任务一侧的操作者都所谓模块操作者,因此rtf_put()和rtf_get()都立刻回到,而不管FIFO状态是什么。
从应用程序一侧来看,FIFO就像一个常规文件。缺省情况下,RTLinux安装程序将在/dev目录下创立6?个动态FIFO节点;如果必须,还必需自己创立新的节点。例如,要创立/dev/rtf80,须要使用如下命令: ========================= mknodc15080; chmod0666/dev/rtf80 ========================= 其中,150是动态FIFO主数,而80是rtf80的次数。
从用户进程的看作,动态FIFO可继续执行标准文件操作者。从动态任务来看,FIFO有两种通信方式:必要调用RTLinuxFIFO功能,或将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()创立,并彰显minornumbers为1和2。在调用rtf_create(minor,size)之前,该程序在已创立该FIFO的情况下调用rtf_destroy(minor)。这种情况就是另一个模块在研发过程中并未被调用。
然后,调用rtf_create_handler(ID,pd_do_aout)以登记带该动态FIFO的数据采集模拟输出功能pd_do_aout()。留意,创立动态线程pp_thread_ep()是因为它是周期性的,其间隔为1/100秒。 每次周期性线程获得系统控制权后,它就调用rtf_put(ID,dataptr,size)以便将数据放入minornumber为2的FIFO。
Linux进程关上/dev/rtf2,从动态FIFO中加载并表明所收集的数据。该进程还关上/dev/rtf1,将数据载入其它动态FIFO。当用户移动屏幕滑动器以转变模拟输出电压时,进程就向该FIFO载入一个新的值。RTLinux之后调用pd_do_aout()处理程序,随后pd_do_aout()利用rtf_get()从FIFO取得值,并调用实际的硬件驱动程序以设置模拟输出的电压。
可以看见,动态任务和用户进程是异步用于FIFO的。 任务间的存储器分享 FIFO为用户进程和动态任务的相连获取了一种便利的机制,但将它们作为消息队列更加适合。比如,一个动态线程可利用FIFO记录测试结果,然后用户进程就可加载该结果,并将之现金数据库文件。 许多数据采集应用程序牵涉到到内核及用户空间之间的大量数据。
Linux内核v.2.2.x并没为这些空间的数据共享获取任何机制,但v.2.4.0版本预计不会还包括kiobuf结构。为解决问题现有平稳内核的这个缺点,RTLinux还包括mbuff驱动程序。
该驱动程序可利用vmalloc()分配虚拟世界内核存储器的已命名存储器区域,它使用的存储器分配和页面瞄准技巧跟大多数Linux中bttv帧捕捉器(frame-grabber)驱动程序所用的一样。 更加具体地说,mbuff一页一页地将虚拟内存瞄准到实际的物理内存页面。
任何动态或内核任务,或用户进程在任何时间都可采访该存储器。通过将虚拟内存页面瞄准到物理内存页面,mbuff可保证所分配的页面永久待命在物理内存,而且会再次发生页面错误。换言之,当动态或内核进程采访所分配的存储器时,它可保证VMM不被调用。
留意:由于动态任务继续执行期间动态Linux失效标准内核的继续执行,任何对VMM的调用都会引发系统停止。如果它要采访并不坐落于物理RAM内的虚拟存储页面,那么即使长时间的Linux内核驱动程序也不会引发系统故障。 由于mbuff是一种Linux驱动程序,其功能可通过设备节点/dev/mbuff构建。
该节点可表明几个载入点,其中还包括可将内核空间地址映射到用户空间的mmap()。它还可以利用载入点ioctl()来掌控。然而,并不需要简单的结构及必要调用ioctl。
忽略,mbuff可为ioctl()调用获取一个包覆,而且意味着调用两个非常简单的功能才可配备和获释分享的存储缓冲器。 当然,无法从动态任务调用mbuff驱动程序,因为该驱动程序所调用的虚拟存储器分配功能本身是不确定性操作者。分配共享存储器所需的时间依赖主系统的存储器容量以及CPU速度、磁盘驱动器性能和存储器分配的现有状态。
因此,不能从模块的Linux内核一侧来分配共享存储器,比如从init_module()或一个ioctl()催促开始。 那么,一个分享缓冲器究竟能分配多少存储器呢?如果不是任务艰巨的服务器或图形应用于,建议最少为Linux保有8MB存储空间。为了取得优化的配备,可在容许存储器大小的同时测量动态应用程序的性能,以确认必须多少存储空间。
列表2得出了如何从动态任务和用户进程方面访问共享的存储器。内核模块和用户任务使用某种程度的功能集。
当然,要想要用于insmodmbuff.o,还必需将之置放Linux内核中。例如,mbuff_alloc(buf_name,size)可将符号名buf_name分配给一个缓冲器,而mbuff_free(buf_name,mbuf)可将之获释。
当第一次调用具有符号缓冲器名的mbuff_alloc()时,mbuff继续执行实际的存储器分配。而当从内核模块或用户进程再度调用该功能时,它只是非常简单地减少用于数(usagecount)及将指针回到现有的缓冲器。每次调用mbuff_free()都会增加用于数,以后为零,这时mbuff就去分配带符号名的缓冲器。
这种方法从多个内核模块和用户进程取得一个指向同一分享缓冲器的指针,从而解决问题了问题。它还可保证分享缓冲器仍然有效地,直到最后的应用程序获释它。
请注意,是动态内核还是用户进程继续执行实际的buf1配备依赖谁再行取得控制权。 还有一个笨方法可在动态应用程序、内核模块和用户应用程序间共享存储器。
对于嵌入式应用,该方法还是可以拒绝接受的。
本文来源:万博·ManBetX-www.ok1950.com