我的项目中有记录实时数据的需求,并且这种数据必须能够提取到上位机,因此采用TF卡录取数据势在必行。
对于TF卡读取,还必须支持常见文件系统,否则数据还需要专门的硬件才能读取出来,嵌入式文件系统最常见的无疑是FATFS了,最重要的是完全免费开源,对商用友好。
但是存在问题,TF卡读取存储速度是否跟得上呢?于是必须要测试一下fatfs再rt1064下的写入速度。
(一)创建工程
1-加入组件:
Middleware-file system-fatfs+sd+ram
只需要加入这一个组件,另外的驱动组件和 Middleware-memories-common+sd 就会被自动加入
2-配置引脚
实际上引脚已经被适配好了,就在board文件里,只需要调用
BOARD_InitUSDHC();
即可
3-时钟
时钟也是在生成的时候就配置好了:
把sdmmc_config支持文件拷过来
4-设置fatfs为sd卡器件
这时候会发现source下面多了个ffconf.h文件,这是fatfs的配置文件,默认生成是用内部ram的,这里配置为外部的TF卡。
将
#define RAM_DISK_ENABLE
改为
#define SD_DISK_ENABLE
5-加入头文件
- #include "sdmmc_config.h"
- #include "ff.h"
- #include "diskio.h"
- #include "fsl_sd.h"
- #include "fsl_sd_disk.h"
复制代码
6-加入宏定义
- static FATFS g_fileSystem; /* File system object */
- static FIL g_fileObject; /* File object */
- SDK_ALIGN(uint8_t g_bufferWrite[100], BOARD_SDMMC_DATA_BUFFER_ALIGN_SIZE);
复制代码
7-检测SD卡并上电
- static status_t sdcardWaitCardInsert(void)
- {
- BOARD_SD_Config(&g_sd, NULL, BOARD_SDMMC_SD_HOST_IRQ_PRIORITY, NULL);
- /* SD host init function */
- if (SD_HostInit(&g_sd) != kStatus_Success)
- {
- PRINTF("rnSD host init failrn");
- return kStatus_Fail;
- }
- /* power off card */
- SD_SetCardPower(&g_sd, false);
- /* wait card insert */
- if (SD_PollingCardInsert(&g_sd, kSD_Inserted) == kStatus_Success)
- {
- PRINTF("rnCard inserted.rn");
- /* power on the card */
- SD_SetCardPower(&g_sd, true);
- }
- else
- {
- PRINTF("rnCard detect fail.rn");
- return kStatus_Fail;
- }
- return kStatus_Success;
- }
复制代码
(二)测试fatfs写入速度
1-首先定义两个变量
- const TCHAR driverNumberBuffer[3U] = {SDDISK + '0', ':', '/'};
- FRESULT error;
- //字符串
- memset(g_bufferWrite, 'a', sizeof(g_bufferWrite));
- memset(g_bufferWrite, 'b', sizeof(g_bufferWrite)/2);
- g_bufferWrite[10 - 2U] = 'r';
- g_bufferWrite[10 - 1U] = 'n';
复制代码
2-使用一个GPT定时器计数
启动定时器:
GPT_StartTimer(BOARD_GPT1_PERIPHERAL);
3-初始化TF卡接口:
if (sdcardWaitCardInsert() != kStatus_Success)
return -1;
4-挂载并计时
- if (f_mount(&g_fileSystem, driverNumberBuffer, 0U))
- {
- PRINTF("Mount volume failed.rn");
- return -1;
- }
- uint32_t t_mountTime = GPT_GetCurrentTimerCount(BOARD_GPT1_PERIPHERAL);
复制代码
5-驱动
- error = f_chdrive((char const *)&driverNumberBuffer[0U]);
- if (error)
- {
- PRINTF("Change drive failed.rn");
- return -1;
- }
- uint32_t t_chdrive = GPT_GetCurrentTimerCount(BOARD_GPT1_PERIPHERAL);
复制代码
6-创建文件夹
- error = f_mkdir(_T("/dir_1"));
- if (error)
- {
- if (error == FR_EXIST)
- {
- PRINTF("Directory exists.rn");
- }
- else
- {
- PRINTF("Make directory failed.rn");
- return -1;
- }
- }
- uint32_t t_mkdir = GPT_GetCurrentTimerCount(BOARD_GPT1_PERIPHERAL);
复制代码
7-打开文件
- error = f_open(&g_fileObject, _T("/dir_1/data.txt"), (FA_WRITE | FA_READ | FA_OPEN_APPEND ));
- if (error)
- {
- if (error == FR_EXIST) PRINTF("File exists.rn");
- else{PRINTF("Open file failed.rn");return -1;}
- }
- uint32_t t_open = GPT_GetCurrentTimerCount(BOARD_GPT1_PERIPHERAL);
复制代码
8-写入
- error = f_write(&g_fileObject, g_bufferWrite, sizeof(g_bufferWrite), &bytesWritten);
- if ((error) || (bytesWritten != sizeof(g_bufferWrite)))
- {
- PRINTF("Write file failed. rn");
- return -1;
- }
- uint32_t t_write = GPT_GetCurrentTimerCount(BOARD_GPT1_PERIPHERAL);
复制代码
9-关闭
- if (f_close(&g_fileObject))
- {
- PRINTF("rnClose file failed.rn");
- return -1;
- }
复制代码
10-打印出来
- PRINTF("t_mount:%drn",t_mountTime);
- PRINTF("t_chdrive:%drn",t_chdrive);
- PRINTF("t_mkdir:%drn",t_mkdir);
- PRINTF("t_open:%drn",t_open);
- PRINTF("t_lseek:%drn",t_lseek);
- PRINTF("t_write:%drn",t_write);
- PRINTF("t_close:%drn",t_close);
- PRINTF("t_size:%drn",t_size);
复制代码
。
t_mount |
| 110016942 | 1466.893 | | 110016418 | 1466.886 | t_chdrive |
| 110017251 | 1466.897 | | 110016707 | 1466.889 | t_mkdir |
| 226354461 | 3018.059 | | 226350886 | 3018.012 | t_open |
| 226385347 | 3018.471 | | 226408050 | 3018.774 | t_lseek |
| 226412100 | 3018.828 | | | | t_write |
| 226413845 | 3018.851 | | 226409926 | 3018.799 | t_close |
| 226606250 | 3021.417 | | 226602074 | 3021.361 | t_size |
| 310 | | | 410 |
|
首先要确定的是,在mount之前和chdrive之前有大段的时间用于初始化TF卡和打印数据,而mkdir因为多次运行的缘故,后面根本不需要创建,这三个时间是没有参考意义的,但可以作为起始的基准。
可以看到,在目前198M的USDHC时钟下,写入100字节只需要不到30us。打开和指针跳转到文末的时间分别在400us以内。考虑到应用中后面四个操作比较频繁,实际上耗时最多的还是close,达到2ms左右,整体耗时3ms左右,还是有比较好的实时性。
0
|
|
|
|