123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690 |
- /* USER CODE BEGIN Header */
- /**
- ******************************************************************************
- * @file : main.c
- * @brief : Main program body
- ******************************************************************************
- * @attention
- *
- * <h2><center>© Copyright (c) 2019 STMicroelectronics.
- * All rights reserved.</center></h2>
- *
- * This software component is licensed by ST under BSD 3-Clause license,
- * the "License"; You may not use this file except in compliance with the
- * License. You may obtain a copy of the License at:
- * opensource.org/licenses/BSD-3-Clause
- *
- ******************************************************************************
- */
- /* USER CODE END Header */
- #include "main.h"
- #if USE_FATFS_RECORD==1
- /* Includes ------------------------------------------------------------------*/
- #include <stdint.h>
- #include <string.h>
- #include <stdlib.h>
- #include <stdbool.h>
- #include "func_fatfs.h"
- #include "dev_spi_sdcard.h"
- #include "func_spi_w25qxx.h"
- #include "func_fatfs_record.h"
- #include "func_queue_record.h"
- #include "Data_deal.h"
- /* Private includes ----------------------------------------------------------*/
- /* USER CODE BEGIN Includes */
- /* USER CODE END Includes */
- /* Private typedef -----------------------------------------------------------*/
- #define MAX_FILE_COUNT 20
- #define NUM_FILE_SET 10
- /* Private define ------------------------------------------------------------*/
- /* USER CODE BEGIN PD */
- /* USER CODE END PD */
- /* Private macro -------------------------------------------------------------*/
- /* USER CODE BEGIN PM */
- /* USER CODE END PM */
- /* Private variables ---------------------------------------------------------*/
- /* USER CODE BEGIN PV */
- /* USER CODE END PV */
- const char FILE_START[] = "20";
- const char FILE_END[] = ".TXT";
- const char FILE_FOLD[] = "JLRECORD";
- /* Private function prototypes -----------------------------------------------*/
- typedef struct fs_record_struct
- {
- int8_t fs_stat;
- const char *fold; //操作路径
- int8_t * path[32]; //操作路径
- int8_t name_new[32]; //最新的文件名
- int8_t name_send[32]; //最老的文件名
-
- FIL opt_file; //当前操作的文件
- FATFS fs;
- DIR dir; //操作的文件名
- uint32_t opt_len;
- uint32_t items_num;
-
- int8_t read_buf[512];
- uint32_t read_len;
-
- int8_t write_buf[512];
- uint32_t write_len;
-
- uint32_t file_num;
- int8_t file_list[MAX_FILE_COUNT][32];//保存文件名
-
- int8_t link_ok;
- uint32_t free_size;
- }fs_record_OBJ;
- fs_record_OBJ fs_record_obj = {
- .fs_stat = true,
- .fold = FILE_FOLD,
- .items_num= 0,
- .file_num = 0,
- .link_ok = false,
- };
- //add boly 20221020
- //uint8_t data_buf[16*1024] = {0};
- //end boly
- void func_record_Get_Capacity(void);
- void func_record_files_update(char * path);
- void func_record_dir_qsort(size_t fcount);
- extern SDateTime m_datetime;
- /* Private user code ---------------------------------------------------------*/
- uint8_t func_record_fatfs_isOK(void)
- {
-
- return fs_record_obj.fs_stat;
- }
- uint8_t func_record_fatfs_set_OK(uint8_t stat)
- {
- fs_record_obj.fs_stat = stat;
- return fs_record_obj.fs_stat;
- }
- void func_record_mk_fileName(char *buf)
- {
- //fs_record_obj.path[12] = 0;
- #if 0
- sprintf(buf,"%s/%04d%02d%02d.TXT",fs_record_obj.fold,
- m_datetime.year%100 + 2000,
- m_datetime.month%100,
- m_datetime.day%100
- );
- #elif 0
- sprintf(buf,"%s/%04d%02d%02d.TXT",fs_record_obj.fold,
- m_datetime.day%100 + 2000,
- m_datetime.hour%100,
- m_datetime.min%100
- );
- #else
- sprintf(buf,"%s/%04d%02d%02d.TXT",fs_record_obj.fold,
- m_datetime.hour%100 + 2000,
- m_datetime.min%100,
- m_datetime.sec%100
- );
-
- #endif
- return;
- }
- /**
- * @brief 指定长度len,buf内容写入文件
- * @retval int
- */
- uint32_t func_record_write(uint8_t *buf ,uint32_t len)
- {
-
- FRESULT res;
- UINT write_len = 0;
- //根据日期生成文件名,用于文件写入
- func_record_mk_fileName((char *)fs_record_obj.name_new);
-
- //打开当前存在的文件;
- res = f_open(&fs_record_obj.opt_file,(char *)fs_record_obj.name_new , FA_WRITE| FA_OPEN_EXISTING);
- if(FR_OK != res)
- {
- //检查文件个数是否超限
- func_record_files_update((char *)fs_record_obj.fold);
-
- if(FR_NO_FILE == res)
- {
- //创建文件并写入
- res = f_open(&fs_record_obj.opt_file, (char*)fs_record_obj.name_new, FA_WRITE| FA_CREATE_NEW);
- if(FR_OK != res)
- {
- fs_record_obj.fs_stat = false;
- return 0;
- }
- }
- else
- {
- return 0;
- }
- }
- //将当前发送文件更新为当前写入文件
- strcpy((char *)fs_record_obj.name_send,(char *)fs_record_obj.name_new);
-
- fs_record_obj.opt_len = f_size(&fs_record_obj.opt_file);
-
- //操作指针移动到文件末尾
- res = f_lseek(&fs_record_obj.opt_file, fs_record_obj.opt_len);
-
- taskENTER_CRITICAL(); /* 临界保护开启 */
- res = f_write(&fs_record_obj.opt_file, buf, len, &write_len);
- res = f_close(&fs_record_obj.opt_file); //关闭文件
- taskEXIT_CRITICAL(); /* 临界保护关闭 */
-
- return write_len;
- }
- void func_record_get_NameSend(void)
- {
- //发送文件是否存在
- if(strlen((char*)fs_record_obj.name_send) > 0)
- {
- return;
- }
-
- //检查文件个数是否超限
- func_record_files_update((char *)fs_record_obj.fold);
- }
- /**
- * @brief The application entry point.
- * @retval int
- */
- uint32_t func_record_read(uint8_t *buf, uint32_t len)
- {
- FRESULT res;
-
- //uint32_t file_len = 0;
- uint32_t read_len = 0;
-
- func_record_get_NameSend();
-
- if(strlen((char *)fs_record_obj.name_send) <= 0)
- {
- return 0;
- }
-
- res = f_open(&fs_record_obj.opt_file, (char*)fs_record_obj.name_send, FA_READ | FA_OPEN_EXISTING);
- if(FR_OK != res)
- {
- return 0;
- }
-
- fs_record_obj.opt_len = f_size(&fs_record_obj.opt_file);
-
- //如果文件小于数据长度,则删除文件
- if(fs_record_obj.opt_len < len)
- {
- res = f_close(&fs_record_obj.opt_file);
-
- taskENTER_CRITICAL(); /* 临界保护开启 */
- res = f_unlink((char*)fs_record_obj.name_send);
- taskEXIT_CRITICAL(); /* 临界保护关闭 */
-
- if(res == FR_OK)
- {
- memset((char*)fs_record_obj.name_send, 0x00,sizeof(fs_record_obj.name_send));
- }
- return 0;
- };
- res = f_lseek(&fs_record_obj.opt_file, fs_record_obj.opt_len - len);
-
- res = f_read(&fs_record_obj.opt_file, buf, len, &read_len);
-
- res = f_close(&fs_record_obj.opt_file);
-
-
- return read_len;
- }
- uint32_t func_record_remove(uint8_t *buf, uint32_t len)
- {
- FRESULT res;
- uint32_t read_len = 0;
-
- func_record_get_NameSend();
-
- if(strlen((char *)fs_record_obj.name_send) <= 0)
- {
- return 0;
- }
-
- res = f_open(&fs_record_obj.opt_file, (char*)fs_record_obj.name_send, FA_WRITE| FA_READ| FA_OPEN_EXISTING);
- if(FR_OK != res)
- {
- memset((char*)fs_record_obj.name_send, 0x00,sizeof(fs_record_obj.name_send));
- return 0;
- }
-
- fs_record_obj.opt_len = f_size(&fs_record_obj.opt_file);
-
- //如果文件小于数据长度,则删除文件
- if(fs_record_obj.opt_len < len)
- {
- res = f_close(&fs_record_obj.opt_file);
- taskENTER_CRITICAL(); /* 临界保护开启 */
- res = f_unlink((char*)fs_record_obj.name_send);
- taskEXIT_CRITICAL(); /* 临界保护关闭 */
- if(res == FR_OK)
- {
- memset((char*)fs_record_obj.name_send, 0x00,sizeof(fs_record_obj.name_send));
- }
- return 0;
- };
- res = f_lseek(&fs_record_obj.opt_file, fs_record_obj.opt_len - len);
- res = f_read(&fs_record_obj.opt_file, buf, len, &read_len);
-
- res = f_lseek(&fs_record_obj.opt_file, fs_record_obj.opt_len - len);
-
- taskENTER_CRITICAL(); /* 临界保护开启 */
- res = f_truncate(&fs_record_obj.opt_file ); //截断后面的文件
- res = f_close(&fs_record_obj.opt_file);
- taskEXIT_CRITICAL(); /* 临界保护关闭 */
-
- return read_len;
- }
- uint32_t func_record_delete(uint8_t *buf,uint32_t len)
- {
- FRESULT res;
- //uint32_t file_len = 0;
-
- if(strlen((char *)fs_record_obj.name_send) <= 0)
- {
- return 0;
- }
- //打开文件
- res = f_open(&fs_record_obj.opt_file, (char*)fs_record_obj.name_send, FA_WRITE | FA_OPEN_EXISTING );
-
- if ( res != FR_OK )
- {
- if(res == FR_NO_FILE )
- {
- memset((char*)fs_record_obj.name_send, 0x00,sizeof(fs_record_obj.name_send));
- memset((char*)fs_record_obj.name_new, 0x00,sizeof(fs_record_obj.name_new));
- }
- return res;
- }
-
- fs_record_obj.opt_len = f_size(&fs_record_obj.opt_file);
- //如果文件小于数据长度,则删除文件
- if(fs_record_obj.opt_len <= len)
- {
- res = f_close(&fs_record_obj.opt_file);
- taskENTER_CRITICAL(); /* 临界保护开启 */
- res = f_unlink((char*)fs_record_obj.name_send);
- taskEXIT_CRITICAL(); /* 临界保护关闭 */
- if(res == FR_OK)
- {
- memset((char*)fs_record_obj.name_send, 0x00,sizeof(fs_record_obj.name_send));
- }
- return 0;
- };
-
- res = f_lseek(&fs_record_obj.opt_file, fs_record_obj.opt_len - len);
- taskENTER_CRITICAL(); /* 临界保护开启 */
- res = f_truncate(&fs_record_obj.opt_file ); //截断后面的文件
- taskEXIT_CRITICAL(); /* 临界保护关闭 */
- res = f_close(&fs_record_obj.opt_file);
-
- return res;
- }
- /**
- * 文件信息获取
- */
- FRESULT func_record_file_check(void)
- {
- FRESULT f_res; /* 文件操作结果 */
- static FILINFO finfo;
- /* 获取文件信息 */
- f_res=f_stat("TestDir/testdir.txt",&finfo);
- if(f_res==FR_OK)
- {
- printf("“testdir.txt”文件信息:\n");
- printf("》文件大小: %ld(字节)\n", finfo.fsize);
- printf("》时间戳: %u/%02u/%02u, %02u:%02u\n",
- (finfo.fdate >> 9) + 1980, finfo.fdate >> 5 & 15, finfo.fdate & 31,finfo.ftime >> 11, finfo.ftime >> 5 & 63);
- printf("》属性: %c%c%c%c%c\n\n",
- (finfo.fattrib & AM_DIR) ? 'D' : '-', // 是一个目录
- (finfo.fattrib & AM_RDO) ? 'R' : '-', // 只读文件
- (finfo.fattrib & AM_HID) ? 'H' : '-', // 隐藏文件
- (finfo.fattrib & AM_SYS) ? 'S' : '-', // 系统文件
- (finfo.fattrib & AM_ARC) ? 'A' : '-'); // 档案文件
- }
- return f_res;
- }
- /**
- * @brief scan_files 递归扫描FatFs内的文件
- * @param path:初始扫描路径
- * @retval result:文件系统的返回值
- */
- FRESULT func_record_scan_files (char* path)
- {
- FRESULT res; //部分在递归过程被修改的变量,不用全局变量
- FILINFO fno;
- DIR dir;
- int i;
- char *fn; // 文件名
-
- #if _USE_LFN
- /* 长文件名支持 */
- /* 简体中文需要2个字节保存一个“字”*/
- static char lfn[_MAX_LFN*2 + 1];
- fno.fname = lfn;
- fno.fsize = sizeof(lfn);
- #endif
- //打开目录
- res = f_opendir(&dir, path);
- if (res == FR_OK)
- {
- i = strlen(path);
- for (;;)
- {
- //读取目录下的内容,再读会自动读下一个文件
- res = f_readdir(&dir, &fno);
- //为空时表示所有项目读取完毕,跳出
- if (res != FR_OK || fno.fname[0] == 0) break;
- #if _USE_LFN
- fn = *fno.lfname ? fno.lfname : fno.fname;
- #else
- fn = fno.fname;
- #endif
- //点表示当前目录,跳过
- if (*fn == '.') continue;
- //目录,递归读取
- if (fno.fattrib & AM_DIR)
- {
- //合成完整目录名
- sprintf(&path[i], "/%s", fn);
- //递归遍历
- res = func_record_scan_files(path);
- path[i] = 0;
- //打开失败,跳出循环
- if (res != FR_OK)
- break;
- }
- else
- {
- printf("%s/%s\n", path, fn); //输出文件名
- /* 可以在这里提取特定格式的文件路径 */
- }//else
- } //for
- }
-
-
- return res;
- }
- /*------------------------------------------------------
- 读取指定目录下所有的文件
- 说明:
- f_readdir 按顺序读取目录内文件,
- 重复调用此函数可读取目录内所有文件;
- ---------------------------------------------------------*/
- void func_record_files_update(char * path)
- {
- char file_name[32] = {0};
- FRESULT res; //部分在递归过程被修改的变量,不用全局变量
- FILINFO fno = {0};
- fs_record_obj.items_num = 0;
- fs_record_obj.file_num = 0;
- memset((void *)fs_record_obj.file_list, 0x00,sizeof(fs_record_obj.file_list));
- memset((void *)fs_record_obj.name_send, 0x00,sizeof(fs_record_obj.name_send));
-
- //获取fatfs文件系统
- fs_record_obj.free_size = func_fatfs_get_free();
-
- #if _USE_LFN//如果使能支持长文件名 先对下面两项初始化
- fileinfo.lfsize=_MAX_LFN * 2 + 1;//
- fileinfo.lfname=(TCHAR*)FileName;//
- #endif
- if(f_opendir(&fs_record_obj.dir,(const char*)path) != FR_OK)/* 打开文件夹目录成功,目录信息已经在dir结构体中保存 */
- {
- res = f_mkdir((const char*)path);
- if(res == FR_OK)
- {
- fs_record_obj.fs_stat = true;
- return;
- }
- else
- {
- return;
- }
- }
-
- fs_record_obj.fs_stat = true;
-
- //打开日志路径正常,获取路文件夹内的文件列表
- while(f_readdir(&fs_record_obj.dir, &fno) == FR_OK) //读文件信息到文件状态结构体中
- {
- fs_record_obj.items_num++;
- //判定的顺序不能变
- if(!fno.fname[0]) break; //如果文件名为‘\0',说明读取完成结束
- if (fno.fattrib & AM_DIR) continue; //表示目录,跳过
-
- if (fno.fname[0] == '.') continue; //点表示当前目录,跳过
-
- if( (fs_record_obj.file_num < MAX_FILE_COUNT)
- &&(strstr(fno.fname,FILE_START) == fno.fname)
- &&((strstr(fno.fname,FILE_END) != 0))
- )
- {
- sprintf((char *)fs_record_obj.file_list[fs_record_obj.file_num], "%s/%s", fs_record_obj.fold,fno.fname);//将文件名存入列表中
- fs_record_obj.file_num ++;
- }
- else
- {
- /* 如果目录已经存在,关闭它 */
- res = f_closedir(&fs_record_obj.dir);
-
- sprintf((char *)file_name,"%s/%s",fs_record_obj.fold, fno.fname); //输出文件名
- taskENTER_CRITICAL(); /* 临界保护开启 */
- res = f_unlink(file_name);
- taskEXIT_CRITICAL(); /* 临界保护关闭 */
- if(FR_OK != res)
- {
-
- fs_record_obj.fs_stat = false;
- return;
- }
- }
- }
-
- /* 如果目录已经存在,关闭它 */
- res = f_closedir(&fs_record_obj.dir);
-
- if(fs_record_obj.file_num > 0)
- {
- }
- else
- {
- memset((void *)fs_record_obj.name_send, 0x00,sizeof(fs_record_obj.name_send));
- return;
- }
-
- //按文件名最小到大排序;
- if(fs_record_obj.file_num > 1)
- {
- func_record_dir_qsort(fs_record_obj.file_num);
- }
-
- //获取最新的文件;
- uint8_t max_idx = fs_record_obj.file_num - 1;
- sprintf((char *)fs_record_obj.name_send,"%s", fs_record_obj.file_list[max_idx]);
-
- //如果文件个数超限,
- if((fs_record_obj.file_num > NUM_FILE_SET)
- ||(fs_record_obj.free_size < 500))
- {
- //删除日期最早的文件
- sprintf((char *)file_name,"%s", fs_record_obj.file_list[0]);
-
- taskENTER_CRITICAL(); /* 临界保护开启 */
- res = f_unlink(file_name);
- taskEXIT_CRITICAL(); /* 临界保护关闭 */
-
- if(FR_OK != res)
- {
- fs_record_obj.fs_stat = false;
- return;
- }
- }
-
- UNUSED(res);
- return;
- }
- int qsort_cmp(const void *a,const void *b)
- {
- return strcmp(( char * ) a, (const char* )b);
- }
- //(void * /*base*/, size_t /*nmemb*/, size_t /*size*/, int (* /*compar*/)(const void *, const void *)) __attribute__((__nonnull__(1,4)));
- void func_record_dir_qsort(size_t fcount)
- {
- qsort((void *)fs_record_obj.file_list, fcount, sizeof(fs_record_obj.file_list[0]), qsort_cmp);
- }
- void func_record_init(void)
- {
-
- memset(fs_record_obj.file_list, 0x00,sizeof(fs_record_obj.file_list)); //清空文件列表
- fs_record_obj.file_num = 0;
- fs_record_obj.fs_stat = true;
- func_record_files_update((char *)fs_record_obj.fold);
- }
- void func_record_fs_test(void)
- {
-
- record_test_obj.cnts++;
- sprintf(record_test_obj.buf,"XX%08xXX",record_test_obj.cnts);
- switch(record_test_obj.test_flag)
- {
- case 0:
- {
- func_record_write((uint8_t *)record_test_obj.buf ,strlen(record_test_obj.buf));
- }break;
- case 1:
- {
- func_record_read((uint8_t *)record_test_obj.buf ,sizeof(record_test_obj.buf));
- func_record_delete((uint8_t *)record_test_obj.buf ,sizeof(record_test_obj.buf));
- func_record_read((uint8_t *)record_test_obj.buf ,sizeof(record_test_obj.buf));
- }break;
- default:
- {
- func_record_read((uint8_t *)record_test_obj.buf ,sizeof(record_test_obj.buf));
- }break;
-
- }
-
- }
- char* pstr = 0;
- char* pidx = 0;
- void func_record_str(void)
- {
- char str_name[] ="20221112.TXT" ;
- while(1)
- {
- pstr = strstr(str_name,FILE_START);
-
- pidx = strstr(str_name,FILE_END);
- UNUSED(pstr);
- UNUSED(pidx);
- }
- }
- char path_buf[512] = {0};
- void func_record_fatfs_main(void const *argument)
- {
- //func_record_str();
-
- //add boly 20221014 SD卡 FATFS组件初始化
- #if USE_SPI_SD
- SDCARD_GPIO_Init();
- SDCARD_SPI_Init();
- #endif
-
- #if USE_SPI_FLASH
- func_w25q_init();
- func_w25q_test();
- #endif
-
-
-
- #if USE_FATFS_RECORD
- taskENTER_CRITICAL();
- func_fatfs_init();
- func_fatfs_main();
- taskEXIT_CRITICAL();
-
- func_record_queue_init();
- func_record_queue_update();
-
- //while(1)
- {
- osDelay(1000);
- };
- //end boly
- #endif
- osDelay(1000);//
- func_record_init();
- while(1)
- {
- strcpy(path_buf,fs_record_obj.fold);
- //func_fatfs_scan_files(path_buf);
- //func_record_fs_test();
- func_record_queue_test();
- func_record_work();
- osDelay(1000);
- }
- }
- #endif //---------------------------USE_FATFS_RECORD----------------------------
- /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|