文件系统比想象中的要简单,步骤也简单。想要使用主要分为以下几步
文件系统参数配置第一眼看很多,其实一点都不复杂,使能就是有些函数的开关,直接用起来就理解了。
void MX_FATFS_Init(void)
{
/*## FatFS: Link the SD driver ###########################*/
retSD = FATFS_LinkDriver(&SD_Driver, SDPath);
/* USER CODE BEGIN Init */
/* additional user code for init */
HAL_GPIO_WritePin(TF_ONOFF_GPIO_Port,TF_ONOFF_Pin,GPIO_PIN_RESET);
FATFS_INIT_LOG("MX_FATFS_Init");
// for(int8_t SD_OK = -1;SD_OK < 3;SD_OK++)
{
/*##-1- Link the micro SD disk I/O driver ##################################*/
if(retSD == 0)
{
/*##-2- Register the file system object to the FatFs module ##############*/
//在外部SD 卡挂载文件系统,文件系统挂载时会对SD 卡初始化
retSD = f_mount(&SDFatFS, (TCHAR const*)SDPath, 0);
#if 0
f_mkfs((TCHAR const*)SDPath, 0, 0);
#endif
if(retSD != FR_OK)
{
/* FatFs Initialization Error */
FATFS_INIT_LOG("Register the file system object to the FatFs module ERROR code:%d",retSD);
switch (retSD)
{
case FR_NO_FILESYSTEM:
FATFS_INIT_LOG("》SD 卡还没有文件系统,即将进行格式化...\r\n");
retSD = f_mkfs((TCHAR const*)SDPath, 0, 0);
if (retSD == FR_OK )
{
FATFS_INIT_LOG("》SD 卡已成功格式化文件系统。\r\n");
/* 格式化后,先取消挂载*/
f_mount(NULL, (TCHAR const*)SDPath, 0);
f_mount(&SDFatFS, (TCHAR const*)SDPath, 0);
}
else
{
Error_Handler();
}
break;
default:
FATFS_INIT_LOG("》SD 卡未成功加载。\r\n");
break;
}
}
else
{
//打开目录
if (1)//(f_opendir(&dir,SDPath) == FR_OK)
{
retSD = f_mkdir("图片");
retSD = f_mkdir("报文");
retSD = f_mkdir("日志");
retSD = f_mkdir("系统文件");
SD_DATA.retSD = FR_OK;
switch (retSD)
{
case FR_EXIST:
FATFS_INIT_LOG("Any object with same name is already existing");
break;
case FR_NO_FILE:
FATFS_INIT_LOG("Can create a new directory ");
break;
default:
FATFS_INIT_LOG("retSD %d",retSD);
break;
}
// f_unlink("0:19112022004455.txt");
retSD = f_open(&SDFile,"0:/系统文件/配置文件.txt",FA_OPEN_ALWAYS|FA_WRITE|FA_READ);
f_lseek (&SDFile,0);
f_printf(&SDFile,"图片数量:\t%8d\r\n报文数量:\t%8d\r\n日期:\t%8d\r\n状态:\t%8d\r\n",retSD,retSD,retSD);
f_lseek (&SDFile,0);
uint8_t buf[100];
UINT count;
f_read(&SDFile,buf,100-1,&count);
FATFS_INIT_LOG("buf:%s",buf);
f_close(&SDFile);
FATFS_INIT_LOG("retSD %d",retSD);
f_sync(&SDFile);
// FATFS_INIT_LOG("打开目录");
char buff[256];
strcpy(buff, "0:/");
retSD = scan_files(buff);
FATFS *fs;
DWORD fre_clust, fre_sect, tot_sect;
/* Get volume information and free clusters of drive 1 */
f_getfree("0:", &fre_clust, &fs);
/* Get total sectors and free sectors */
tot_sect = (fs->n_fatent - 2) * fs->csize;
fre_sect = fre_clust * fs->csize;
/* Print the free space (assuming 512 bytes/sector) */
FATFS_INIT_LOG("%10lu KiB total drive space.\n%10lu KiB available.\n", tot_sect / 2, fre_sect / 2);
}
else
{
}
}
}
}
/* USER CODE END Init */
}
函数使用流程
这里只是大概流程,主要还是直接看官网就好fatfs官网,官网例子可以直接拿来就能用。
/*
* 日志记录到文件 0:/日志/日志.txt
* 最多一次512字节 时间每5次显示一次
*/
int log_txt(const char *format,...)
{
#ifdef SD_FILE_LOG_ENABLE
if (SD_DATA.retSD != FR_OK) return -1;
uint8_t* name_buf = NULL;
va_list args;
int rc;
uint8_t log_buf[512] = {0};
va_start(args, format);
rc = vsnprintf((char*)log_buf, 512, format, args);
va_end(args);
SD_LOG("log txt lenght:%d",rc);
GET_Time_For_SD();
#ifdef SD_FILE_LOG_NO_OS
name_buf = (uint8_t*)malloc(sizeof("0:/日志/日志190102.txt"));
#endif
#ifdef SD_FILE_LOG_OS
name_buf = (uint8_t*)malloc((int)sizeof("0:/日志/日志190102.txt"));
#endif
if (name_buf == NULL)
{
SD_LOG("txt内存申请失败");
return -1;
}
else
{
sprintf((char*)name_buf,"0:/日志/日志");
if (SD_DATA.SD_Date.Year >= 10)
{
sprintf((char*)&name_buf[12],"%d",SD_DATA.SD_Date.Year);
}
else
{
sprintf((char*)&name_buf[12],"0%d",SD_DATA.SD_Date.Year);
}
if (SD_DATA.SD_Date.Month >= 10)
{
sprintf((char*)&name_buf[14],"%d",SD_DATA.SD_Date.Month);
}
else
{
sprintf((char*)&name_buf[14],"0%d",SD_DATA.SD_Date.Month);
}
if (SD_DATA.SD_Date.Date >= 10)
{
sprintf((char*)&name_buf[16],"%d",SD_DATA.SD_Date.Date);
}
else
{
sprintf((char*)&name_buf[16],"0%d",SD_DATA.SD_Date.Date);
}
sprintf((char*)&name_buf[18],".txt");
SD_LOG("name_buf:%s",name_buf);
SD_DATA.log_count++;
SD_DATA.retSD = f_open(&SDFile,(char*)name_buf,FA_OPEN_ALWAYS|FA_WRITE|FA_READ);
if (SD_DATA.retSD == FR_OK)
{
f_lseek (&SDFile,f_size(&SDFile));
f_puts((TCHAR*)log_buf,&SDFile);
SD_LOG("txt:%s",log_buf);
if (!(SD_DATA.log_count%5))
{
f_printf(&SDFile,"[%2d:%2d:%2d] ",SD_DATA.SD_Time.Hours,SD_DATA.SD_Time.Minutes,SD_DATA.SD_Time.Seconds);
SD_LOG("[%2d:%2d:%2d] ",SD_DATA.SD_Time.Hours,SD_DATA.SD_Time.Minutes,SD_DATA.SD_Time.Seconds);
f_sync(&SDFile);
}
else if (!(SD_DATA.log_count%100))
{
FATFS *fs;
DWORD fre_clust, fre_sect, tot_sect;
/* Get volume information and free clusters of drive 1 */
f_getfree("0:", &fre_clust, &fs);
/* Get total sectors and free sectors */
tot_sect = (fs->n_fatent - 2) * fs->csize;
fre_sect = fre_clust * fs->csize;
/* Print the free space (assuming 512 bytes/sector) */
SD_LOG("%10lu KiB total drive space.\n%10lu KiB available.\n", tot_sect / 2, fre_sect / 2);
f_printf(&SDFile,"%10lu KiB total drive space.\n%10lu KiB available.\n", tot_sect / 2, fre_sect / 2);
f_sync(&SDFile);
}
}
else
{
}
SD_DATA.retSD = f_close(&SDFile);
#ifdef SD_FILE_LOG_NO_OS
free(name_buf);
#endif
#ifdef SD_FILE_LOG_OS
name_buf = (uint8_t*)malloc((int)sizeof("0:/日志/日志190102.txt"));
#endif
return SD_DATA.retSD;
}
#endif
// return 0;
}
这用到的是可变参数,也是从腾讯阿里sdk中学习到的。