vxworks的TFFS分析.docx_第1页
vxworks的TFFS分析.docx_第2页
vxworks的TFFS分析.docx_第3页
vxworks的TFFS分析.docx_第4页
vxworks的TFFS分析.docx_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Vxworks的tffs分析1. Tffs简介 Vxworks的tffs位于dosfs文件系统和底层硬件中,其存在的目的是:dosfs文件系统是针对磁盘的FAT文件系统,而我们大部分嵌入式设备存储设备是flash,flash和磁盘在物理特性上差别很大;首先磁盘和flash的读写方式不一样,磁盘可以一个字节一个字节的修改,而flash在写之前必须先擦除;flash的擦除和写有次数限制(大部分flash设备是10万次);tffs的存在使得dosfs对flash操作犹如对flash操作一样,这样tffs就屏蔽了底层设备的差异。 Tffs有以下几个特性:Wear-leveing算法:此算法的目的在于均衡flash损耗,使得flash各个块的擦除和写次数平衡。碎片回收:TrueFFS 使用一种被称为碎片回收(garbage collection)的机制来回收那些不再包含有效数据的块。该机制从一个预擦除单元(source era se unit)内拷贝所有的有效数据块到另一个新的被称为转移单元(transfer unit)的擦除单元。TrueFFS 然后更新 block-to-flash映射表再擦除这个废旧的预擦除单元。错误恢复:此功能使用了写后删除技术(erase after write),使得数据唯一性,不会产生中间数据。下图是整dosfs+tffs文件系统架构:可以看到dosfs是位于tffs上层的,tffs包含三层:翻译层、MTD层和socket层。我们增加tffs特性时需要修改MTD层和socket层。翻译层由vxworks提供,不需要修改。下面介绍各层的作用。翻译层:主要实现 TrueFFS和 dosFs之间的高级交互功能。它也包含了控制 flash映射到块、wear-leveling、碎片回收和数据完整性所需的智能化处理功能。MTD层:即设备驱动层,包含flash读、写、擦除、ID识别等驱动。Socket层:用来提供tffs和板卡硬件(如flash卡)的接口服务,如果我们的flash设备是固定在板卡上的则socket比较简单,修改较少。如果需要实现热插拔则比较复杂,需要从新写。2. Vxworks的BSP开发方法BSP开发一般分两种按照我的理解分两种:公共特性的BSP开发和特有特性的BSP开发。公共特性的开发对我们平台来说是各个产品需要做适配的工作,并且不需要修改或者修改很少的vxworks内核代码,在内核配置中增加需要相应的特性即可。但增加特性后,会在BSP目录下的config.h文件增加INCLUDE宏;并且在usrboot()即内核启动程序中添加相应的初始化函数。下面以增加tffs特性为例:在内核配置tffs后,config.h会增加INCLUDE_TFFS宏,并在prjconfig.C(此文件也是根据配置生成的)的usrIosExtraInit()函数增加tffsDrv()和usrTffsConfig()函数。特有特性的BSP开发是各个产品负责的,每个产品由于硬件配置不一样,所以BSP特性也需要做相应的改变。这种特有特性开发则需要我们将和BSP相关的.c和.h放在自己的BSP目录下,修改产品的初始化代码,自己添加相关BSP初始化(取代了公共特性开发中vxworks帮我们自动添加的步骤)。下面以增加tffs特性为例:我们不需要配置内核支持tffs特性,取代的是将systffs.c、systffs.h放在BSP目录下,在初始化中添加tffsDrv()和usrTffsConfig()函数。3. TFFS中两大数据结构:FLSOCKET和FLFLASHFLFLASH是MTD层维护的数据结构,它的定义如下:struct tFlash FlashTypetype;/* Flash device type (JEDEC id) */ long interasableBlockSize;/* Smallest physically erasable size (with interleaving taken in account) */ long intchipSize;/* chip size */ intnoOfChips;/* no of chips in array */ intinterleaving;/* chip interleaving*/ unsignedflags;/* Special capabilities & options*/ void *mtdVars;/* Points to MTD private area*/ FLSocket *socket;/* Socket of this drive */ void FAR0 *(*map)(FLFlash *, CardAddress, int); FLStatus(*read)(FLFlash *, CardAddress, void FAR1 *, int, int); FLStatus (*write)(FLFlash *, CardAddress, const void FAR1 *, int, int); FLStatus (*erase)(FLFlash *, int, int); void (*setPowerOnCallback)(FLFlash *);这个数据结构中包含了MTD维护的数据和flash的操作方法,包括重映射、读、写、擦除等函数指针。只需要注意的是这个数据结构包含socket指针,它指向flash对应的socket数据结构。具体每个数据的含义可以看flflash.h的解释。FLSOCKET是socket层维护的数据结构,它的定义如下struct tSocket unsignedvolNo;/* Volume no. of socket */ unsigned serialNo; /* Serial no. of socket on controller */ FLBooleancardChanged;/* need media change notification */ int VccUsers;/* No. of current VCC users */ int VppUsers;/* No. of current VPP users */ PowerStateVccState;/* Actual VCC state */ PowerStateVppState;/* Actual VPP state */ FLBooleanremapped; /* set to TRUE whenever the socket window is moved */ void(*powerOnCallback)(void *flash); /* Notification routine for Vcc on */ void *flash;/* Flash object for callback */ struct /* Window state */ unsigned int baseAddress;/* Physical base as a 4K page */ unsigned int currentPage;/* Our current window page mapping */ void FAR0 *base;/* Pointer to window base */ long intsize; /* Window size (must by power of 2) */ unsignedspeed;/* in nsec. */ unsigned busWidth;/* 8 or 16 bits */ window; FLBoolean (*cardDetected)(FLSocket vol); void (*VccOn)(FLSocket vol); void (*VccOff)(FLSocket vol); FLStatus (*VppOn)(FLSocket vol); void (*VppOff)(FLSocket vol); FLStatus (*initSocket)(FLSocket vol); void (*setWindow)(FLSocket vol); void (*setMappingContext)(FLSocket vol, unsigned page); FLBoolean (*getAndClearCardChangeIndicator)(FLSocket vol); FLBoolean (*writeProtected)(FLSocket vol);#ifdef EXIT void (*freeSocket)(FLSocket vol);#endif;这结构体为TFFS提供了指向处理flash硬件接口的函数指针。一般情况下,怎样实现这些flash接口函数相对软件来说更需要硬件细节。 相应的,FLSocket结构体的成员描述指出了风河提供的BSP,这样我们就可以用来作例子。但是,在使用这些BSP时,我们需要对特定的硬件特别谙熟。每个成员的含义看以看flsocket.h文件。4. 添加socket添加socket需要做三部分工作:注册socket、添加全局函数FitInSocketWindow()和DelayLoop()函数。为何要注册socket?socket注册后怎么被MTD发现?MTD如何使用socket功能?下面为大家解答:为何要注册socket?Socket层在MTD层之下,为MTD层提供检测硬件擦拔、硬件写保护等功能。对于固定在板卡上的flash其没有擦拔功能,所以比较简单而且代码改动较少;对于带热插拔的flash比较复杂。Socket注册后怎么被MTD发现?MTD如何使用socket功能?首先看如何创建一个tffs设备FlMount()函数是挂载翻译层: FLSocket *socket = flSocketOf(volNo); /根据volume no 获取socket指针 checkStatus(flIdentifyFlash(socket,flash); for (iTL = 0; iTL = DRIVES) return (flTooManyComponents);tffsSocketnoOfDrives = RFA;noOfDrives+;第二部初始化下面一些变量:window.baseAddressSee window.baseAddress; cardDetected ;VccOn ;VccOff; VppOn;VppOff;initSocket;setWindow;setMappingContext;getAndClearCardChangeIndicatorwriteProtected freeSocket 4.3添加全局函数FitInSocketWindow()和DelayLoop()函数Tffs使用FitInSocketWindow()函数确定chipsize不会比windowsize大;什么是chipsize什么是windowsize?chipsize是你的flash大小;而windowsize是ppc为了方便管理每个外围设备,而分配的一段空间;所以FitInSocketWindow()就是要确保分配给你的空间足够用;如果ppc分配的flash空间比flash本身要小,那么就返回ppc分配的flash空间。一般这个函数直接返回FLSocket.chipSize。如下:long int flFitInSocketWindow ( long int chipSize,/* size of single physical chip in bytes */ int interleaving,/* flash chip interleaving (1,2,4 etc) */ long int windowSize/* socket window size in bytes */ ) /* x86 architectures use sliding windows for flash arrays */ /* so this check is irrelevant for them */ return (chipSize);Tffs使用DelayLoop()函数来处理flash硬件之间交互所需的等待时间;这个函数格式比较固定:void flDelayLoop(int cycles /* loop count to be consumed */)while (-cycles);.5. 添加MTD根据第4节分析的添加tffs流程分析可以得出:添加MTD需要以下几个部分:xxxIdentify()函数、flmap()函数、flash读写擦除函数、添加xxxIndentify到MTD中。xxxIdentify()xxxIdentify函数探测设备,并鉴别设别ID;看设备ID是否是其支持的设备ID;如果是则初始化flflash数据结构;如果不是则返回失败。Flflash中需要初始化的数据包括以下部分:typeerasableBlockSizechipSizenoOfChipsinterleavingwriteerasemapread对于大部分的norflash你可以使用标准的IntelIdentify()和IntelSize()函数自动读取flash设备ID、flash大小等;首先调用IntelIdentify()FLStatus flIntelIdentify(FLFlash vol,void (*amdCmdRoutine) (FLFlash *, long int, unsigned char),long int chipOffset)IntelIdentify()使用flash设备READ_ID命令检测设备并读取ID,如果是intel的flash设备amdCmdRoutine设置为NULL,如果是AMD& Fujitsu的flash设备amdCmdRoutine设置为写flash命令函数的地址;chipOffSet设置为读取设备ID的偏移地址。一般设置为0。如果IntelIdentify失败,那么MTD的xxxIndentify函数也将返回失败;如果成功,它将设置vol.type和erleaving的值;xxxIndentify函数将检查vol.type中包含的ID;如果MTD可以处理这种类型的flash,它将设置vol.chipSize为正确的值。然后调用IntelSize()函数,它将设置vol.noOfChips的值。Flmap()函数Flmap是MTD映射函数,第四章有介绍在鉴定flash设备时需要调用flmap函数获取硬件设备地址,然后读取flash设备ID。Flash阵列是通过系统一个智能控制器连接到总线的,我们系统通过主机地址窗口访问flash地址空间。具体如下图:地址窗口可以在地址空间上左右移动,当我们需要访问flash地址空间时,将窗口移动到flash地址,然后访问flash就可以像访问本地存储空间一样。因为窗口的最小值为4K,所以在访问偏移地址时不能超过4K大小。Read()函数如果 flash设备可以直接映射到 flash存储空间,则读取操作将是小菜一碟。TFFS提供一个默认函数用于重映射和简单的内存拷贝以便从特定区域重新获取数据。如果映射是通过缓存进行的,你就必须提供你自己的读取函数。 一般情况下,你应当尽可能通用地编写读函数。就是说,读函数每次只应当读一个字符或一个字也或者一个长字,而且它还应当能忽略芯片类型进行通用的读操作。Write()函数和Erase()函数通常来说,擦除和写函数应该尽量做到通用化,写函数每次只应当写一个字符,或者一个字也或者一个长字,而且能象忽略芯片类型一样进行通用的写操作。这种要求同样使用擦除操作。作为输入,使用FLFlash结构体中的erasableBlockSize成员的值将块号传送到 flash阵列的偏移地址,即可以针对某个块进行擦除。注册你的MTD设备前面第四章有将到,当tffs要匹配MTD时,需要遍历mtdtable数组,这个数组是全局遍历。我们将我们mtd的xxxIndentify函数加载这个数组中。如下:MTDidentif

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论