这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » 关于在NAND FLASH上建立TFFS文件系统小结 这篇文章的一个疑问

共2条 1/1 1 跳转至

关于在NAND FLASH上建立TFFS文件系统小结 这篇文章的一个疑问

菜鸟
2006-03-21 01:01:36     打赏
以下是引用minuet在2004-8-24 1:09:00的发言:
经过一个星期的摸索,终于在NAND FLASH上建立了TFFS文件系统,今天拿出来和大家分享一下!相信大家对NAND FLASH的特点和与NOR FLASH的区别都有所了解,有关这方面的文章坛子里有,我就不在赘述了。下面我以三星的K9F6408U0C为例(它是8M x 8 Bit NAND Flash Memory),详细说明建立过程。

环境:tornado2.0 for arm

一、硬件连接
主要是CLE和ALE的连接,可以用I/O口控制,也可以直接与地址线相连。我选择后者,因为这种方法既方便,访问速度也比I/O口控制快。我是让CLE接在A20上,ALE接在A21上。
还要注意/WP(写保护)这个脚,使其上拉。我在工作过程中曾忽略了对它的控制(浮空),导致写保护有效,擦写都无效。希望大家不要犯同样的错误。
/CE这个脚我是接在CPU的BANK1片选上,即界于0x1000000~0x1ffffff的16M地址都是指向此flash设备,当然我们只要选择一个地址表示即可,简单起见选0x1000000。
R//B接在CPU的一个输入I/O上,通过读此I/O判断设备是忙还是准备好。有的片子要求在片子忙状态时,/CE要是低电平,所以建议R//B与/CE连接在一起。
综上所述,可以如此定义:
#define WRITE_COMMAND(val) (*(volatile char *)0x1100000 = (char)(val)) /* CLE = A20 */
#define WRITE_ADDRESS(val) (*(volatile char *)0x1200000 = (char)(val)) /* ALE = A21 */
#define WRITE_DATA(val) (*(volatile char *)0x1000000 = (char)(val)) /* CE = 0 CLE = 0 ALE = 0 */
#define READ_DATA(val) ((char)(val) = *(volatile char *)0x1000000) /* CE = 0 CLE = 0 ALE = 0 */
#define READ_REG(val) ((int)(val) = *(volatile int *)0x60061C) /* PI3寄存器地址 */
上班时间到了,先写到这。(未完待续)by 浊玉
二、编写MTD
在vxworks提供的参考MTD中(.\target\src\drv\tffs文件夹下),有两个关于nand flash的MTD,分别是nfdc2048.c和nfdc2148.c。前者是支持NFDC2048 ASIC controller的,后者支持DOC2000。这对于我要做的nand TFFS来说是有不小的差别的,但是有参考总比全靠自己写要强吧,所以我参考了相对容易点的nfdc2048.c。
在基本看懂程序之后,便着手大刀阔斧的修改。因为不是用NFDC2048 ASIC controller,所以应该#undef NFDC2048或者去掉所有有关的内容。首先是识别函数nandMTDIdentify()。如下:

FLStatus nandMTDIdentify(FLFlash vol)
{
#ifdef DEBUG_PRINT
DEBUG_PRINT("Debug: Entering K9F6408U0C identification routine\n");
#endif flSetWindowBusWidth(vol.socket,8);/* use 16-bits */
flSetWindowSpeed(vol.socket,120); /* 120 nsec. */
flSetWindowSize(vol.socket,2); /* 4 KBytes */ vol.mtdVars = &mtdVars[flSocketNoOf(vol.socket)];
/* get pointer to buffer (we assume SINGLE_BUFFER is not defined) */
thisVars->buffer = flBufferOf(flSocketNoOf(vol.socket)); vol.interleaving = 1;
vol.noOfChips = 1; /* 以1为起始 */

if(readFlashID(&vol, vol.noOfChips) != TRUE )
{
#ifdef DEBUG_PRINT
DEBUG_PRINT("Debug: did not identify K9F6408U0C flash media.\n");
#endif
return flUnknownMedia;
}

/* Register our flash handlers */
vol.write = nandMTDWrite;
vol.erase = nandMTDErase;
vol.read = nandMTDRead;
vol.map = nandMTDMap; vol.flags |= SUSPEND_FOR_WRITE; #ifdef DEBUG_PRINT
DEBUG_PRINT("Debug: Identified K9F6408U0C.\n");
#endif return flOK;
}
和NOR FLASH不同的是,读数据也是以页为单位的,所以要写nandMTDRead()函数,类似于nandMTDWrite()。参考MTD写的很细,而且和我的硬件连接不一样,所以主要改动的是与硬件相关的部分,其它的基本不需改动。
三、sysTffs.c文件
在这个文件中加 #define INCLUDE_MTD_NAND /* K9F6408U0C add */
#undef INCLUDE_TL_NFTL /* NFTL translation layer */
#define INCLUDE_TL_FTL /* FTL translation layer */
#undef INCLUDE_TL_SSFDC /* SSFDC translation layer */
#undef INCLUDE_TFFS_BOOT_IMAGE /* include tffsBootImagePut() */
#define FLASH_BASE_ADRS 0x00000000 /* K9F6408U0C的基地址 */
#define FLASH_SIZE 0x00800000
注意:1、这里的FLASH_BASE_ADRS是指设备的绝对地址,始终为0。
2、定义的是INCLUDE_TL_FTL而不是INCLUDE_TL_NFTL。这是最关键的地方。开始我也是定义的INCLUDE_TL_NFTL,可是格式化的时候根本不能调用到擦除、写、读函数。既然这样我就试了试INCLUDE_TL_FTL,却能够调用。后来我分析可能是把此nand flash当成了nor flash来做,只是读的时候麻烦点,因为nor flash是直接读的!就是现在我也不知道这样理解到底对不对,但能够成功建立了文件系统,我也就管不了那么多了!
3、除了以上的部分外,此文件的其它部分无需修改。还要做的就是要在tffsConfig.c文件中加入自己所写的MTD,这方面的文章坛子里也有,大家可以参考一下。
四、加入工程
在makefile中加入MACH_EXTRA = sysTffs.o nandMtd.o,重新生成工程,编译!启动wShell。输入如下:
-> sysTffsFormat
-> usrTffsConfig 0,0,"/tffs0"
如果执行这两句返回的都是正确的,那你在执行devs就可以看到flash设备了。如下:
-> devs
drv name
0 /null
1 /tyCo/1
3 /tffs0
4 /vio
5 /tgtsvr
value = 0 = 0x0
接着就可以创建文件了!
五、最后
我在nandMtd.c中加入了调试语句,可以在文件头加入#define DEBUG_PRINT printf,就可以在wShell中看到打印输出了,方便调试时查找错误。祝各位好运气!(完)by 浊玉



[upload=rar]viewFile.asp?ID=3799[/upload]

为了方便大家参考,我将vxworks提供的nfdc2048.c和nfdc2148.c也上传上来,以供大家参考!我没有在tornado2.2下试过,不过我想应该也是可以的! [upload=rar]viewFile.asp?ID=3816[/upload]

看了这篇文章,有一处还是不明白,希望各位指教,谢谢
#define WRITE_COMMAND(val) (*(volatile char *)0x1100000 = (char)(val)) /* CLE = A20 */
#define WRITE_ADDRESS(val) (*(volatile char *)0x1200000 = (char)(val)) /* ALE = A21 */
#define WRITE_DATA(val) (*(volatile char *)0x1000000 = (char)(val)) /* CE = 0 CLE = 0 ALE = 0 */
#define READ_DATA(val) ((char)(val) = *(volatile char *)0x1000000) /* CE = 0 CLE = 0 ALE = 0 */
#define READ_REG(val) ((int)(val) = *(volatile int *)0x60061C) /* PI3寄存器地址 */

请问0x1100000,0x120000,0x60061C是怎么确定的啊,谢谢!!!




关键词: 关于     FLASH     建立     文件     系统     小结     这篇         

菜鸟
2006-03-28 05:57:00     打赏
2楼

arm有25根地址线,cle连到A20,ale连到A21,高电平有效,就是说只要A20输出高电平,cle就有效,ale也是一样的道理

这里涉及到高地址编码

A24 A23 A22 A21 A20……

cle: 1 /* cle有效 */

ale: 1 /* ale有效 */

其他无关的地址一般是0,作者把A24定义成了1。从A0开始,采用十六进制编码,四根地址线一组,就得到了那些值。对Nand flash不熟悉,至于那个0x60061C是怎么来的就帮不了你了

[align=right][color=#000066][此贴子已经被作者于2006-3-27 22:08:18编辑过][/color][/align]

共2条 1/1 1 跳转至

回复

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