123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658 |
- /*
- *********************************************************************************************************
- *
- * 模块名称 : NAND Flash Fat文件系统演示模块。
- * 文件名称 : demo_nand_fatfs.c
- * 版 本 : V1.0
- * 说 明 : 该例程移植FatFS文件系统(版本 R0.09b),演示如何创建文件、读取文件、创建目录和删除文件
- * 并测试了文件读写速度。
- *
- * 修改记录 :
- * 版本号 日期 作者 说明
- * V1.0 2013-02-01 armfly 正式发布
- * V1.1 2013-06-20 armfly 正式发布
- *
- * Copyright (C), 2013-2014, 安富莱电子 www.armfly.com
- *
- *********************************************************************************************************
- */
- #include "bsp.h"
- #include "ff.h" /* FatFS文件系统模块*/
- #include "demo_nand_fatfs.h"
- /* 用于测试读写速度 */
- #define TEST_FILE_LEN (2*1024*1024) /* 用于测试的文件长度 */
- #define BUF_SIZE (4*1024) /* 每次读写SD卡的最大数据长度 */
- uint8_t g_TestBuf[BUF_SIZE];
- /* 仅允许本文件内调用的函数声明 */
- static void DispMenu(void);
- static void ViewRootDir(void);
- static void CreateNewFile(void);
- static void ReadFileData(void);
- static void CreateDir(void);
- static void DeleteDirFile(void);
- static void WriteFileTest(void);
- /*
- *********************************************************************************************************
- * 函 数 名: DemoFatFS
- * 功能说明: FatFS文件系统演示主程序
- * 形 参:无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void DemoFatFS(void)
- {
- uint8_t cmd;
- /* 打印命令列表,用户可以通过串口操作指令 */
- DispMenu();
- while(1)
- {
- bsp_Idle(); /* 这个函数在bsp.c文件。用户可以修改这个函数实现CPU休眠和喂狗 */
-
- //cmd = getchar(); /* 从串口读入一个字符 (阻塞方式) */
- if (1) /* 从串口读入一个字符(非阻塞方式) */
- {
- printf("\r\n------------------------------------------------\r\n");
- switch ('2')
- {
- case '1':
- printf("【1 - ViewRootDir】\r\n");
- ViewRootDir(); /* 显示根目录下的文件名 */
- break;
- case '2':
- printf("【2 - CreateNewFile】\r\n");
- CreateNewFile(); /* 创建一个新文件,写入一个字符串 */
- break;
- case '3':
- printf("【3 - ReadFileData】\r\n");
- ReadFileData(); /* 读取根目录下armfly.txt的内容 */
- break;
- case '4':
- printf("【4 - CreateDir】\r\n");
- CreateDir(); /* 创建目录 */
- break;
- case '5':
- printf("【5 - DeleteDirFile】\r\n");
- DeleteDirFile(); /* 删除目录和文件 */
- break;
- case '6':
- printf("【6 - TestSpeed】\r\n");
- WriteFileTest(); /* 速度测试 */
- break;
- case '0':
- printf("Start Format(Low Level) NAND Flash......\r\n");
- NAND_Format();
- printf("NAND Flash Format Ok\r\n");
- break;
- default:
- DispMenu();
- break;
- }
- }
- }
- }
- /*
- *********************************************************************************************************
- * 函 数 名: DispMenu
- * 功能说明: 显示操作提示菜单
- * 形 参:无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void DispMenu(void)
- {
- printf("\r\n------------------------------------------------\r\n");
- printf("请选择操作命令:\r\n");
- printf("1 - 显示根目录下的文件列表\r\n");
- printf("2 - 创建一个新文件armfly.txt\r\n");
- printf("3 - 读armfly.txt文件的内容\r\n");
- printf("4 - 创建目录\r\n");
- printf("5 - 删除文件和目录\r\n");
- printf("6 - 读写文件速度测试\r\n");
- printf("0 - NAND Flash 低级格式化\r\n");
- }
- /*
- *********************************************************************************************************
- * 函 数 名: ViewRootDir
- * 功能说明: 显示SD卡根目录下的文件名
- * 形 参:无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void ViewRootDir(void)
- {
- /* 本函数使用的局部变量占用较多,请修改启动文件,保证堆栈空间够用 */
- FRESULT result;
- FATFS fs;
- DIR DirInf;
- FILINFO FileInf;
- uint32_t cnt = 0;
- char lfname[256];
- /* 挂载文件系统 */
- result = f_mount(&fs, FS_VOLUME_NAND, 0); /* Mount a logical drive */
- if (result != FR_OK)
- {
- printf("挂载文件系统失败 (%d)\r\n", result);
- }
- /* 打开根文件夹 */
- result = f_opendir(&DirInf, "0:/"); /* 1: 表示盘符 */
- if (result != FR_OK)
- {
- printf("打开根目录失败 (%d)\r\n", result);
- return;
- }
- /* 读取当前文件夹下的文件和目录 */
- FileInf.lfname = lfname;
- FileInf.lfsize = 256;
- printf("属性 | 文件大小 | 短文件名 | 长文件名\r\n");
- for (cnt = 0; ;cnt++)
- {
- result = f_readdir(&DirInf,&FileInf); /* 读取目录项,索引会自动下移 */
- if (result != FR_OK || FileInf.fname[0] == 0)
- {
- break;
- }
- if (FileInf.fname[0] == '.')
- {
- continue;
- }
- /* 判断是文件还是子目录 */
- if (FileInf.fattrib & AM_DIR)
- {
- printf("(0x%02d)目录 ", FileInf.fattrib);
- }
- else
- {
- printf("(0x%02d)文件 ", FileInf.fattrib);
- }
- /* 打印文件大小, 最大4G */
- printf(" %10d", FileInf.fsize);
- printf(" %s |", FileInf.fname); /* 短文件名 */
- printf(" %s\r\n", (char *)FileInf.lfname); /* 长文件名 */
- }
- /* 卸载文件系统 */
- f_mount(NULL, FS_VOLUME_NAND, 0);
- }
- /*
- *********************************************************************************************************
- * 函 数 名: CreateNewFile
- * 功能说明: 在SD卡创建一个新文件,文件内容填写“www.armfly.com”
- * 形 参:无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void CreateNewFile(void)
- {
- /* 本函数使用的局部变量占用较多,请修改启动文件,保证堆栈空间够用 */
- FRESULT result;
- FATFS fs;
- FIL file;
- DIR DirInf;
- uint32_t bw;
- /* 挂载文件系统 */
- result = f_mount(&fs, FS_VOLUME_NAND, 0); /* Mount a logical drive */
- if (result != FR_OK)
- {
- printf("挂载文件系统失败 (%d)\r\n", result);
- }
- /* 打开根文件夹 */
- result = f_opendir(&DirInf, "0:/"); /* 1: 表示盘符 */
- if(result==FR_NO_FILESYSTEM) //如果返回值为无filesystem则创建文件系统
- {
- f_mkfs("0:",0,0);
- }
- if (result != FR_OK)
- {
- printf("打开根目录失败 (%d)\r\n", result);
- return;
- }
- /* 打开文件 */
- result = f_open(&file, "0:/armfly.txt", FA_CREATE_ALWAYS | FA_WRITE);
- /* 写一串数据 */
- result = f_write(&file, "FatFS Write Demo \r\n www.armfly.com \r\n", 34, &bw);
- if (result == FR_OK)
- {
- printf("armfly.txt 文件写入成功\r\n");
- }
- else
- {
- printf("armfly.txt 文件写入失败\r\n");
- }
- /* 关闭文件*/
- f_close(&file);
- /* 卸载文件系统 */
- f_mount(NULL, FS_VOLUME_NAND, 0);
- }
- /*
- *********************************************************************************************************
- * 函 数 名: ReadFileData
- * 功能说明: 读取文件armfly.txt前128个字符,并打印到串口
- * 形 参:无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void ReadFileData(void)
- {
- /* 本函数使用的局部变量占用较多,请修改启动文件,保证堆栈空间够用 */
- FRESULT result;
- FATFS fs;
- FIL file;
- DIR DirInf;
- uint32_t bw;
- char buf[128];
- /* 挂载文件系统 */
- result = f_mount(&fs, FS_VOLUME_NAND, 0); /* Mount a logical drive */
- if (result != FR_OK)
- {
- printf("挂载文件系统失败(%d)\r\n", result);
- }
- /* 打开根文件夹 */
- result = f_opendir(&DirInf, "0:/"); /* 1: 表示盘符 */
- if (result != FR_OK)
- {
- printf("打开根目录失败(%d)\r\n", result);
- return;
- }
- /* 打开文件 */
- result = f_open(&file, "0:/armfly.txt", FA_OPEN_EXISTING | FA_READ);
- if (result != FR_OK)
- {
- printf("Don't Find File : armfly.txt\r\n");
- return;
- }
- /* 读取文件 */
- result = f_read(&file, &buf, sizeof(buf) - 1, &bw);
- if (bw > 0)
- {
- buf[bw] = 0;
- printf("\r\narmfly.txt 文件内容 : \r\n%s\r\n", buf);
- }
- else
- {
- printf("\r\narmfly.txt 文件内容 : \r\n");
- }
- /* 关闭文件*/
- f_close(&file);
- /* 卸载文件系统 */
- f_mount(NULL, FS_VOLUME_NAND, 0);
- }
- /*
- *********************************************************************************************************
- * 函 数 名: CreateDir
- * 功能说明: 在SD卡根目录创建Dir1和Dir2目录,在Dir1目录下创建子目录Dir1_1
- * 形 参:无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void CreateDir(void)
- {
- /* 本函数使用的局部变量占用较多,请修改启动文件,保证堆栈空间够用 */
- FRESULT result;
- FATFS fs;
- /* 挂载文件系统 */
- result = f_mount(&fs, FS_VOLUME_NAND, 0); /* Mount a logical drive */
- if (result != FR_OK)
- {
- printf("挂载文件系统失败 (%d)\r\n", result);
- }
- /* 创建目录/Dir1 */
- result = f_mkdir("0:/Dir1");
- if (result == FR_OK)
- {
- printf("f_mkdir Dir1 Ok\r\n");
- }
- else if (result == FR_EXIST)
- {
- printf("Dir1 目录已经存在(%d)\r\n", result);
- }
- else
- {
- printf("f_mkdir Dir1 失败 (%d)\r\n", result);
- return;
- }
- /* 创建目录/Dir2 */
- result = f_mkdir("0:/Dir2");
- if (result == FR_OK)
- {
- printf("f_mkdir Dir2 Ok\r\n");
- }
- else if (result == FR_EXIST)
- {
- printf("Dir2 目录已经存在(%d)\r\n", result);
- }
- else
- {
- printf("f_mkdir Dir2 失败 (%d)\r\n", result);
- return;
- }
- /* 创建子目录 /Dir1/Dir1_1 注意:创建子目录Dir1_1时,必须先创建好Dir1 */
- result = f_mkdir("0:/Dir1/Dir1_1"); /* */
- if (result == FR_OK)
- {
- printf("f_mkdir Dir1_1 成功\r\n");
- }
- else if (result == FR_EXIST)
- {
- printf("Dir1_1 目录已经存在 (%d)\r\n", result);
- }
- else
- {
- printf("f_mkdir Dir1_1 失败 (%d)\r\n", result);
- return;
- }
- /* 卸载文件系统 */
- f_mount(NULL, FS_VOLUME_NAND, 0);
- }
- /*
- *********************************************************************************************************
- * 函 数 名: DeleteDirFile
- * 功能说明: 删除SD卡根目录下的 armfly.txt 文件和 Dir1,Dir2 目录
- * 形 参:无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void DeleteDirFile(void)
- {
- /* 本函数使用的局部变量占用较多,请修改启动文件,保证堆栈空间够用 */
- FRESULT result;
- FATFS fs;
- char FileName[13];
- uint8_t i;
- /* 挂载文件系统 */
- result = f_mount(&fs, FS_VOLUME_NAND, 0); /* Mount a logical drive */
- if (result != FR_OK)
- {
- printf("挂载文件系统失败 (%d)\r\n", result);
- }
- #if 0
- /* 打开根文件夹 */
- result = f_opendir(&DirInf, "0:/"); /* 如果不带参数,则从当前目录开始 */
- if (result != FR_OK)
- {
- printf("打开根目录失败(%d)\r\n", result);
- return;
- }
- #endif
- /* 删除目录/Dir1 【因为还存在目录非空(存在子目录),所以这次删除会失败】*/
- result = f_unlink("0:/Dir1");
- if (result == FR_OK)
- {
- printf("删除目录Dir1成功\r\n");
- }
- else if (result == FR_NO_FILE)
- {
- printf("没有发现文件或目录 :%s\r\n", "/Dir1");
- }
- else
- {
- printf("删除Dir1失败(错误代码 = %d) 文件只读或目录非空\r\n", result);
- }
- /* 先删除目录/Dir1/Dir1_1 */
- result = f_unlink("0:/Dir1/Dir1_1");
- if (result == FR_OK)
- {
- printf("删除子目录/Dir1/Dir1_1成功\r\n");
- }
- else if ((result == FR_NO_FILE) || (result == FR_NO_PATH))
- {
- printf("没有发现文件或目录 :%s\r\n", "/Dir1/Dir1_1");
- }
- else
- {
- printf("删除子目录/Dir1/Dir1_1失败(错误代码 = %d) 文件只读或目录非空\r\n", result);
- }
- /* 先删除目录/Dir1 */
- result = f_unlink("0:/Dir1");
- if (result == FR_OK)
- {
- printf("删除目录Dir1成功\r\n");
- }
- else if (result == FR_NO_FILE)
- {
- printf("没有发现文件或目录 :%s\r\n", "/Dir1");
- }
- else
- {
- printf("删除Dir1失败(错误代码 = %d) 文件只读或目录非空\r\n", result);
- }
- /* 删除目录/Dir2 */
- result = f_unlink("0:/Dir2");
- if (result == FR_OK)
- {
- printf("删除目录 Dir2 成功\r\n");
- }
- else if (result == FR_NO_FILE)
- {
- printf("没有发现文件或目录 :%s\r\n", "/Dir2");
- }
- else
- {
- printf("删除Dir2 失败(错误代码 = %d) 文件只读或目录非空\r\n", result);
- }
- /* 删除文件 armfly.txt */
- result = f_unlink("0:/armfly.txt");
- if (result == FR_OK)
- {
- printf("删除文件 armfly.txt 成功\r\n");
- }
- else if (result == FR_NO_FILE)
- {
- printf("没有发现文件或目录 :%s\r\n", "armfly.txt");
- }
- else
- {
- printf("删除armfly.txt失败(错误代码 = %d) 文件只读或目录非空\r\n", result);
- }
- /* 删除文件 speed1.txt */
- for (i = 0; i < 20; i++)
- {
- sprintf(FileName, "0:/Speed%02d.txt", i); /* 每写1次,序号递增 */
- result = f_unlink(FileName);
- if (result == FR_OK)
- {
- printf("删除文件%s成功\r\n", FileName);
- }
- else if (result == FR_NO_FILE)
- {
- printf("没有发现文件:%s\r\n", FileName);
- }
- else
- {
- printf("删除%s文件失败(错误代码 = %d) 文件只读或目录非空\r\n", FileName, result);
- }
- }
- /* 卸载文件系统 */
- f_mount(NULL, FS_VOLUME_NAND, 0);
- }
- /*
- *********************************************************************************************************
- * 函 数 名: WriteFileTest
- * 功能说明: 测试文件读写速度
- * 形 参:无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void WriteFileTest(void)
- {
- /* 本函数使用的局部变量占用较多,请修改启动文件,保证堆栈空间够用 */
- FRESULT result;
- FATFS fs;
- FIL file;
- DIR DirInf;
- uint32_t bw;
- uint32_t i,k;
- uint32_t runtime1,runtime2,timelen;
- uint8_t err = 0;
- char TestFileName[13];
- static uint8_t s_ucTestSn = 0;
- for (i = 0; i < sizeof(g_TestBuf); i++)
- {
- g_TestBuf[i] = (i / 512) + '0';
- }
- /* 挂载文件系统 */
- result = f_mount(&fs, FS_VOLUME_NAND, 0); /* Mount a logical drive */
- if (result != FR_OK)
- {
- printf("挂载文件系统失败 (%d)\r\n", result);
- }
- /* 打开根文件夹 */
- result = f_opendir(&DirInf, "0:/"); /* 如果不带参数,则从当前目录开始 */
- if (result != FR_OK)
- {
- printf("打开根目录失败 (%d)\r\n", result);
- return;
- }
- /* 打开文件 */
- sprintf(TestFileName, "0:/Speed%02d.txt", s_ucTestSn++); /* 每写1次,序号递增 */
- result = f_open(&file, TestFileName, FA_CREATE_ALWAYS | FA_WRITE);
- /* 写一串数据 */
- printf("开始写文件%s %dKB ...\r\n", TestFileName, TEST_FILE_LEN / 1024);
- runtime1 = 10; /* 读取系统运行时间 */
- for (i = 0; i < TEST_FILE_LEN / BUF_SIZE; i++)
- {
- result = f_write(&file, g_TestBuf, sizeof(g_TestBuf), &bw);
- if (result == FR_OK)
- {
- if (((i + 1) % 8) == 0)
- {
- printf(".");
- }
- }
- else
- {
- err = 1;
- printf("%s文件写失败\r\n", TestFileName);
- break;
- }
- }
- runtime2 =100; /* 读取系统运行时间 */
- if (err == 0)
- {
- timelen = (runtime2 - runtime1);
- printf("\r\n 写耗时 : %dms 平均写速度 : %dB/S (%dKB/S)\r\n",
- timelen,
- (TEST_FILE_LEN * 1000) / timelen,
- ((TEST_FILE_LEN / 1024) * 1000) / timelen);
- }
- f_close(&file); /* 关闭文件*/
- /* 开始读文件测试 */
- result = f_open(&file, TestFileName, FA_OPEN_EXISTING | FA_READ);
- if (result != FR_OK)
- {
- printf("没有找到文件: %s\r\n", TestFileName);
- return;
- }
- printf("开始读文件 %dKB ...\r\n", TEST_FILE_LEN / 1024);
- runtime1 = 10; /* 读取系统运行时间 */
- for (i = 0; i < TEST_FILE_LEN / BUF_SIZE; i++)
- {
- result = f_read(&file, g_TestBuf, sizeof(g_TestBuf), &bw);
- if (result == FR_OK)
- {
- if (((i + 1) % 8) == 0)
- {
- printf(".");
- }
- /* 比较写入的数据是否正确,此语句会导致读卡速度结果降低到 3.5MBytes/S */
- for (k = 0; k < sizeof(g_TestBuf); k++)
- {
- if (g_TestBuf[k] != (k / 512) + '0')
- {
- err = 1;
- printf("Speed1.txt 文件读成功,但是数据出错\r\n");
- break;
- }
- }
- if (err == 1)
- {
- break;
- }
- }
- else
- {
- err = 1;
- printf("Speed1.txt 文件读失败\r\n");
- break;
- }
- }
- runtime2 = 100; /* 读取系统运行时间 */
- if (err == 0)
- {
- timelen = (runtime2 - runtime1);
- printf("\r\n 读耗时 : %dms 平均读速度 : %dB/S (%dKB/S)\r\n", timelen,
- (TEST_FILE_LEN * 1000) / timelen, ((TEST_FILE_LEN / 1024) * 1000) / timelen);
- }
- /* 关闭文件*/
- f_close(&file);
- /* 卸载文件系统 */
- f_mount(NULL, FS_VOLUME_NAND, 0);
- }
- /***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/
|