vxworks的TFFS分析

2020-06-28 11:40

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和FLFLASH

FLFLASH是MTD层维护的数据结构,它的定义如下: struct tFlash{

FlashType type; /* Flash device type (JEDEC id) */ long int erasableBlockSize; /* Smallest physically erasable size (with interleaving taken in account) */ long int chipSize; /* chip size */ int noOfChips; /* no of chips in array */ int interleaving; /* chip interleaving*/ unsigned flags; /* 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 {

unsigned volNo; /* Volume no. of socket */ unsigned serialNo; /* Serial no. of socket on controller */

FLBoolean cardChanged; /* need media change notification */

int VccUsers; /* No. of current VCC users */ int VppUsers; /* No. of current VPP users */

PowerState VccState; /* Actual VCC state */ PowerState VppState; /* Actual VPP state */

FLBoolean remapped; /* 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 int size; /* Window size (must by power of 2) */ unsigned speed; /* 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 < noOfTLs && status != flOK; iTL++)

status = tlTable[iTL].mountRoutine(flash,tl, &volForCallback);

可以看到flmount先获取注册的socket号,然后执行flIdentifyFlash()函数。flIdentifyFlash函数首先装载默认的MTD函数指针,然后遍历全局变量mtdtable数组,查找合适的MTD。如果没有查找到,则使用默认的MTD。 根据tffs创建设备的过程,我们可以发现创建设备需要根据volume no 获取socket指针,在具体的xxxIdentify()函数中调用flIntelIdentify。此函数根据socket指针调用flMap()函数获取设备硬件资源(设备窗口地址),然后通过获取的硬件资源对硬件进行读取ID操作,获取设备ID。xxxIdentify()函数通过读取返回的设备ID判断是否是XXXMTD注册的设备,如果是初始化读写函数并返回。

4.1注册socket

要使用socket必须先注册socket,下图是vxworks使用socket注册的步骤:

tffsDrv最终会调用xxxRegister()函数,此函数就是我们需要增加的具体的socket注册函数。如果我们要注册多个socket的话,需要在sysTffsInit()函数中增加,增加的方法如下:

#ifdef

INCLUDE_SOCKET_DOC

/* Disk On Chip */

(void) docRegister ();

#endif #ifdef

/* INCLUDE_SOCKET_DOC */ INCLUDE_SOCKET_PCIC0

/* flash card on socket 0 */

(void) pcRegister (0, PC_BASE_ADRS_0);

#endif #ifdef

/* INCLUDE_SOCKET_PCIC0 */ INCLUDE_SOCKET_PCIC1

(void) pcRegister (1, PC_BASE_ADRS_1);

#endif

/* INCLUDE_SOCKET_PCIC1 */

/* flash card on socket 1 */

使用宏开关控制。

4.2xxxRegister()一般写法

xxxRegister()函数一般包括两部分:一部分是获取socket号,更新全局变量tffsSocket[]并更新socket号;另一部分是初始化flsocket数据而机构;


vxworks的TFFS分析.doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:高考物理实验创新题

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: