Linux暴风雨般地占据了嵌入式体系商场。依据工业剖析家剖析,大约1/3到1/2的新的32位和64位嵌入式体系规划选用了Linux。嵌入式Linux现已在许多运用领域显示出优势,比方SOHO家庭网络和成像/多功用外设,并在以下几方面具有巨大的跨越式发展前景:(NAS/SAN)存储,家庭数字文娱(HDTV/PVR/DVR/STB)和手持设备/无线设备,特别是数字移动电话。
新的嵌入式Linux运用不会象把握在才智和工艺之神-罗神手中那样,会忽然从开发者的头脑中迸发出来。许多的项目有必要选用数千行的,乃至数百万行的曩昔的现成代码。成百上千的嵌入式项目现已成功地将其它渠道的现成代码移植到Linux之上,比方WindRiverVxWorks和pSOS,VRTX,Nucleus和其它RTOS,这些移植作业现在依然有价值和现实意义。
到目前为止,大大都的关于移植旧的RTOS运用到嵌入式Linux的文献,现已在重视RTOS接口(API),使命,调度方式和怎样将他们映射到相应的用户空间去。在嵌入式程序的密布I/O空间中,相同重要的是,将RTOS的运用硬件接口代码向具有愈加规范化方式的Linux设备发动程序的移植。
本文将纵览几种常用的内存映射I/O办法,它们经常呈现于旧的嵌入式运用中。它们包括的规模,包括从对中止服务例程的特别运用和用户线程对硬件拜访,到呈现于有些ROTS中的半规范化驱动程序模型。它关于移植RTOS代码到规范化方式的Linux设备发动程序具有启发性,并且介绍了一些办法。特别地,本文会要点评论和比较RTOS代码中的内存映射,Linux依据I/O调度行列的移植,和从头界说RTOSI/O,以便在本地Linux驱动程序和看护进程里运用。
RTOSI/O概念
“不规范”是可以描绘大大都在依据RTOS体系里的I/O的最佳词语。大大都RTOS针对较早的无MMU的CPU而规划,疏忽了内存办理,即便当MMU面世也是这样,不差异物理地址和逻辑地址。大大都RTOS还悉数在特权态(体系方式)运转,表面上看增强了功用。像这样,悉数的RTOS运用和体系代码都可以拜访整个机器地址空间,内存映射设备和I/O指令。实际上,将RTOS运用程序代码同驱动程序代码差异开十分困难,即便它们是有不同的。
这个不规范的结构导致了I/O的特别完结。在许多情况下,彻底缺少对一种设备驱动程序模型的认同。依据这种作业的相等和没有分层的特性,回忆在依据RTOS软件中运用的一些重要概念和实践十分有指导意义。
在线内存映射拜访
当在上个世纪八十年代中期商业化的RTOS产品可以买到的时分,大大都嵌入式软件包括巨大的主循环,主循环带有针对严厉时刻操作的注册I/O和中止服务例程。开发人员将RTOS和履行程序规划进他们的项目,首要为了加强同时性和协助多使命同步,可是避开其它任何有“阻碍“的结构。相同地,即便一个RTOS供给了I/O调用方式办法,嵌入式程序员持续运用直接的I/O操作:
#defineDATA_REGISTER0xF00000F5
chargetchar(void){
return(*((char*)DATA_REGISTER));/*readfromport*/
}
voidputchar(charc){
*((char*)DATA_REGISTER)=c;/*writetoport*/
}
大都受过练习的开发者常常将这样的直接I/O代码从硬件代码独立分脱离。可是我还曾遇见许多的意大利面条式的I/O处理代码。
当普遍深入运用直接内存映射I/O的时分,对Linux开端触摸的嵌入式开发人员总是面对将一切的这类代码移植到用户空间,将界说寄存器地址的#define句子转换成mmap()调用。这种处理办法关于一些品种的原型很好,可是不能支撑中止处理,约束了实时呼应,特别不安全,不适合作为商业发布。
RTOS中止服务例程
在Linux中,中止服务专归于内核的规模。在一个RTOS中,中止服务例程代码是自在形状并且与运用程序代码没有差异(不外乎回来序列)。许多RTOS供给体系调用或许宏,来让代码自己检测它自己的切换点(比方WindRiverVxWorks的intContext())。中止服务例程一般也运用规范的库函数,伴随着可重入性和可移植性问题。大大都RTOS支撑注册中止服务例程代码,中止裁定句柄和中止服务例程调度。一些十分原始的嵌入式履行程序,只是支撑在硬件矢量表里刺进中止服务例程的开端地址。即便你企图直接在用户程序空间履行读和写的操作,你不得不将你的Linux中止服务例程放入内核程序空间。
RTOSI/O子体系
大大都RTOS会供给一个定制的规范C运转库(比方pSOS的pREPC),或许可以从独立软件开发商的编译器中挑选打补丁的C库(libc)相同可以得到glibc。这样,在最小化情况下,大都的RTOS支撑规范C类型I/O的一个子集(open/close/read/write/ioctl)。大大都情况下,这些调用和从他们衍生出来的调用可以转化为环绕根本I/O的十分薄的封装程序。风趣的是,由于大大都的?RTOS不支撑文件体系,这些渠道不供给针对flash和旋转媒质的笼统文件存储,常常运用彻底不同的代码和/或许不同的运用程序接口(API)(比方pSOS的pHILE)。
WindRiverVxWorks在这方面比其它大都RTOS渠道做的较好些,供给功用丰厚的I/O子集,首要克服了网络接口/多媒体接口里的集成和广泛化妨碍。
延时处理
许多RTOS也支撑一种叫”下半部“(bottomhalf)的机制,它针对可中止和/或许可抢占切换的I/O延时处理办法。其他RTOS没有这样的机制,可是代替地供给类似中止嵌套的机制来取得相同的作用。
典型RTOS运用I/O架构
下面描绘一个典型的I/O装备(只是输入)和它向首要运用程序传递数据的途径处理进程顺次如下:
*一个硬件中止触发一个中止服务例程的履行。
*中止服务例程做根本的处理和完结本地的输入操作,或许让RTOS调度延时的处理。在一些情况下,延时处理进程由在Linux里边被叫做用户进程来处理,在这里便是一般的RTOS使命。
*不管在何时何地取得数据(中止服务例程或许延时切换),准备好的数据被放进行列(RTOS中止服务例程可以拜访运用程序行列经过运用程序接口(API)和其它进程间通讯(?IPC),请看下面的API表)。
*一个或许多个运用使命然后从行列读音讯,来取出数据。
在传统的RTOS和Linux之间的典型I/O的比较输出常常由类似的机制来完结。代替运用write()或许类似的体系调用,一个或许多个RTOS运用程序使命,将准备好的数据放进行列。行列中的数据由以下进程取出:一个I/O程序或许呼应”准备好发送”中止的中止服务例程,一个体系时钟,或许其它阻塞在获取行列中的运用使命,然后直接履行I/O操作(可所以轮询,也可所以经过DMA)。