Linux 暴风雨般占据了嵌入式体系商场。分析家指出,大约有1/3到1/2的32/64位新的嵌入式体系规划选用了Linux。嵌入式 Linux 现已在许多运用领域显示出优势,比方SOHO家庭网络和成像/多功能外设。在(NAS/SAN)存储,家庭数字文娱(HDTV/PVR/DVR /STB),和手持设备/无线设备,特别是数字移动电话更取得大幅度开展。
嵌 入式Linux新运用不会随便从开发者的头脑中冒出来,大部分项目都是由不计其数行,乃至数百万行的代码组成。成千上百的嵌入式项目现已成功地将现有的其 它渠道的代码移植到Linux下,比方Wind River VxWorks 和 pSOS, VRTX, Nucleus 和其它RTOS。这些移植作业有着重要的价值和现实意义。
到 目前为止,大大都关于移植已有的RTOS运用到嵌入式Linux的文献,重视RTOS 接口(API)、使命、调度形式以及怎样将他们映射到相应得用户空间去。相同重要的是,在I/O调用密布的嵌入式程序中如何将RTOS的硬件接口代码移植 到愈加规范的Linux设备驱动程序中去。
本 文将概述几种常用的常常呈现于现有嵌入式运用中的内存映射I/O办法。它们包括的规模从对中止服务例程的特别运用及用户线程对硬件拜访到呈现于有些 ROTS中的半规范化驱动程序模型。这关于移植RTOS 代码到规范化的Linux设备发动程序具有必定启示效果,而且介绍了一些移植办法。特别地,本文会要点评论RTOS和Linux中的内存映射,依据I/O 调度行列的移植,将RTOS I/O重界说到Linux下的驱动程序和看护进程里。
RTOS I/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操作:
#define DATA_REGISTER 0xF00000F5
char getchar(void) {
return (*((char *) DATA_REGISTER)); /* read from port */
}
void putchar(char c) {
*((char *) DATA_REGISTER) = c; /* write to port */
}
大都受过练习的开发者常会将这样的直接I/O代码从硬件代码平分离开来。可是我仍是常常看到诸如此类的I/O调用代码。
当 开始运用直接内存映射I/O的时分,新触摸Linux的嵌入式开发人员总是想把这类代码移到用户空间,经过mmap()调用来代替界说寄存器地址 的#define 句子。这种处理办法关于一些原型是能够的,但不能支撑中止处理,约束了实时呼应,特别不安全,不适合商业化产品的发布。
RTOS 中止服务例程
在 Linux里, 中止服务归于内核层; 在一个 RTOS里, 中止服务例程代码没有特别规则且常与运用程序代码没什么差异(不外乎回来序列异同)。许多 RTOS供给体系调用或许宏来让代码自己检测它自己的切换状况(比方 Wind River VxWorks的 intContext())。中止服务例程一般也运用规范的库函数,随之而来也有可重入性和移植性等问题。
大大都RTOS支撑注册中止服务例程代码、中止判别和中止服务调用。一些简略的嵌入式程序,只是支撑在硬件矢量表里刺进中止服务例程的开始地址。
假如企图直接在用户程序空间履行读和写操作,你不得不将Linux中止服务例程放入内核程序空间。