FATFS写SD卡偶尔出现写失败和打开文件失败
本帖最后由 DX3906 于 2023-12-14 11:34 编辑我在at32f435上用fatfs周期写16KB数据到sd卡,偶尔会出现写文件失败和打开文件失败,有时候重新上电几次之后又能长时间稳定写入,fatfs报错是FR_DISK_ERR,但是sdio驱动和fatfs都是直接用的官方的,换了几张卡都有一定几率出现
想问下各位大佬这可能是哪些方面的问题呢?
这个是我的测试代码,在freertos下跑的,只有这一个任务
void log_store_init(void)
{
FRESULT ret;
ret = f_mount(NULL, "1:", 1);
ret = f_mount(&fs, "1:", 1);
if(ret){
DEBUG_PRINTF("fs mount err:%d.\r\n", ret);
if(ret == FR_NO_FILESYSTEM){
DEBUG_PRINTF("create fatfs..\r\n");
BYTE *work= (BYTE *)pvPortMalloc(FF_MAX_SS);
ret = f_mkfs("1:", 0, work, sizeof(work));
if(ret){
DEBUG_PRINTF("creates fatfs err:%d.\r\n", ret);
return;
}
else{
DEBUG_PRINTF("creates fatfs ok.\r\n");
}
ret = f_mount(NULL, "1:", 1);
ret = f_mount(&fs, "1:", 1);
if(ret){
DEBUG_PRINTF("fs mount err:%d.\r\n", ret);
return;
}
else{
DEBUG_PRINTF("fs mount ok.\r\n");
}
}
else{
return;
}
}
else{
DEBUG_PRINTF("fs mount ok.\r\n");
}
}
char filename[] = "1:/test_data0000.bin";
void write_sd_test(void)
{
FIL file0;
FRESULT ret;
uint32_t len = 0;
static uint64_t total_len = 0;
static uint16_t file_count = 0;
if(file_count >= 940)
{
file_count = 0;
}
char *filename = (char *)pvPortMalloc(22);
sprintf(filename, "1:/test_data%04d.bin", file_count);
if(filename == NULL)
{
DEBUG_PRINTF("firename malloc failed.\r\n");
return;
}
ret = f_open(&file0, filename, FA_WRITE | FA_CREATE_ALWAYS | FA_OPEN_ALWAYS);
if(ret){
DEBUG_PRINTF("open file err:%d.\r\n", ret);
}
else{
DEBUG_PRINTF("open file ok. %s\r\n", filename);
uint8_t *buf = (uint8_t *)pvPortMalloc(16384);
if(buf == NULL)
{
DEBUG_PRINTF("buf malloc failed.\r\n");
if(filename != NULL)
vPortFree(filename);
f_close(&file0);
return;
}
else
{
for(uint32_t i = 0; i < 500; i++)
{
for(uint16_t j = 0; j < 16384; j++)
{
buf = rand();
}
f_lseek(&file0, len);
ret = f_write(&file0, (uint8_t*)buf, 16384, &bytes_written);
if(ret){
DEBUG_PRINTF("write file err:%d.\r\n", ret);
f_close(&file0);
ret = f_mount(NULL, "1:", 1);
ret = f_mount(&fs, "1:", 1);
if(ret){
DEBUG_PRINTF("fs mount err:%d.\r\n", ret);
return;
}
else{
DEBUG_PRINTF("fs mount ok.\r\n");
}
break;
}
else{
f_sync(&file0);
len += bytes_written;
total_len += bytes_written;
DEBUG_PRINTF("write file ok, byte:%u, total:%lld\r\n", bytes_written, total_len);
}
vTaskDelay(1);
}
f_close(&file0);
file_count++;
}
if(buf != NULL)
vPortFree(buf);
}
if(filename != NULL)
vPortFree(filename);
}
static void log_task(void* parameter)
{
portBASE_TYPE uxHighWaterMark;
__IO size_t xFreeStackSpace;
log_store_init();
while(1)
{
xFreeStackSpace = xPortGetFreeHeapSize();
DEBUG_PRINTF("free heap size: %d\r\n", xFreeStackSpace);
write_sd_test();
DEBUG_PRINTF("%s runing\r\n", LOG_TASK_NAME);
vTaskDelay(1);
}
}
1、是不是开DMA了,要特别注意4字节对齐问题。
2、不建议重复的挂载卸载,推荐fopen后,后面仅调用fwrite和f_sync即可,fclose不需要调用,试试是否好点。 频率太高了吧 用的是阻塞读写
开始以为是重新下程序后sd卡内部没复位,想着报错的时候重新挂载初始化一下试试,没有f_close的话文件不会异常吗? 之前遇到过类似的,原因是SD卡用了DMA, UI任务操作LTDC寄存器时 APB2总线会暂停,导致DMA出错 DX3906 发表于 2023-12-14 16:11
用的是阻塞读写
开始以为是重新下程序后sd卡内部没复位,想着报错的时候重新挂载初始化一下试试,没有f_cl ...
不会,f_sync也会将数据实际写入文件。 eric2013 发表于 2023-12-15 08:41
不会,f_sync也会将数据实际写入文件。
好的,我一会儿试试 无关风月 发表于 2023-12-15 08:37
之前遇到过类似的,原因是SD卡用了DMA, UI任务操作LTDC寄存器时 APB2总线会暂停,导致DMA出错
老哥用的是什么芯片,dma是sdio里的dma吗? DX3906 发表于 2023-12-15 09:43
老哥用的是什么芯片,dma是sdio里的dma吗?
stm32f4
Care must be taken when accessing the LTDC registers since the APB2 bus is stalling when
the following operations are ongoing:
• Register write access and update for 6 xPCKL2 period + 5x LCD_CLK period (5x
HCLK period for register on AHB clock domain)
• Register read access for 7xPCKL2 period + 5x LCD_CLK period (5x HCLK period for
register on AHB clock domain).
For registers on PCLK2 clock domain, APB2 bus is stalling during the register write access
for 6 xPCKL2 period and 7xPCKL2 period for read access. 说下这几天的测试结论,不是驱动和f_close的问题,是卡的写入速度慢了,虽然用的是class10的卡,但是用工具测出来单次小数据量的写入速度非常慢
我分别测了杂牌的c10卡、闪迪的c10卡和移速的u3高速卡,在单次写入16KB这一项的速度差距很大
杂牌卡的16KB写入速度只有4MB/S多点,而我的测试代码是1ms循环写入16KB数据,卡跟不上所以报错了,把循环里的延时调大以后就可以稳定了
大家挑sd卡最好还是挑品牌卡比较好,然后能用高速卡尽量用高速卡
杂牌c10卡
闪迪c10卡
移速u3卡
页:
[1]