这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » [原创]Tornado之TrueFFS编程者指南(五)

共1条 1/1 1 跳转至

[原创]Tornado之TrueFFS编程者指南(五)

菜鸟
2003-03-11 00:35:09     打赏
3.格式化Flash 为了使用TrueFFS,要先调用tffsDevFormat( )函数来格式式flash。在格式化的过程中,该函数先擦除flash然后将TrueFFS数据管理结构(data-management structures)写到位于每个擦除单元(如扇区)起始处的头里。tffsDevFormat( )需要两个输入参数:设备号(socket组件号)和一个指向格式化参数(FormatParams)的指针。设备号由socket组件在系统中注册的先后顺序决定。而FormatParams结构则是传递如何格式化此flash的值。这个结构定义如下: typedef struct { /* FTL formatting section */ long int bootImageLen;      /*bootImage需要从flash媒体开始处预留的长度*/ unsigned percentUse;        /*flash媒体被格式化的百分率,为了提高TrueFFS的性能,不要设为100%,以便任何时候都有空余 空间。默认值为99%*/ unsigned noOfSpareUnits;      /*空余擦除单元数目,目的在于flash出现坏块时可以用它来替代,默认为1*/ unsigned long vmAddressingLimit;  /* FTL 在RAM中映射的大小,默认为61Kbytes*/ FLStatus (*progressCallback)(int totalUnitsToFormat, int totalUnitsFormattedSoFar); /* 回调函数,用来监测flash擦除过程,如果返回值为OK,则继续,否则停止擦除。*/ /* DOS formatting section */ char volumeId[4];   /*Dos卷标号*/ char FAR1 * volumeLabel;   /*Dos卷标字符串,如果为NULL,则没有卷标*/ unsigned noOfFATcopies; /* 文件分配表(FAT)的拷贝数,正常情况下只使用一个FAT,而另一个只有在使用的FAT被破坏的情况下用来恢复分配表,默认为2*/ unsigned embeddedCISlength; /* CIS 嵌在单元头部(unit header)之后的字节长度*/ char FAR1 * embeddedCIS;  /* 单元头部被结构化用来作为一个PCMCIA ''tuple'' 链(a CIS)的起始,它包含了一个数据组织tuple,通常用16进制的0xFF来标示上一个单元头部结束的位置(''end-of-tuple-chain'')。*/ } FormatParams; /* 默认的FormatParams 结构*/ #define STD_FORMAT_PARAMS {0, 99, 1, 0x10000l, NULL, {0,0,0,0}, NULL, 2, 0, NULL}。 一般来说,你可以把这个指针赋为NULL(0),这样就告诉tffsDevFormat( )使用在dosformt.h中定义的默认FormatParams结构。在这个默认的结构中定义的值对于绝大多数的应用已经足够了。然而,如果你想在该flash媒体上共用TrueFFS和引导映象(boot image),这个缺省的结构就不太合适了。你必须修改bootImageLen的值,以适应boot Image的大小,tffsDevFormat( )在格式化的时候会保留这一部分空间。   另外,我们还应该了解另一个格式化函数sysTffsFormat( )。它在内部其实还是调用了tffsDevFormat( )函数。它没有入口参数,它使用自己的FormatParams参数来格式化flash。要了解更详细的信息你可以参阅bsp中sysTffs.c文件中的sysTffsFormat( )函数。 4.设置簇的大小 在为TrueFFS格式化一个flash设备时,扇区都被分配到簇里面,一个簇包含的扇区数由flMinClusterSize来决定,这是一个在dosFormat.c中定义的int型全局变量。合法的值是2的非负数n次幂(1,2,4,8,……)。默认值为4。你可以减小这个值以获得更好的存贮密度,但由于FAT的入口数是有限的,flash媒体上的可寻址空间也会相应减小。例如,如果把flMinClusterSize设为1,则最大的可寻址空间为16M字节。 5.与bootImage区域相关的问题  正如上面所说的,当tffsDevFormat( )在一个偏移地址上格式化flash时,它不会碰偏移地址以下的的空间。正常情况下,这是好事。然而,如果先前使用了TrueFFS格式化了偏移地址以下的空间,那么这些空间的擦除单元就会包含tffsDevFormat( )写入的TrueFFS格式化头部信息。当TrueFFS挂接(mount)一个flash设备时,它会扫描整个flash的TrueFFS格式化头部信息,用来建立一个它控制的flash memory的区域表。如果在偏移地址之下的区域碰巧包含这样的头,那么TrueFFS挂接(mount)程序还可以看到这些头,结果当然会失败。 怎样解决这个问题呢?你可以调用tffsRawio( )来对这些有问题的单元作一个物理擦除。这非常有效,但也非常危险。如果误用,有可能永久地损坏flash。在你的嵌入式系统开发初期,你可以小心地使用它。如果已经是产品了,你就必须保证你的应用程序和它的用户不被伤及。下图就是调用tffsRawio( )的情况。 [upload=gif]uploadImages/200331016311810102.gif[/upload] 6.创建TrueFFS块设备   在你能创建一个逻辑TrueFFS块设备之前,你需要运行tffsDrv( )。如果你正确配置了VxWorks,它会在启动的时候自动加载。tffsDrv( )为Tornado初始化TrueFFS,包括建立互斥信号量、全局变量和用来管理TrueFFS的数据结构。也包括为目标机上所有的flash设备注册socket组件的驱动程序。 注册socket组件的驱动程序从获取FLSocket中预先分配的5元素(5-element)TrueFFS内部数组开始。下一步是更新FLSocket结构以包含那些控制flash设备基本硬件接口的数据和函数指针。 当TrueFFS需要和具体的socket硬件打交道时,它使用设备号(0-4)作为索引来查找它的FLSocket结构,然后用相应结构中的函数来控制它的硬件接口需求。虽然这些socket接口函数并没有提供完整的块设备接口,但它们的确提供了一个足够好的使用tffsDevFormat( )的接口。这对于一个从未格式化的flash媒体来说是非常重要的,因为这种能力使得在此阶段创建一个TrueFFS块设备成为可能。 注册完一个socket组件驱动后,就可以调用tffsDevCreate( )在此之上创建一个TrueFFS块设备。作为一个输入参数,你必须为它指定一个设备号(0-4)。也就进入FLSocket结构数组的索引。作为设备号,它稍后对于dosFs是可见的。 在创建了TrueFFS块设备后,你必须调用dosFsDevInit( )函数将dos文件系统挂接(mount)到它上面。之后你就可以象从一个标准disk设备上读写flash了。为了方便,函数usrTffsConfig( )将tffsDevCreate( )和dosFsDevInit( )合成了,并包含了一些创建TrueFFS块设备和挂接dosFS必要的函数,你只需调用它就可以了。以下是bootCofig.c中关于TrueFFS块设备的代码,当采用tffs方式引导vxworks内核时,该函数被调用。 LOCAL STATUS tffsLoad ( int drive, /* TFFS drive number (0 - (noOfDrives-1)) */ int removable, /* 0 - nonremovable flash media */ char * fileName, /* file name to download */ FUNCPTR * pEntry ) { int fd; if (tffsDrv () != OK) { printErr ("Could not initialize.\n"); return (ERROR); } printf ("Attaching to TFFS... "); dosFsInit (NUM_DOSFS_FILES); /* initialize DOS-FS */ if (usrTffsConfig (drive, removable, fileName) == ERROR) { printErr ("usrTffsConfig failed.\n"); return (ERROR); } printErr ("done.\n"); /* load the boot file */ printErr ("Loading %s...", fileName); if ((fd = open (fileName, O_RDONLY, 0)) == ERROR) { printErr ("\nCannot open \"%s\".\n", fileName); return (ERROR); } if (bootLoadModule (fd, pEntry) != OK) goto tffsLoadErr; close (fd); return (OK); } --------------------------------------- (未完待续) [align=right][color=#000066][此贴子已经被作者于2003-3-10 16:42:35编辑过][/color][/align]



关键词: 原创     Tornado     TrueFFS     编程     指南         

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]