加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

实验证明在一片Norflash上划分两个TrueFFS分区的误区

发布时间:2020-12-15 18:00:00 所属栏目:百科 来源:网络整理
导读:实验证明在一片Norflash上划分两个TrueFFS分区的误区 DanielLee_USTB?2013-8-1 QQ:382899443 ? ? ? ? ?这几天研究flash TrueFFS驱动,以及挂载dosfs文件系统,发现格式化C盘后再重启系统出现挂载失败的情况,于是决定做flash重新分区以及在同一个Norflash上

实验证明在一片Norflash上划分两个TrueFFS分区的误区

DanielLee_USTB?2013-8-1

QQ:382899443

? ? ? ? ?这几天研究flash TrueFFS驱动,以及挂载dosfs文件系统,发现格式化C盘后再重启系统出现挂载失败的情况,于是决定做flash重新分区以及在同一个Norflash上划分两个磁盘分区的实验。网上有一些文章讲了修改步骤以及在划分2的非n次幂大小空间出现了分歧,令人感到困惑。如果已经找到这些文章可以与本文做一下对比。下面就通过一些了的实验说明问题。

???????? 实验条件:vxworks5.5, s3c2410开发板,flash sst39vf160大小为8M,起始地址为0x00000000,结束地址为0x00800000。

???????? 系统镜像存储区为0-2M,C盘dosfs文件系统地址为2M-8M,为6M大小。

一、查看信息

查看C盘:

-> dosFsShow "/C:"

……

- total number of sectors:??????? 11,747

?-bytes per sector:????????? 512

……

- free space on volume:?? 1,990,656 bytes

value = 0 = 0x0

发现确实为6M大小

查看C盘有很多文件:

-> ls "/C"

/C/butterfly240.bin

……

/C/blackbeauty480.bin

/C/my.txt

value = 0 = 0x0

下面将C盘格式化掉:

-> dosFsVolFormat("/C",0)

…… ??

value = 0 = 0x0

再查看C盘大小:

dosFsShow("/C:")

- free space on volume:?? 5,988,352 bytes

value = 0 = 0x0

确实已经格式化成功,整个格式化过程仅1S多点,可见vxworks格式化真的很快。

二、改变C盘大小

将C盘大小从6M改为4M

(1)修改sst39MTDIdentify

if (vol.socket->serialNo == 0){

?????????????????? flSetWindowSize(vol.socket,FIRST_FLASH_SIZE>>12);

?????????????????? vol.chipSize= 0x400000;//FIRST_FLASH_SIZE;

?????????????????? vol.map?? = sst39MTDMap0;

?????????????????? vol.mtdVars= &mtdVars[flSocketNoOf(vol.socket)];

???????? ??????? baseFlashPtr = (FlashWPTR)vol.map(&vol,(CardAddress)0,vol.interleaving);

???????? }

(2)网上说窗口大小到大于等于chipsize,即实际分区的大小,先这样试试,稍后验证,修改#define ?FIRST_FLASH_SIZE? ?????????????????? 0x800000//0x600000窗口大小为整片flash大小。

(3)添加格式化函数,挂载任何文件系统之前都需要先格式化

? ? ? ? ??添加擦除函数:

??tffsDevFormatParams params = {{0,99,1,0x10000,NULL,{0,0},2,NULL},FTL_FORMAT};

其中共用两个参数:

? ? ? ? ?tffsFormatParams ?=? {0,NULL}

???????? 这个参数的详细介绍在installDirtargethtffstffsDrv.h?有详细的介绍,除了第一项以外都不用修改。其中第一个参数是擦除的偏移地址,一般为系统镜像留出,如果系统镜像不放在文件系统中的话,而是放在rawdata中,这一项就设置为0,其实是不需要改动的。

???????? MyFormatC();

???????? if(usrTffsConfig(0,"/C")==0)

???????? {

?????????????????? ioDefPathSet("/C");

???????? };

结果:

sst39VF160 serialNo=0

sst39VF160 serialNo=0

sst39VF160 serialNo=0

-> initisizing.......

CMD0 Chk_CMDend:1.

In idle.

In SD ready.

End id.

In stand-by

sd/mmc_card_init OK.

RK2410 USB DEVICE Download FileTest-UsbRxAddr=0x318395c4

Wait for usb line......

devs

drv name???????????????

? 0/null??????????????

? 1/tyCo/0????????????

? 1/tyCo/1????????????

? 3 /ram???????????????

? 5host:??????????????

? 8/vio???????????????

? 3/C?????????????????

? 3/E?????????????????

value = 25 = 0x19 = PLL_ON_START + 0x18

-> dosFsShow "/C:"

- allocation group size:??? 1 clusters

?-free space on volume: 3,973,120 bytes

value = 0 = 0x0

? ? ? ? ?结果是成功的,但这里面存在两个问题:

? ? ? ?(1)为什么在所有改动之前(没有加入格式化函数),使用Jlink把整片flash全部擦除,直接挂载后6M不成功??????

? ? ? ?(2)为什么窗口大小是整片flash大小而不是FIRST_FLASH_SIZE呢?

对于(1)看看格式化的问题。基于以上结果在usrAppinit()中注释掉//MyFormatC()直接挂载C盘,注之前已运行过一次,即对C盘已经格式化。使用Jlink下载:

- Erasing affected sectors ...

??? - Erasing sector 0,16,32,48,64,80,96,112,128,144,160,176,192,208,224,240,256,272,288,304

??? - Erase operation completed successfully

?- Target programmed successfully - Completedafter 92.032 sec注意:Jlink擦除了304个sector

结果:

sst39VF160 serialNo=0

->initisizing.......

CMD0Chk_CMDend:1.

In idle.

In SD ready.

End id.

In stand-by

sd/mmc_card_initOK.

RK2410 USBDEVICE Download File Test-UsbRxAddr=0x31839fe4

Wait for usbline......

devs

drv name???????????????

? 0 /null??????????????

? 1 /tyCo/0????????????

? 1 /tyCo/1????????????

? 3 /ram???????????????

? 5 host:??????????????

? 8 /vio???????????????

? 3 /C?????????????????

? 3 /E?????????????????

value = 25 =0x19 = PLL_ON_START + 0x18

挂载成功

如果使用Jlink先erase chip 呢?

Erasing 2048 sectors,0x0 - 0x7FFFFF

?- RAM tested O.K.

?- Erasing sector 0,304,……,1488,1504,1520

?- Erase operation completed successfully -Completed after 47.205 sec

???????? 可以看出一共擦除了2048个sectors,显然把之前从2M-6M格式化的空间也擦除掉了,所以再写入系统镜像挂载C盘是失败的。同时也说明Jlink自己擦除已用flash空间的时候并没有擦除已经格式化的空间,不知道使用的是什么方法。

???????? 原来如果是新做的开发板,或是把flash完全擦除,flash内完全没有内容,需要在程序中先使用MyFormatC()将flash进行格式化,之后在进行挂载,然后在程序中删掉MyFormatC(),再编译下载镜像,防止每次运行都格式化一次。买的开发板的话厂家已经做了这一步了。

???????? 再看(2),恢复到之前的运行结果,即不注释MyFormatC(),将#define FIRST_FLASH_SIZE定义的窗口大小,改为文件系统实际大小0x400000

运行结果:

sst39VF160 serialNo=0

sst39VF160 serialNo=0

sst39VF160 serialNo=0

-> initisizing.......

CMD0 Chk_CMDend:1.

In idle.

In SD ready.

End id.

In stand-by

sd/mmc_card_init OK.

RK2410 USB DEVICE Download FileTest-UsbRxAddr=0x318385bc

Wait for usb line......

devs

drv name???????????????

? 0/null??????????????

? 1/tyCo/0????????????

? 1/tyCo/1????????????

? 3/ram???????????????

? 5host:??????????????

? 8/vio???????????????

? 3/C?????????????????

? 3/E?????

???????? 居然成功了!这就很明了了,窗口大小可以和文件系统大小一样,而不是网上说的必须大于等于芯片大小,在vxworks BSP中显然也没有将文件系统大小与窗口大小做宏定义上的区分,人家这么做说明两者相同完全是可以的。所以,遇到问题要自己分析实验,对网上的说法要批判性的吸收,不能盲从。

三、重新划分为两个磁盘为偶数大小

???????? 为了更好对dosfs文件系统有跟好的了解,下面将原来的6M空间划分为4M的C盘以及2M的D盘。

???????? ConfigTffs.h基地址以及大小:

???????? C盘基地址为

???????? #defineFIRST_FLASH_START???????????????????? 0x200000? //2M 开始

???????? #defineFIRST_FLASH_SIZE???????????????????????? 0x400000? //0x600000 改为4M大小

???????? D盘基地址以及大小:

???????? #defineSECOND_FLASH_START ? ? ? ? ? ? ?0x600000 ?//6M位置开始

???????? #defineSECOND_FLASH_SIZE?????????????????? 0x200000 // 8M大小

???????? 另外,看SECOND_FLASH_BASE到底是0x600000,还是0x000000.因为这两个分区时在同一个flash中进行的,由于对flash的写和擦除都需要写入解锁命令,这个命令对于两个分区来说是没有区别的,都应该写在flash中同一地址上,因此断定SECOND_FLASH_BASE为0x000000。

? ? ? ? 1.修改:sst39vf160.c

sst39MTDIdentify()

static void FAR0 *??? sst39MTDMap0(FLFlash *vol,CardAddress addr,int length)

{

???????? UINT32ret;

???????? ret= FIRST_FLASH_START +addr;

???????? return(void FAR0 *)ret;

}

static void FAR0 *??? sst39MTDMap1(FLFlash *vol,int length)

{

???????? UINT32ret;

???????? ret= SECOND_FLASH_START +addr;

???????? return(void FAR0 *)ret;

}

???????? if(vol.socket->serialNo == 0){

?????????????????? flSetWindowSize(vol.socket,FIRST_FLASH_SIZE>>12);

?????????????????? vol.chipSize= FIRST_FLASH_SIZE;? //0x400000

?????????????????? vol.map?? = sst39MTDMap0;

?????????????????? vol.mtdVars= &mtdVars[flSocketNoOf(vol.socket)];

???????? ??????? baseFlashPtr = (FlashWPTR)vol.map(&vol,(CardAddress)0,vol.interleaving);

???????? }

???????? elseif(vol.socket->serialNo == 1)

???????? {

?????????????????? flSetWindowSize(vol.socket,SECOND_FLASH_SIZE>>12);

?????????????????? vol.chipSize= SECOND_FLASH_SIZE;? //0x200000

?????????????????? vol.map?? = sst39MTDMap1;

?????????????????? vol.mtdVars= &mtdVars[flSocketNoOf(vol.socket)];

???????? ??????? baseFlashPtr = (FlashWPTR)vol.map(&vol,vol.interleaving);

???????? }

flSetWindowSize 这个函数设置指出了窗口的大小,是4KB页的倍数,也是右移12位的原因。其实这个WindowSize设置的可以比实际申请的空间大的,但是绝对不能小。

? ? ? ? 2.在sysTffs.c文件中修改Socket接口

???????? if? (noOfDrives == 0)

??? ???????? vol.window.baseAddress =FIRST_FLASH_START >> 12;

???else if(noOfDrives == 1)

?????????????????? vol.window.baseAddress= SECOND_FLASH_START >> 12;

???????? noOfDrives++;

LOCAL void rfaSetWindow

??? (

??? ???????? FLSocket vol?????????????? /* pointer identifying drive */

??? )

??? {

???/* Physical base as a 4K page */

???if???? (vol.serialNo == 0){

??? ???????? vol.window.baseAddress =FIRST_FLASH_START >> 12;

??? ???????? flSetWindowSize (&vol,FIRST_FLASH_SIZE >> 12);

??? }

???else if(vol.serialNo == 1){

??? ???????? vol.window.baseAddress =SECOND_FLASH_START >> 12;

??? ???????? flSetWindowSize (&vol,SECOND_FLASH_SIZE >> 12);

???????? }

}

? ? ?3.挂载dosfs修改usrAppInit.c

???MyFormatC();

???????? if(usrTffsConfig(0,"/C")==0)

???????? {

?????????????????? ioDefPathSet("/C");

???????? };

???????? MyFormatD();

???????? if(usrTffsConfig(1,"/D")==0)

???????? {

?????????????????? ioDefPathSet("/D");

???????? };

???结果:

sst39VF160serialNo=0

sst39VF160serialNo=0

sst39VF160serialNo=0

sst39VF160serialNo=1

sst39VF160serialNo=1

sst39VF160serialNo=1

->initisizing.......

CMD0Chk_CMDend:1.

In idle.

In SDready.

End id.

Instand-by

sd/mmc_card_initOK.

RK2410USB DEVICE Download File Test-UsbRxAddr=0x31817488

Wait forusb line......

devs

drvname???????????????

? 0 /null??????????????

? 1 /tyCo/0????????????

? 1 /tyCo/1????????????

? 3 /ram???????????????

? 5 host:??????????????

? 8 /vio???????????????

? 3 /C?????????????????

? 3 /D?????????????????

? 3 /E?????????????????

value =25 = 0x19 = PLL_ON_START + 0x18

查看空间:

->dosFsShow "/C:"

- totalnumber of sectors:??????? 7,791

-allocation group size:??? 1 clusters

?- free space on volume: 3,120bytes

->dosFsShow "/D:"

- totalnumber of sectors:??????? 3,831

-allocation group size:??? 1 clusters

?- free space on volume: 1,949,696bytes

value = 0= 0x0??????????

? ? ? ? C盘和D盘都挂载成功了,而且容量都是正确的。现在先总结一下以前实验不成功的原因:(1)挂载之前没有格式化,所以挂载失败(2)挂载盘卷号写错误导致挂载出现异常。而且通过验证,窗口设置的大小flSetWindowSize (&vol,FIRST_FLASH_SIZE >> 12);与分区大小一致就可以了,用不着设置成整个芯片的大小。

四、重新划分为两个磁盘为非2N次幂大小

? ? ? ? 现在把C盘划分为3M,D盘划分为3M试一下

? ? ? ? 做如下定义:

#define FIRST_FLASH_BASE?????????????????????? 0x000000

#define FIRST_FLASH_START???????????????????? 0x200000

#define FIRST_FLASH_SIZE???????????????????????? 0x300000//0x400000

#define FIRST_FLASH_TYPE????????? 0x01

#define SECOND_FLASH_BASE????????????????? 0x000000

#define SECOND_FLASH_START????? ??? 0x500000//0x600000

#define SECOND_FLASH_SIZE?????????????????? 0x300000//0x200000

#define SECOND_FLASH_TYPE????????????????? 0x02

编译下载,结果:

sst39VF160serialNo=0

sst39VF160serialNo=0

sst39VF160serialNo=0

sst39VF160serialNo=1

sst39VF160serialNo=1

sst39VF160serialNo=1

devs

drvname???????????????

? 0 /null??????????????

? 1 /tyCo/0????????????

? 1 /tyCo/1????????????

? 3 /ram???????????????

? 5 host:??????????????

? 8 /vio???????????????

? 3 /C?????????????????

? 3 /D?????????????????

? 3 /E?????????????????

->dosFsShow "/C:"

- free space on volume:?? 2,961,408 bytes

value = 0= 0x0

->dosFsShow "/D:"

- free space on volume:?? 2,408 bytes

value = 0= 0x0

? ? ? ? 为了保险起见,又尝试重新划分为1M和5M大小,结果为:

->dosFsShow "/C:"

- free space on volume:?? 940,032 bytes

value = 0= 0x0

->dosFsShow "/D:"

- free space on volume:?? 4,984,832 bytes

value = 0= 0x0

? ? ? ? ?同样是成功的。

???????? 之所以做这个实验,是因为看到网上 “只能建立2n次幂M大小的文件系统的疑问”的说法,说如果遇到非2的n次幂情况格式化flash不成功,解决的方法是修改窗口为整个芯片大小,其实这样的说法是不合理的。因为本实验发现即使将C盘和D盘均分为3M以及分为1M和5M都是可以成功的,是不是2的n次幂的磁盘空间修改的方法都一样,都是修改configTffs.h里的宏定义。

? ? ? ? 由于vxworks系统版本以及硬件环境上存在差异,不排斥其他博文说明的情况,只是在找原因的时候要多动手做实验自己找原因,不能盲从。欢迎讨论。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读