zedboard第十四课(SD卡,FAT32读写)

SDK的standalone已移植好了FatFs库(SDK中叫做xilffs),所以在BSP中添加xilffs库后就可以在程序中使用FatFs中各API来操作SD卡,该库支持FAT12, FAT16 FAT32 and exFAT文件系统(本例将SD卡格式化为FAT32)。
打开BSP中的system.mss,可以修改BSP的配置信息。
我们选中xilffs这个lib,并在左侧选项卡中,对这个lib进行选项配置。确保fs_interface这个选项的值是true。还有use_lfn这个选项为true。还有use_strfunc这个选项为2,用来使能f_printf()函数。
之后我们可以在BSP中看到xilffs_v3_7这个文件夹。
diskio.c是底层操作函数,和板子相关的硬件操作。
ff.c是文件操作函数,和FATFS相关的文件操作。
我们主要使用的,就是FATFS相关的文件操作。

注意,之前版本中的f_write的关于section的BUG,在V3_7这个版本里,已经被修正了。即使写入的不是256的整数倍也是可以的,而且对写入的长度不再有最小长度的要求,哪怕只有1个BYTE都是可以的。

其中的几个重要函数是:

FRESULT f_mount (
	FATFS* fs,			/* Pointer to the file system object (NULL:unmount)*/
	const TCHAR* path,	/* Logical drive number to be mounted/unmounted */
	BYTE opt			/* 0:Do not mount (delayed mount), 1:Mount immediately */
)

这个函数用来挂载SD卡上的FAT32。

FRESULT f_open (
	FIL* fp,			/* Pointer to the blank file object */
	const TCHAR* path,	/* Pointer to the file name */
	BYTE mode			/* Access mode and file open mode flags */
)

这个函数用来打开一个FILE。

FRESULT f_lseek (
	FIL* fp,		/* Pointer to the file object */
	DWORD ofs		/* File pointer from top of file */
)

这个函数用来标记LSEEK。

FRESULT f_read (
	FIL* fp, 		/* Pointer to the file object */
	void* buff,		/* Pointer to data buffer */
	UINT btr,		/* Number of bytes to read */
	UINT* br		/* Pointer to number of bytes read */
)

这个函数用来读取文件中的数据,并转存到buff中来。

FRESULT f_write (
	FIL* fp,			/* Pointer to the file object */
	const void *buff,	/* Pointer to the data to be written */
	UINT btw,			/* Number of bytes to write */
	UINT* bw			/* Pointer to number of bytes written */
)

这个函数用来把buff中的数据,写入FILE中。

FRESULT f_close (
	FIL *fp		/* Pointer to the file object to be closed */
)

这个函数用来关闭一个FILE。

还有其他的一些函数,可以在ff.c文件中查看源代码,了解它的功能。

下面进行一些情景分析。

static FATFS fatfs;

声明一个静态的数据对象,FATFS类型,它用来作为SD卡上的FAT32文件系统的句柄。

#define FILE "test123456789.txt"
static  char src_str[MAX_LEN] = { 0 } ;
static  char dst_str[MAX_LEN] = { 0 } ;

定义缓冲区,定义文件名字符串。

int SD_Init()
{
FRESULT rc;
rc = f_mount(&fatfs,"",0);
if(rc)
{
xil_printf("ERROR : f_mount returned %d\r\n",rc);
return XST_FAILURE;
}
return XST_SUCCESS;
}

定义了初始化函数。主要是mount文件系统,利用空串,检索到系统内的默认的逻辑卷0,并初始化FATFS数据对象。
这是一个比较费解的地方,这里多做一些说明。
在fatfs外挂一个设备的时候,通过 f_mount(&fs, “”, 1);就可以访问,而在多个设备时,就得指定磁盘号。
支持以下两种方式:
f_mount(&fs, “1:”, 1);
f_mount(&fs, “1:/”, 1);

这种方式不支持:
f_mount(&fs, “1”, 1);

result = f_mount(&fs, "", 1);    /* Mount a logical drive */
 result = f_mount(&fs, "1:/", 1);    /* Mount a logical drive */
result  = f_mount(NULL, "1:/", 1); /* UnMount a logical drive */

这是f_mount使用的样例。

int SD_Transfer_read(char *FileName,u32 DestinationAddress,u32 ByteLength)
{
FIL fil;
FRESULT rc;
UINT br;

rc = f_open(&fil,FileName,FA_READ);
if(rc)
{
xil_printf("ERROR : f_open returned %d\r\n",rc);
return XST_FAILURE;
}
rc = f_lseek(&fil, 0);
if(rc)
{
xil_printf("ERROR : f_lseek returned %d\r\n",rc);
return XST_FAILURE;
}
rc = f_read(&fil, (void*)DestinationAddress,ByteLength,&br);
printf("act read len is %d \n\r",br );
if(rc)
{
xil_printf("ERROR : f_read returned %d\r\n",rc);
return XST_FAILURE;
}
rc = f_close(&fil);
if(rc)
{
xil_printf(" ERROR : f_close returned %d\r\n", rc);
return XST_FAILURE;
}
return XST_SUCCESS;
}

定义了读文件数据的函数。

int SD_Transfer_write(char *FileName,u32 SourceAddress,u32 ByteLength)
{
FIL fil;
FRESULT rc;
UINT bw;

rc = f_open(&fil,FileName,FA_CREATE_ALWAYS | FA_WRITE);
if(rc)
{
xil_printf("ERROR : f_open returned %d\r\n",rc);
return XST_FAILURE;
}
rc = f_lseek(&fil, 0);
if(rc)
{
xil_printf("ERROR : f_lseek returned %d\r\n",rc);
return XST_FAILURE;
}
rc = f_write(&fil,(void*) SourceAddress,ByteLength , &bw );
printf("SD_Transfer_write -> f_write result len is %d \n\r" , bw );
if(rc)
{
xil_printf("ERROR : f_write returned %d\r\n", rc);
return XST_FAILURE;
}
rc = f_close(&fil);
if(rc){
xil_printf("ERROR : f_close returned %d\r\n",rc);
return XST_FAILURE;
}
return XST_SUCCESS;
}

定义了写文件数据的函数。

下面来看看在main中如何使用SD的操作函数的具体流程。

r  = SD_Init();
if ( XST_SUCCESS != r ){
	printf("fail to open SD\n\r");
	return 1 ;
}
printf("OK to open SD\n\r");

初始化SD卡。

SD_Transfer_write(FILE,(void *)src_str,(MAX_LEN));
printf("write done SD\n\r");

向FILE中写入buffer里的数据。

SD_Transfer_read(FILE,(void*)dst_str,(MAX_LEN));
printf("read done SD\n\r");

从FILE中读出数据,写入BUFFER。

你可能感兴趣的:(vivado)