测试环境:

OS:

wince5.0

cpu:

J9

image:

ramimage(开始是一个binfs分区存放ramimage,后面是一个fat分区存放user data,它们公用一个块驱动)

note:

具体测试command的书写要参照注册表的配置。

本文中频繁用到的smflash,是设备名,即传递给CreateFile和OpenStore的实参,如果不确定你块驱动的设备名,可以在AP中通过FindFirstStore以及FindNextStore的方式将其遍历出来。

因为之前发了一篇存在诸多问题,所以重新排版和修改了其中的大部分错误,并附上我的注册表配置。

CETK使用方法—NAND Flash(一个块驱动并且将Image放到该块驱动上)

1. 对测试有用的TUX关键词

TUX语法中的关键词有很多,其中用来制定传递给TUX DLL(即测试DLL,如flashwear.dll)的关键词是-c,详细解释如下:

-c parameters

This parameter allows you to pass a parameter string to the Tux test DLL itself. The parameter string that you pass is associated with the DLL most recently specified with the -d parameter. This behavior allows you to specify different parameters for each Tux test DLL. If the string that you specify contains spaces or other special characters, then you should surround the string with quotation marks.

在上面的文字中说的很清楚,-c用来传递参数给-d指定的tux dll,如果传递的参数中包含了空格,则应用引号将参数包起来。

如下:

详细的TUX语法参照如下地址:

ms-help://MS.WindowsCE.500/wcedebug5/html/wce50conTuxCommandLineParameters.htm

2. FSD测试

命令

默认命令+-c “-zorch -p msflash”

细节

详细解释如下。

-zorch: If you run the unmodified test, it will fail. In the results file you will see a message warning you to back up data on all cards and disks that are attached to the testing device before running the test. It then instructs you to modify the command line by right clicking on the test in the CETK tree control, choosing Edit Command Line, and adding the following switch to the command line: -zorch

可见参数-zorch告诉测试DLL在不备份磁盘数据的情况下进行测试。因为测试会毁坏测试磁盘上的文件,所以有此命令参数。

-p:Specify the storage profile to which to restrict testing, found in the registry under the HKEY_LOCAL_MACHINE/System/StorageManager/Profiles key. The default storage profile is PCMCIA.

可见参数-p告诉了测试项到HKEY_LOCAL_MACHINE/System/StorageManager下的哪个测试项下搜索相关信息。

如果磁盘上有多个分区的话,还要使用-r传递分区名,相关解释如下:Specify the root directory in which to run the test. If you provide this option, the test only runs in the specified directory and ignores the –s and –p options. This flag is useful for a file system driver that does not use storage profiles such as a network file system driver. If the name of the root directory includes spaces, surround the name of the directory with single quotation marks; for example, -r '/Storage Card'.

更加详细的参数介绍参照:

ms-help://MS.WindowsCE.500/wcedebug5/html/wce50tskModifyingtheFileSystemDriverTest.htm

3. disktest测试项

命令:

tux -o -d disktest -c "/disk msflash /oldioctls /maxsectors 128 /store /zorch /profile msflash"

细节:

从理论上来说,TUX调用disktest.dll对块驱动进行测试的时候,只需要调用打开块驱动获取操作Handle,然后调用DSK_IoControl进行读写就可以了。但是,实际操作过程中发现由于smflash.dll由Storage Manager进行加载,所以无法使用CreateFile获取块驱动的操作句柄,而必须调用OpenStore。

PB帮助文档中在介绍通过传递给TUX DLL参数决定使用CreateFile还是OpenStore打开块驱动的时候,提到如下内容:

/store

Specify that the test opens a handle to the disk by using the OpenStore function instead of the CreateFile function.

Opening a handle by using the OpenStore function is not required to test block driver functionality. However, it is useful for testing a storage device that Filesys.exe loads automatically if you cannot open the storage device as a stream device. For example, you can open a handle to a flash driver for ROM by using the OpenStore function.

代码中可以找到如下的

HANDLE

OpenDevice(

LPCTSTR pszDiskName)

// --------------------------------------------------------------------

{

// open the device as either a store or a stream device

if(g_fOpenAsStore[Passion1] )

{

return OpenStore(pszDiskName);

}

else

{

return CreateFile(pszDiskName, GENERIC_READ, FILE_SHARE_READ,

NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

}

}

关于/disk dsk*,帮助文档中提到:

Specify the device name of the disk to be tested.

If you do not specify this parameter, the test probes for a mass storage disk on devices DSK1-9. Specifying this parameter overrides the automatic detection process and forces the test to use the disk that you specify.

可以看到,如果不配置/disk的参数的话,系统就会去搜索所有的dsk1~9。其实不是这么回事,这个地方有两个错误:

>> /disk的参数描述不正确

正确的描述应该如下:

参数

获取块驱动的操作句柄

/disk

CreateFile(DSK1~9)

/disk ***

CreateFile(***)

/disk *** /store

OpenStore(***)

/disk /store

通过设备管理器发送STORE_MOUNT_GUID的Store,具体参照DEV_DetectFirstDevice(&STORE_MOUNT_GUID, szDisk, MAX_PATH)

/store

通过设备管理器发送BLOCK_DRIVER_GUID的块驱动,DEV_DetectFirstDevice(&BLOCK_DRIVER_GUID, szDisk, MAX_PATH)

>> /disk的***描述不正确

***是任意可以传递给OpenStore或者CreateFile的参数。

详细的参数如下:

tux -o -d disktest -c "/disk msflash /oldioctls /maxsectors 128 /store /zorch /profile msflash"

>> 传递Command但是TUX DLL的解析有问题

从TUX DLL最开始的Log信息中看到如下的信息:

TUXMAIN.CPP: DLL_PROCESS_ATTACH

ShellProc(SPM_LOAD_DLL, ...) calledDISKTEST: Usage: tux -o -d disktest -c"/disk <disk> /profile <profile> /maxsectors <count> /oldioctls"       /disk <disk>        : name of the disk to test (e.g. DSK1:); default = first detected disk       /profile <profile>  : limit to devices of the specified storage profile; default = all profiles       /maxsectors <count> : maximum number of sectors per operation; default = 128       /oldioctls          : use legacy DISK_IOCTL_* codes       /store              : open the disk using the OpenStore() APIShellProc(SPM_SHELL_INFO, ...) calledCommand Line: "/disk msflash /oldioctls /maxsectors 128 /store /zorch /profile msflash".

DISKTEST: Disk Device Name = msflash[Passion2]

DISKTEST: Forcing use of legacy DISK_IOCTL* style control codes

DISKTEST: Will open disk as a store (using OpenStore())

DISKTEST: Max Sectors per operation = 128

ShellProc(SPM_REGISTER, ...) called<TESTGROUP>

但是有的时候你给/disk传递的参数TUX DLL解析不出来,经过反复实践,下面的一条命令是万能命令:

tux -o -d disktest -c "/disk msflash /oldioctls /maxsectors 128 /store /zorch /profile msflash"

保证可以解析出来device name。

仔细的看了看源代码,但是还是没有找到原因。从源代码上来看,这些解析工作由函数ProcessCmdLine调用类CClParse的成员函数来实现,不存在任何问题。

4. Flashwear测试

命令

默认命令+-c”/zorch /profile msflash /store /disk msflash”或者/disk msflash /repeat 1 /sectors 64 /store都行

同时需要修改注册表。修改Flash注册表的Profile为FlashDisk,这是Microsoft Flashwear 测试DLL的Bug引起的。Flashwear的参数意义和DiskTest一致,同样它也存在Bug。

细节

详细如下:

SHELLPROCAPI ShellProc(UINT uMsg, SPPARAM spParam)

{

LPSPS_BEGIN_TEST    pBT;

LPSPS_END_TEST      pET;

switch (uMsg)

{

case SPM_SHELL_INFO:

// Sent once to the DLL immediately after SPM_LOAD_DLL to give the DLL

// some useful information about its parent shell and environment. The

// spParam parameter will contain a pointer to a SPS_SHELL_INFO

// structure. The pointer to the structure may be stored for later use

// as it will remain valid for the life of this Tux Dll. The DLL may

// return SPR_FAIL to prevent the DLL from continuing to load.

Debug(TEXT("ShellProc(SPM_SHELL_INFO, ...) called"));

// Store a pointer to our shell info for later use.

g_pShellInfo = (LPSPS_SHELL_INFO)spParam;

Initialize();

break;

//...

}

//...

}}

//check its profile

if(!DeviceIoControl(hDisk, IOCTL_DISK_DEVICE_INFO[Passion3] , &sdi, sizeof(STORAGEDEVICEINFO), NULL, 0, &cbReturned, NULL))

{

g_pKato->Log(LOG_DETAIL, _T("device /"%s/" does not support IOCTL_DISK_DEVICE_INFO (required for /profile option); error %u"), szDisk, GetLastError());

VERIFY(CloseHandle(hDisk));

hDisk = INVALID_HANDLE_VALUE;

continue;

}

else

{

// check for a profile match

if(0 != wcsicmp(_T("FlashDisk"), sdi.szProfile))[Passion4]

{

g_pKato->Log(LOG_DETAIL, _T("device /"%s/" profile /"%s/" does not match specified profile /"FlashDisk/""), szDisk, sdi.szProfile);

VERIFY(CloseHandle(hDisk));

hDisk = INVALID_HANDLE_VALUE;

continue;

}

}

如果Profile不是FlashDisk,则操作的时候会出现如下的错误Log信息:

opening a handle to storage device "msflash" OpenStore("msflash") device "msflash" profile "MSFlash" does not match specified profile "FlashDisk!" !!!msflash is not a MSFlash device, we have to re-enumerate the system to find one!!! ERROR: found no mass storage devices!

!!!ERROR: There's no MSFlash device in the system!!! FLSHWEAR: using "" disk device

另外,在测试Sector为>=2048的块设备驱动的时候,该测试Item的1~124项会全部Failed。原因是Tux Dll的设计Bug造成,这部分代码如下:

从下面的代码中可以看到,首先根据测试sector的个数,申请两段buffer,一段用来存放待写入的数据,一段用来存放读出的数据。

然后将写Buffer pWriteBuffer初始化,并调用Dsk_WriteSectors将数据写入到块驱动上;

最后调用Dsk_ReadSectors将数据从块驱动上读取,并比较是否一致。

BOOL ReadWritePerf(HANDLE hDisk, DWORD startSector, DWORD cSectors, DWORD cBytes)

{

BOOL fRet = FALSE;

BYTE *pWriteBuffer = NULL;

BYTE *pReadBuffer = NULL;

pWriteBuffer = new BYTE[cBytes];

if(NULL == pWriteBuffer) {

ERRFAIL("new BYTE[]");

goto done;

}

pReadBuffer = new BYTE[cBytes];

if(NULL == pReadBuffer) {

ERRFAIL("new BYTE[]");

goto done;

}

memset(pWriteBuffer, (BYTE)Random(), cBytes);

if(g_pWritePerfLog) g_pWritePerfLog->StartTick();

if(!Dsk_WriteSectors(hDisk, startSector, cSectors, pWriteBuffer)) {

if(g_pWritePerfLog) g_pWritePerfLog->EndTick();

ERRFAIL("Dsk_WriteSectors()");

goto done;

}

if(g_pWritePerfLog) g_pWritePerfLog->EndTick();

if(g_pReadPerfLog) g_pReadPerfLog->StartTick();

if(!Dsk_ReadSectors(hDisk, startSector, cSectors, pReadBuffer)) {

if(g_pReadPerfLog) g_pReadPerfLog->EndTick();

ERRFAIL("Dsk_ReadSectors()");

goto done;

}

if(g_pReadPerfLog) g_pReadPerfLog->EndTick();

if(0 != memcmp(pWriteBuffer, pReadBuffer, cBytes)) {

LOG(L"bad data while reading %u sectors at sector %u", cSectors, startSector);

ERRFAIL("data read is different from data written");

goto done;

}

if(g_fDelete) {

if(!Dsk_DeleteSectors(hDisk, startSector, cSectors)) {

ERRFAIL("Dsk_DeleteSectors()");

goto done;

}

}

fRet = TRUE;

done:

if(NULL != pReadBuffer) {

delete[] pReadBuffer;

}

if(NULL != pWriteBuffer) {

delete[] pWriteBuffer;

}

return fRet;

}

上面描述的流程是没有问题的,但是下面的读函数Dsk_ReadSectors和写函数Dsk_WriteSectors却有问题,即读写数据的长度都是cSectors * DEF_SECTOR_SIZE[Passion5] ,而不是cBytes(cSectors*Sector_size)。这将直接影响到上面函数ReadWritePerf中对读写数据的比较,导致测试结果出错。

简单说,就是对于Sector为>=512字节的情况,会导致测试Failed。

BOOL Dsk_WriteSectors(HANDLE hDisk, DWORD startSector, DWORD cSectors, PBYTE pData)

{

BOOL fRet;

SG_REQ sgReq;

DWORD cBytes;

// build sg request buffer -- single sg buffer

sgReq.sr_start = startSector;

sgReq.sr_num_sec = cSectors;

sgReq.sr_num_sg = 1;

sgReq.sr_callback = NULL; // no callback under CE

sgReq.sr_sglist[0].sb_len = cSectors * DEF_SECTOR_SIZE[Passion6] ;

sgReq.sr_sglist[0].sb_buf = pData;

fRet = DeviceIoControl(hDisk, DISK_IOCTL_WRITE, &sgReq, sizeof(sgReq), NULL, 0, &cBytes, NULL);

if(FALSE == fRet) {

g_pKato->Log(LOG_COMMENT, L"FAILED: DeviceIoControl(0x%08x, DISK_IOCTL_WRITE) failed error %u", hDisk, GetLastError());

fRet = DeviceIoControl(hDisk, IOCTL_DISK_WRITE, &sgReq, sizeof(sgReq), NULL, 0, &cBytes, NULL);

}

if(FALSE == fRet) {

g_pKato->Log(LOG_DETAIL, L"FAILED: DeviceIoControl(0x%08x, IOCTL_DISK_WRITE) failed error %u", hDisk, GetLastError());

}

return fRet;

}

BOOL Dsk_ReadSectors(HANDLE hDisk, DWORD startSector, DWORD cSectors, PBYTE pData)

{

BOOL fRet;

SG_REQ sgReq;

DWORD cBytes;

// build sg request buffer -- single sg buffer

sgReq.sr_start = startSector;

sgReq.sr_num_sec = cSectors;

sgReq.sr_num_sg = 1;

sgReq.sr_callback = NULL; // no callback under CE

sgReq.sr_sglist[0].sb_len = cSectors * DEF_SECTOR_SIZE[Passion7] ;

sgReq.sr_sglist[0].sb_buf = pData;

fRet = DeviceIoControl(hDisk, DISK_IOCTL_READ, &sgReq, sizeof(sgReq), NULL, 0, &cBytes, NULL);

if(FALSE == fRet) {

g_pKato->Log(LOG_COMMENT, L"FAILED: DeviceIoControl(0x%08x, DISK_IOCTL_READ) failed error %u", hDisk, GetLastError());

fRet = DeviceIoControl(hDisk, IOCTL_DISK_READ, &sgReq, sizeof(sgReq), NULL, 0, &cBytes, NULL);

}

if(FALSE == fRet) {

g_pKato->Log(LOG_DETAIL, L"FAILED: DeviceIoControl(0x%08x, IOCTL_DISK_READ) failed error %u", hDisk, GetLastError());

}

return fRet;

}

解决方法就是重新Build Flashwear测试的源码,修改上述的Bug。

5. rw_all及rwtest

这两种测试的TUX DLL,同样存在Bug,它只会去以CreateFile的方式打开流驱动,并获取其操作句柄,实际上对于Mulitple-bin的情况,需要调用OpenStore,这是因为smflash.dll是由storage manager加载。

具体修改的方法在此不再赘述。

附注册表配置:

; HIVE BOOT SECTION

[HKEY_LOCAL_MACHINE/System/StorageManager/AutoLoad/MSFlash]

"DriverPath"="Drivers//BuiltIn//MSFlash"

"Order"=dword:0

"MountFlags"=dword:11

"LoadFlags"=dword:1 ;load synchronously

"BootPhase"=dword:0

"Flags"=dword:1000

[HKEY_LOCAL_MACHINE/Drivers/BuiltIn/MSFlash]

"Prefix"="DSK"

"Order"=dword:0

"Dll"="smflash.dll"

"Profile"="FlashDisk"

"FriendlyName"="MSFLASH Driver"

"BootPhase"=dword:0

IF BSP_USE_HIVE_REGISTRY

"Flags"=dword:1000

ENDIF

[HKEY_LOCAL_MACHINE/System/StorageManager/BinFS]

"FriendlyName"="BIN Filesystem"

"Dll"="binfs.dll"

"Paging"=dword:1

"Order"=dword:0

"MountFlags"=dword:10 ;specifies to mount as an external rom file system

;if set to 11, it will be an hidden file system like mitac solution

"BootPhase"=dword:0

[HKEY_LOCAL_MACHINE/System/StorageManager/Profiles/FlashDisk]

"DefaultFileSystem"="BINFS"

"PartitionDriver"="mspart.dll"

"AutoMount"=dword:1

"AutoPart"=dword:1

"Folder"="NandFlash"

"Name"="Microsoft Flash Disk"

"BootPhase"=dword:0

IF BSP_USE_HIVE_REGISTRY

"Flags"=dword:1000

ENDIF

"MountAsHidden"=dword:1

"MountAsRom"=dword:1

[HKEY_LOCAL_MACHINE/System/StorageManager/FATFS]

"Flags"=dword:00000014                     ; FATFS_ENABLE_BACKUP_FAT | FATFS_DISABLE_AUTOSCAN

"CheckForFormat"=dword:1

"EnableWriteBack"=dword:1

"MountAsRoot"=dword:1             ; for ROM-only file system

"DisableAutoScan"=dword:1

[HKEY_LOCAL_MACHINE/System/StorageManager/Profiles/FlashDisk/FATFS]

"FriendlyName"="FAT FileSystem"

"Dll"="fatfsd.dll"

"Flags"=dword:00280014

"Paging"=dword:1

"CacheSize"=dword:0

"EnableCacheWarm"=dword:0

"EnableCache"=dword:1

IF BSP_USE_HIVE_REGISTRY

"MountAsBootable"=dword:1 ;Specifies that the file system may contain the system registry

ENDIF

"MountAsRom"=dword:1  ;Specifies to mount as an external ROM file system

"MountAsRoot"=dword:1 ;Specifies to mount as the root of the file system

任何问题欢迎给我留言或者发邮件到guopeixin@126.com进行讨论。


[Passion1]这个值其实就是通过/store来进行控制

[Passion2]这里就设Device Name

[Passion3]这里透过DeviceIoControl调用IOCTL_DISK_DEVICE_INFO [Passion3]来获取测试块驱动的Profile值

[Passion4]这里是flash wear tux dll的一个Bug,应该将该行代码注释掉

[Passion5]这里的值错误,应该根据实际的块驱动赋值

[Passion6]这里的值错误,应该根据实际的块驱动赋值

[Passion7]这里的值同样错误,应该根据实际的块驱动赋值

cetk使用方法--nand flash测试相关推荐

  1. Nand Flash Yaffs系统大量写入数据失败问题的解决方法。

    一个朋友的问题,我们共同分析后搞定.其实以前也遇到过同样问题,时间长了,没总结. 事发:在Nand Flash上使用2.6.14的linux kernel,三星2440的板子,连续写入文件,到一定大小 ...

  2. 基于STM32F429IGT6的NAND FLASH读写测试(CUBEMX)

    本文基于W29N01HV这款NAND FLASH芯片进行讲解,这款芯片的讲解在网上的资料真的很少,关于这款flash的datasheet我会免费共享出来.(如果觉得本文对你没什么帮助可参考:NAND ...

  3. Nand Flash 通过调整阈值的Retry方法简单描述

    最近想到了一个如何更加简单的理解Nand Flash做Retry原理的方法,在这里记录分享一下 这里为了表述简单,假设一个Nand Flash,它非常非常的小,小到只有8个SLC Cell,本身Ret ...

  4. STM32 + UCGUI+外扩NAND FLASH 中文字库支持方法

    1.在需要程序支持全部中文字库时,CPU内部FLASH往往不够用,这时候需要采用外部存储空间来存放字库数据.可以选用的外部存储空间有 外部FLASH.EEPROM.SD卡等. 2.汉字的编码方式有很多 ...

  5. PXA270-基于ARM9内核Processor外部NAND FLASH的控制实现

    于ARM9内核Processor外部NAND FLASH的控制实现 夏 涛 (上海交通大学微电子学院 上海 200030) 1 NAND FLASH NAND写回速度快.芯片面积小,特别是大容量使其优 ...

  6. mini2440硬件篇之Nand Flash

    1. 硬件原理 Nand Flash在对大容量的数据存储中发挥着重要的作用.相对于Nor Flash,它具有一些优势,但它的一个劣势是很容易产生坏块,因此在使用Nand Flash时,往往要利用校验算 ...

  7. NAND FLASH 内存详解与读写寻址方式

    目录: 第一章 绪论 1.1 课题来源 1.2 研究背景与意义     1.2.1 Flash介绍     1.2.2 NAND Flash介绍     1.2.3 NAND Flash与NOR Fl ...

  8. NAND FLASH 读写操作 简介

    NAND FLASH 内存详解与读写寻址方式 一.内存详解 NAND闪存阵列分为一系列128kB的区块(block),这些区块是 NAND器件中最小的可擦除实体.擦除一个区块就是把所有的位(bit)设 ...

  9. SRAM SROM DRAM DROM DDR NAND FLASH EMMC的区别

    SRAM SROM DRAM DROM DDR NAND FLASH EMMC的区别 RAM(Random Access Memory)的全名为随机存取记忆体,它相当于PC机上的移动存储,用来存储和保 ...

最新文章

  1. 矩形在as3视觉编程中的几个应用方式
  2. Linux - MiniFtp实现
  3. 哈夫曼编码之大根堆小根堆揭西县
  4. 百度超级链XChain(6)XVM虚拟机
  5. (三)docker-compose 启动 Redis 服务
  6. SAP Cloud for Customer的前世今生
  7. GIS工具篇(二):GIS最全数据下载指南
  8. php常见漏洞修复,phpstudy漏洞修复方法
  9. 编程:使用递归方式判断某个字串是否回文(Palindrome)
  10. 润乾报表连接mysql_润乾报表与DERBY数据库的创建连接详解
  11. 我在项目中运用 IOC(依赖注入)--入门篇
  12. [Google Guava]学习--新集合类型BiMap
  13. c语言程序如何编写选择题,c语言程序 如何编写挑选题
  14. 推荐一款卸载软件的小工具-《UninstallToo》
  15. ip iq 谐波检测matlab仿真,基于Matlab的低压电力系统谐波检测方法仿真研究
  16. python基础(一)完结
  17. 中国城市人均月收入已突破9000人民币大关[转载]
  18. 内存控制器(以位宽为16的NOR FLASH举例)
  19. java实现第七届蓝桥杯交换瓶子
  20. 论文中常用的英语短语

热门文章

  1. 类5-类的继承、虚函数、纯虚函数、虚析构函数
  2. 实现SDI与MDI的转换 (转)
  3. asp.net 2中的图片上传
  4. 2018年计算机学校迎新标语,2018学校迎新标语大全.doc
  5. c语言链表代码大全,C语言实现链表
  6. php curl http2,用php做ios http2推送服务遇到的坑
  7. php mongodb 连接失败,解决PHP使用普通账号连接mongodb报错问题
  8. jtable mysql数据库_使用MySQL数据库语法错误填充jTable
  9. android 悬浮球简书,轻松自制flyme悬浮球
  10. java txt 写入_JAVA 写入TXT文件