Linux nand测试

  首先说说需求。我要做的是对nand flash进行大量的读写测试,这个工作有两个做法,第一个做法就是在uboot下停住,通过uboot下的命令nand read、nand write、nand erase等命令,对nand进行读写擦除等操作,这样的测试也是没有问题的,之前做过这样的工作,这将在另外一篇文章中讲述。今天要讲的是,在linux应用程序起来之后如何对nand进行大量的读写测试,这是因为之所以要测试,是想要了解软硬件的可靠性,想要知道产品在长时间的应用中会不会出问题,既然如此,那就尽量将测试的环境和使用的环境达成一致,因此,肯定是应用程序下对nand进行操作更接近实际应用。

  对于这样一个目的,首先要编写nand测试的c程序代码。下面把代码贴出来,原始的来源是下面的网址,我对它有一些改动:

  http://blog.chinaunix.net/uid-14880649-id-3023488.html

  非常感谢这位兄台,程序主体完全是他的,我只不过按照自己的习惯进行了改写,并加以分析。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>

#include <sys/statfs.h> 	//for statfs
#include <sys/vfs.h> 		//for statfs

#include <sys/types.h>
#include <sys/stat.h> 		//for stat
#include <sys/time.h>
#include "errno.h"

//函数声明
int check_remain_space(void);
int nand_test(void);
int check_remain_space(void);
int write_read_nandflash(unsigned int i,int file_size,char *write_buf,char *read_buf);

//为了让串口打印日志中看到测试次数,所以将该变量定义为全局变量
int test_count = 0; 		

int main(int argc, char *argv[])
{
	FILE *logf = NULL;			//日志文件
	int ret = 0;				//test return: -1 fail  1 succeed  0 pass
	char tempBuf[30];			//写日志中用到,用字符数组则无需分配内存,若用指针则需要malloc分配内存,之后还需要手动free,因此此处用字符数组
	int len = 0;
	
	if( ( logf = fopen("/mnt/nand/log.log","w") ) == NULL )
    {
    	printf("fopen log.log failed!\n");
        return -1;
    }
	
	while(1)
	{
		ret = nand_test();
		if(ret == -1)		//nand测试失败
		{
			printf("nand test failed!\n");
			return 0;
		}
		else if(ret == 1)	//nand写满了,写日志
		{
			memset(tempBuf, 0, sizeof(tempBuf));
			sprintf(tempBuf, "%d: nand test is OK!\n", test_count);
			len = strlen(tempBuf);    		
    		fwrite(tempBuf,len,1,logf);
    		test_count ++;
		}
		else 
		{
			//
		}
		sleep(3);
		if(test_count > 500) //限定测试次数,一般用一个较大的数
		{
			printf("test_count = 500\n");
			break;
		}			
	}
	fclose(logf);
	printf("main end!\n");
	return 0;
}

int nand_test(void)
{
	int a_size = 0;	
	int a_fd = 0;
	char *a_buf_read = NULL;
	char *a_buf_write = NULL;	
	int loop = 1;	
	int ret = 0;
	int i = 0;
	char path_name_check[32] = {0};
	
	system("date");				//测试开始
	printf("###test begin!\n");
	
	a_fd = open("/mnt/nand/uboot", O_RDONLY);	//O_RDONLY 只读;O_WRONLY 只写;O_RDWR 可读可写
    if(a_fd < 0)
    {
    	printf("open uboot failed!\n");
    	return -1;
    }
    a_size = lseek(a_fd, 0, SEEK_END);
    lseek(a_fd, 0, SEEK_SET);
    
    a_buf_write = (char *)malloc(a_size);
    if(NULL == a_buf_write)
    {
    	printf("a_buf_write malloc failed!\n");
    	close(a_fd);
    	return -1;
    }    
    a_buf_read = (char *)malloc(a_size);
    if(NULL == a_buf_read)
    {
    	printf("a_buf_read malloc failed!\n");
    	close(a_fd);
    	return -1;
    }
    
	//从a_fd文件中读取a_size个字节到a_buf_write这个buf中。成功读取返回读取字节数,出错返回-1并设置errno。
    if(read(a_fd, a_buf_write, a_size) < 0)	 //经过read函数,uboot文件中的内容到了a_buf_write中了。
    {
    	close(a_fd);
    	free(a_buf_write);
    	free(a_buf_read);
    	printf("read a file failed!\n");
    	return -1;
    }    
    close(a_fd);
    
    while(1)
    {
    	ret = check_remain_space();
    	if(ret == -1)		//nand fail
    	{	
    		free(a_buf_write);
    		free(a_buf_read);
    		printf("check_remain_space failed!\n");
    		return -1;
    	}
    	else if (ret == 1)	//nand full and delete file
    	{
    		for(i=0; i<1600; i++)
    		{
    			sprintf(path_name_check,"/mnt/nand/mm%d",i);
                unlink(path_name_check);
        	}
        	free(a_buf_write);
    		free(a_buf_read);
    		printf("nand full and delete file over!\n");
    		return 1;
    	}
    	else 				//go on
    	{
    		if( write_read_nandflash(loop, a_size, a_buf_write, a_buf_read) < 0 )
    		{
    			printf("write_read nand flash wrong!\n");
    			return -1;
    		}
    		sleep(0.1);
    		loop ++;
    	}
    }
}

int check_remain_space(void)
{
    int stat_flag = 0;
    struct statfs nandflash_stat;
    long hdisk_remainder_space = 0;
    
    stat_flag = statfs("/mnt/nand", &nandflash_stat);//获取nandflash的信息
    if(stat_flag < 0)
    {
    	printf("get nandflash info error!\n");
        return -1;	//fail
    }
    
    hdisk_remainder_space = (float)nandflash_stat.f_bsize * nandflash_stat.f_bfree / 1024;	//检测磁盘空间
    if(hdisk_remainder_space < 128 * 1024) 	//至少保留128M的空间
    {
    	printf("remain 128!\n");
    	return 1;	//full
	}
	return 0;		//normal
}

int write_read_nandflash(unsigned int i,int file_size,char *write_buf,char *read_buf)
{
	FILE *fp;
	char path_name[32];
    unsigned long buf_count=0;
    struct stat name_buf;
        
    sprintf(path_name,"/mnt/nand/mm%d",i);
    stat(path_name, &name_buf);
   	if(errno != ENOENT) 			//文件存在,则删除
   	{
   		unlink(path_name);		//不能重名
        sleep(0.1);
   	}
    if((fp=fopen(path_name,"w"))==NULL)
    {
    	printf("fopen failed!\n");
        return -1;
    }

    fwrite(write_buf,file_size,1,fp);
    fclose(fp);
    
    printf("%d:\t",test_count);
	printf("write file name is:%s\n",path_name);
    if((fp=fopen(path_name,"r"))==NULL)
    {
    	printf("fopen failed!\n");
        return -1;
    }
    fread(read_buf,file_size,1,fp);
    
    for(buf_count=0;buf_count<(file_size-1);buf_count++)	//将master/slave文件写到nandflash中的内容读出来比较
    {
    	if(read_buf[buf_count]!=write_buf[buf_count])
        {
        	system("date");//出错的时候打印的系统时间
            printf("file name is %s:\n",path_name);
            sleep(1);
            return -1;  
        }
    }
    fclose(fp);
    return 0;
}


  写完了测试c代码,万里长征走了一大半。剩下的就是如何使这段代码运行从而达到想要的效果。

  首先将该该代码放在Linux工程下,具体放在哪个目录下并没有规定,我将其放在\platform\sys目录下,并将该目录下的Makefile进行了相应的修改:

all_targets := $(NAND_NAME)

NAND_NAME =nand_test

NANDTEST_OBJS = $(shell /bin/pwd)/nand_test.o

$(NAND_NAME): $(NAND_NAME).dbg
    $(OBJCOPY) --strip-debug $< $@
    cp nand_test ../../build/exec/ -f
    $(RM) *.o *.a

$(NAND_NAME).dbg: $(NANDTEST_OBJS)
    @rm -f $@    # Prevent core dump if currently running
    @echo Linking $@ # This is needed for error parsing
    $(CC) $(CFLAGS) -o $@ $(NANDTEST_OBJS)  \
    -Wl,--start-group  $(LIBS) -Wl,--end-group $(LDFLAGS)

  在编译的时候,总的Makefile会调用该文件下的Makefile,有了上述语句,会对该文件进行编译,在当前目录下产生一个名为nand_test的文件,并将nand_test文件复制到\build\exec文件夹下,这还不够,因为这还是在本地,需要将其打包到rootfs中,这样才能在加载rootfs的时候将该程序加载到目标板的文件系统中。

  在工程根目录下的Makefile中需要加上:

sudo cp -rfa ${BUILD_DIR}/exec/nand_test ${ROOTFS_DIR}/mnt/application/

  这样,在打包rootfs的时候就会将nand_test包含进去。

  这些操作完成之后,编译,加载,等应用程序起来之后进入shell。在我当前的系统中,nand挂载在/mnt目录下,因此进入mnt目录,下面有子目录application和nand,可以在application文件夹下找到我们编译生成的nand_test,此时就可以通过./nand_test的方式对nand进行测试了。





  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值