Zynq讀寫SD卡
之前一直沒有寫過部落格,也不知道如何開始,現在想記錄一下自己做過的事情,以後回看還能記得更快。那就以此為開始吧~~~
專案需要,要實現一個將資料寫入到SD卡中的小demo,查找了一些資料,最後終於實現,將具體實現方案記錄如下。
1.搭建Zynq硬體平臺,根據開發板及自己需要設定好DDR、PL時鐘、外設等,本實驗要選中SD0、UART1;
2.搭建好硬體平臺如下所示,生成bit檔案並匯出到SDK中。
3.建立Appliaction Project,選擇Helloworld就行。讀寫SD卡用到了xilffs庫,所以需要在bsp中新增xilffs庫,同時選中xilffs庫做如下修改配置。
在配置上,主要參考了這位博主:https://blog.csdn.net/pro_he/article/details/79937426#zedboard四嵌入式應用程式開發例項三寫入資料到sd卡txt檔案中。
4.先測試官方提供例程,找到Xilinx Vivado安裝目錄下的xilffs提供程式碼,按照版本選擇,我的是3.7,D:\Xilinx\SDK\2017.4\data\embeddedsw\lib\sw_services\xilffs_v3_7\examples,將example內容拷貝到helloworld.c中。
這裡面主要就是實現了向SD卡中寫資料,再讀出寫入的資料,最後做判斷比較兩者資料,比較簡單。但程式碼提供的是生成了一個Test.bin
將其用:%!xxd轉換後,可看出具體資料,寫入是沒有問題的。
5.如何將資料提取出來去使用呢?我用的是UltraEdit,開啟如下
選中所有資料,右鍵 ——> 十六進位制複製選定檢視(V),貼上到Test.c檔案中,然後刪除掉不需要的列就可以了。
6.讀寫SD卡的程式碼如下:
/***************************** Include Files *********************************/ #include "xparameters.h" /* SDK generated parameters */ #include "xsdps.h" /* SD device driver */ #include "xil_printf.h" #include "ff.h" #include "xil_cache.h" #include "xplatform_info.h" /************************** Constant Definitions *****************************/ /**************************** Type Definitions *******************************/ /***************** Macros (Inline Functions) Definitions *********************/ /************************** Function Prototypes ******************************/ int FfsSdPolledExample(void); /************************** Variable Definitions *****************************/ static FIL fil; /* File object */ static FATFS fatfs; /* * To test logical drive 0, FileName should be "0:/<File name>" or * "<file_name>". For logical drive 1, FileName should be "1:/<file_name>" */ static char FileName[32] = "Test.bin"; static char *SD_File; u32 Platform; #ifdef __ICCARM__ #pragma data_alignment = 32 u8 DestinationAddress[10*1024*1024]; u8 SourceAddress[10*1024*1024]; #pragma data_alignment = 4 #else u8 DestinationAddress[10*1024*1024] __attribute__ ((aligned(32))); u8 SourceAddress[10*1024*1024] __attribute__ ((aligned(32))); #endif #define TEST 7 /*****************************************************************************/ /** * * Main function to call the SD example. * * @param None * * @return XST_SUCCESS if successful, otherwise XST_FAILURE. * * @note None * ******************************************************************************/ int main(void) { int Status; xil_printf("SD Polled File System Example Test \r\n"); Status = FfsSdPolledExample(); if (Status != XST_SUCCESS) { xil_printf("SD Polled File System Example Test failed \r\n"); return XST_FAILURE; } xil_printf("Successfully ran SD Polled File System Example Test \r\n"); return XST_SUCCESS; } /*****************************************************************************/ /** * * File system example using SD driver to write to and read from an SD card * in polled mode. This example creates a new file on an * SD card (which is previously formatted with FATFS), write data to the file * and reads the same data back to verify. * * @param None * * @return XST_SUCCESS if successful, otherwise XST_FAILURE. * * @note None * ******************************************************************************/ int FfsSdPolledExample(void) { FRESULT Res; UINT NumBytesRead; UINT NumBytesWritten; u32 BuffCnt; u32 FileSize = (8*1024*1024); /* * To test logical drive 0, Path should be "0:/" * For logical drive 1, Path should be "1:/" */ TCHAR *Path = "0:/"; Platform = XGetPlatform_Info(); if (Platform == XPLAT_ZYNQ_ULTRA_MP) { /* * Since 8MB in Emulation Platform taking long time, reduced * file size to 8KB. */ FileSize = 8*1024; } for(BuffCnt = 0; BuffCnt < FileSize; BuffCnt++){ SourceAddress[BuffCnt] = TEST + BuffCnt; } /* * Register volume work area, initialize device */ Res = f_mount(&fatfs, Path, 0); if (Res != FR_OK) { return XST_FAILURE; } /* * Path - Path to logical driver, 0 - FDISK format. * 0 - Cluster size is automatically determined based on Vol size. */ Res = f_mkfs(Path, 0, 0); if (Res != FR_OK) { return XST_FAILURE; } /* * Open file with required permissions. * Here - Creating new file with read/write permissions. . * To open file with write permissions, file system should not * be in Read Only mode. */ SD_File = (char *)FileName; Res = f_open(&fil, SD_File, FA_CREATE_ALWAYS | FA_WRITE | FA_READ); if (Res) { return XST_FAILURE; } /* * Pointer to beginning of file . */ Res = f_lseek(&fil, 0); if (Res) { return XST_FAILURE; } /* * Write data to file. */ Res = f_write(&fil, (const void*)SourceAddress, FileSize, &NumBytesWritten); if (Res) { return XST_FAILURE; } /* * Pointer to beginning of file . */ Res = f_lseek(&fil, 0); if (Res) { return XST_FAILURE; } /* * Read data from file. */ Res = f_read(&fil, (void*)DestinationAddress, FileSize, &NumBytesRead); if (Res) { return XST_FAILURE; } /* * Data verification */ for(BuffCnt = 0; BuffCnt < FileSize; BuffCnt++){ if(SourceAddress[BuffCnt] != DestinationAddress[BuffCnt]){ return XST_FAILURE; } } /* * Close file. */ Res = f_close(&fil); if (Res) { return XST_FAILURE; } return XST_SUCCESS; }
最後根據自己的需要進行修改就行,我用到的是修改了SourceAddress[ ]的大小以及內容取值。
u8 SourceAddress[10*1024*1024];
for(BuffCnt = 0; BuffCnt < FileSize; BuffCnt++){
SourceAddress[BuffCnt] = TEST + BuffCnt;
}