刚学习了一些关于ZYNQ开发板中SD卡读取的内容,想要在这里进行一下总结。
这篇博客主要参考了以下一些博客、网页
[1]. https://forums.xilinx.com/t5/Embedded-Development-Tools/SDK-2015-2-problem-with-xilffs-3-0/td-p/653278
[2].https://github.com/Xilinx/embeddedsw/tree/master/lib/sw_services/xilffs
[3].http://blog.csdn.net/husipeng86/article/details/52262070
[4].http://blog.csdn.net/mcupro/article/details/73694460
[5].http://elm-chan.org/fsw/ff/00index_e.html
ZYNQ嘛,肯定是要进行PS端的配置,配置PS端的时候,其实就是配置SD卡和UART,这些配置参数就跟之前的实验一样,要注意IO Type以及Speed的设置,这里就不着重强调了,下图是我配置完的一个状态,很简单。
导出Hardware,然后Launch SDK,然后新建一个HelloWorld的Application。Xilinx Tools->Board Support Package Setting,双击bsp,勾选xliffs库,这个库是用于SD卡读写的,目前(2018年1月21日)已经更新到版本v3.7了,我目前用的是3.1版本,参考文献【2】是这个库的GitHub,参考文献【5】是这个库的文档说明。
以下是所有的代码,这个代码主要参考文献【4】
#include "platform.h"
#include "xparameters.h"
#include "xil_printf.h"
#include "ff.h"
#include "xdevcfg.h"
static FATFS fatfs;
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;
}
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_open returned %d\r\n",rc);
return XST_FAILURE;
}
rc = f_read(&fil,(void*)DestinationAddress,ByteLength,&br);
if(rc)
{
xil_printf("ERROR:f_open returned %d\r\n",rc);
return XST_FAILURE;
}
rc = f_close(&fil);
if(rc)
{
xil_printf("ERROR:f_open 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);
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;
}
#define FILE "test.txt"
int main()
{
init_platform();
int rc;
const char src_str[] = "hsp test sd card write and read!";
u32 len = strlen(src_str);
rc = SD_Init();
if(XST_SUCCESS != rc)
{
xil_printf("fail to open SD Card~\n\r");
}
else
{
xil_printf("success to open SD Card~\n\r");
}
rc = SD_Transfer_write(FILE,(u32)src_str,(len/256+1)*256);
xil_printf("%d",(len/256+1)*256);
if(XST_SUCCESS != rc)
{
xil_printf("fail to write SD Card~\n\r");
}
else
{
xil_printf("success to write SD Card~\n\r");
}
char dest_str[33];
rc = SD_Transfer_read(FILE,(u32)dest_str,(len+1));
if(XST_SUCCESS != rc)
{
xil_printf("fail to read SD Card~\n\r");
}
else
{
xil_printf("success to read SD Card~\n\r");
}
xil_printf("%s\r\n",dest_str);
printf("SD Card Write and Read Success~");
cleanup_platform();
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
在f_write这个函数后面,原作者有那么一句注释//当直接指定len时没有写出,需要指定较大的长度才会写出,原因未知,于是原作者直接将len+1000,这样呢,问题貌似解决了,但是我比较想知道这个原因,我自己也试了一下,确实写入一小串字符串并写不进去。我查看了其他的文档博客,然后把源代码中的ByteWidth改为了(len/256+1)*256,也就是取了256的整数倍,这样呢,原本想要写入的数据都写入进去了,就是稍微浪费了一点资源。至于为什么写入的数据必须大于某个阈值,或者是为什么必须是256的整数倍这一点呢,我暂时还没找到原因以及更好的解决方案。
在这个库中呢,有一个函数f_printf,但是当我想要用这个函数的时候,却提示 undefined reference to `f_printf’ ,感觉非常奇怪,并不知道问题出在哪里,在.h和.c文件中都有相关定义声明。参考资料【1】似乎是关于这个问题的解决方案,但是我自己试了发现并没有解决这个问题。
这里还有一点要注意的就是SD的磁盘格式,这个库支持FAT16和FAT32,如果是NTFS估计应该识别不了,我用的是FAT32磁盘格式。
既然目前这个库已经更新到了v3.7了,那以上的一些问题是否解决了呢,等我试一下,试完了之后跟大家讲一下。