[求助]CH374枚举文件和打开文件问题

用CH374枚举U盘根目录下文件以及打开文件遇到一些问题: 1.枚举根目录下的文件或者文件夹时,只能枚举到排在前面的一个或者两个文件/文件夹。 2.只能打开根目录下的第一个文件,并且只能打开文件里面的前64个字符。 3.打开根目录下其他文件时,会返回0x42。 4.打开子目录下文件时,也会返回0x42。 程序调用的是CH374HF9.LIB库,main函数里面主要都是从示例程序里面复制的程序,希望各位大虾能够帮忙看看,为什么会出现这些为题,下面是main函数里面和CH374相关的部分:

i = CH374LibInit( ); /* 初始化CH374程序库和CH374芯片,操作成功返回0 */ mStopIfError( i ); while(1) { ak_printf("\r\nWaiting......\r\n"); while ( 1 ) { /* 支持USB-HUB */ ms_delay( 50 ); /* 没必要频繁查询 */ if ( CH374DiskConnect( ) == ERR_SUCCESS ) { /* 查询方式: 检查磁盘是否连接并更新磁盘状态,返回成功说明连接 */ ms_delay( 100 ); /* 延时,可选操作,有的USB存储器需要几十毫秒的延时 */ ak_printf("Device_In\r\n"); /* 对于检测到USB设备的,最多等待100*50mS,主要针对有些MP3太慢,对于检测到USB设备并且连接DISK_MOUNTED的,最多等待5*50mS,主要针对DiskReady不过的 */ for ( i = 0; i < 100; i ++ ) { /* 最长等待时间,100*50mS */ ms_delay( 50 ); ak_printf( "Ready ?\r\n" ); if ( CH374DiskReady( ) == ERR_SUCCESS ) { ak_printf("Ready!\r\n"); break; /* 查询磁盘是否准备好 */ } if ( CH374DiskStatus < DISK_CONNECT ) { /* 检测到断开,重新检测并计时 */ ak_printf( "Device gone\n" ); break; /* 重新等待 */ } if ( CH374DiskStatus >= DISK_MOUNTED && i > 5 ) break; /* 有的U盘总是返回未准备好,不过可以忽略,只要其建立连接MOUNTED且尝试5*50mS */ if ( CH374DiskStatus == DISK_CONNECT ) { /* 有设备连接 */ if ( CH374vHubPortCount ) { /* 连接了一个USB-HUB,但可能没有U盘 */ ak_printf( "No Udisk in USB_HUB\n" ); break; } else { /* 未知USB设备,有可能是U盘反应太慢,所以要再试试 */ } } } if ( CH374DiskStatus >= DISK_MOUNTED ) { /* 是U盘 */ break; /* 开始操作U盘 */ } if ( CH374DiskStatus == DISK_CONNECT ) { /* 多次尝试还是不行,估计不是U盘 */ if ( CH374vHubPortCount ) { /* 连接了一个USB-HUB,但可能没有U盘 */ /* 在while中等待HUB端口有U盘 */ } else { /* 未知USB设备,例如USB键盘、打印机等,而且已经试了很多次还不行 */ ak_printf( "Unknown device\n" ); } } } } ms_delay(200); #if DISK_BASE_BUF_LEN if ( DISK_BASE_BUF_LEN < CH374vSectorSize ) { // 检查磁盘数据缓冲区是否足够大,CH374vSectorSize是U盘的实际扇区大小 ak_printf( "Too large sector size\r\n" ); continue; } #endif

ak_printf("Enumer begin:\r\n"); for ( c=0; c<254; c++ ) { // 最多搜索前 254 个文件 strcpy( mCmdParam.Enumer.mPathName, "\\*" ); i = strlen( mCmdParam.Enumer.mPathName ); // 计算文件名长度,指向结束符 mCmdParam.Enumer.mPathName[i] = c; // 将结束符替换为搜索的序号,从 0 到 254 i=CH374FileEnumer( ); // 文件名中含有通配符*,枚举/搜索文件而不打开 if ( i==ERR_MISS_FILE ){ ak_printf("再也搜索不到匹配文件,已经没有匹配的文件名\r\n"); break; // 再也搜索不到匹配文件,已经没有匹配的文件名 } if ( i!=ERR_SUCCESS ){ ak_printf("出错\r\n"); break; // 出错 } ak_printf( "found name %d#: %s\r\n", (unsigned int)c, mCmdParam.Enumer.mPathName ); // 搜索到相匹配的文件名,显示序号和搜索到的匹配文件名或者子目录名 } ak_printf("Enumer end!\r\n"); ak_printf( "Open file \r\n" ); strcpy( (char *)mCmdParam.Open.mPathName, "/ABCD.C" ); //* 文件名,该文件在C51子目录下 i = CH374FileOpen( ); // ak_printf("%s \r\n",mCmdParam.Open.mPathName); mStopIfError( i ); if ( i == ERR_MISS_DIR || i == ERR_MISS_FILE ) { // 没有找到文件 // 列出文件 if ( i == ERR_MISS_DIR ) pCodeStr = (PUINT8)"/*"; // C51子目录不存在则列出根目录下的文件 else pCodeStr = (PUINT8)"/CH374*"; // CH374HFT.C文件不存在则列出\C51子目录下的以CH374开头的文件 ak_printf( "List file %s \r\n", pCodeStr ); for ( c = 0; c < 254; c ++ ) { // 最多搜索前254个文件,如果要搜索大255个文件请参考EXAM1和EXAM0 strcpy( (char *)mCmdParam.Open.mPathName, (char *)pCodeStr ); // 搜索文件名,*为通配符,适用于所有文件或者子目录 i = strlen( (char *)mCmdParam.Open.mPathName ); mCmdParam.Open.mPathName[ i ] = c; // 根据字符串长度将结束符替换为搜索的序号,从0到254 i = CH374FileOpen( ); // 打开文件,如果文件名中含有通配符*,则为搜索文件而不打开 if ( i == ERR_MISS_FILE ) break; // 再也搜索不到匹配的文件,已经没有匹配的文件名 if ( i == ERR_FOUND_NAME ) { // 搜索到与通配符相匹配的文件名,文件名及其完整路径在命令缓冲区中 ak_printf( " match file %03d#: %s\n", (unsigned int)c, mCmdParam.Open.mPathName ); // 显示序号和搜索到的匹配文件名或者子目录名 continue; // 继续搜索下一个匹配的文件名,下次搜索时序号会加1 } else { // 出错 mStopIfError( i ); break; } } } else { // 找到文件或者出错 mStopIfError( i ); gpio_set_pin_level(GPIO_LED_3,0); TotalCount=100; ak_printf( "文件路径:%s,从文件中读出的前%d个字符是:\r\n\r\n",mCmdParam.Open.mPathName,TotalCount ); ak_printf("\r\n"); while ( TotalCount ) { // 如果文件比较大,一次读不完,可以再调用CH374ByteRead继续读取,文件指针自动向后移动 if ( TotalCount > MAX_BYTE_IO ) c = MAX_BYTE_IO; // 剩余数据较多,限制单次读写的长度不能超过 sizeof( mCmdParam.ByteRead.mByteBuffer ) else c = TotalCount; // 最后剩余的字节数 mCmdParam.ByteRead.mByteCount = c; // 请求读出几十字节数据 i = CH374ByteRead( ); // 以字节为单位读取数据块,单次读写的长度不能超过MAX_BYTE_IO,第二次调用时接着刚才的向后读 mStopIfError( i ); TotalCount -= mCmdParam.ByteRead.mByteCount; // 计数,减去当前实际已经读出的字符数 for ( i=0; i!=mCmdParam.ByteRead.mByteCount; i++ ) ak_printf( "%c", mCmdParam.ByteRead.mByteBuffer[i] ); // 显示读出的字符 ak_printf("\r\n"); if ( mCmdParam.ByteRead.mByteCount < c ) { // 实际读出的字符数少于要求读出的字符数,说明已经到文件的结尾 ak_printf( "\r\n" ); ak_printf( "文件已经结束\n" ); break; } } ak_printf( "\r\nClose\r\n" ); i = CH374FileClose( ); //关闭文件 mStopIfError( i ); ak_printf( "\r\n" ); } ak_printf("\r\n");

}

看了你的程序,针对你的问题作如下回答: (1)如果是全盘枚举请参考EXAM13 (2)从你的程序看,你只打开了ABCD.C文件,并且只读去了TotalCount=100的数据 (3)打开其他文件或者目录你需要调用打开函数实现,返回0x42代表指定路径的文件没有找到,可能是文件名称错误


全盘枚举的我先琢磨琢磨2014171504851.jpg201417151292.jpg


全盘枚举的我先研究研究,打开文件问题的具体情况:我U盘有上面3个文件和4个文件夹,我的程序里面是打开ABCD.C,这个文件能够打开,我要读取100个字符,现在只能读出最前面的64个,把100改成其他大于64的数字,也是只能读取64个。然后我把程序里面strcpy( (char *)mCmdParam.Open.mPathName, "/ABCD.C" ); /ABCD.C改成/SCF.H,重新编译,让程序打开SCF.H这个文件,就会返回0x42。


能读取多少个字节的数据取决于mCmdParam.Open.mPathName这个缓冲区的大小,这个缓冲区的大小有MAX_PATH_LEN这个宏来确定。至于你说的枚举有问题估计还有其他的问题,你看下你枚举的时候枚举序号是多少?枚举出现问题最多就出现在枚举序号上面有问题。枚举的时候看下mCmdParam.Enumer.mPathName这个缓冲区的数据是什么?


只有登录才能回复,可以选择微信账号登录