123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280 |
- #include "at32f403a_407.h"
- #include "user_fatfs.h"
- #include "common_config.h"
- #include "common.h"
- #include "FreeRTOS.h"
- #include "task.h"
- #include "semphr.h"
- #include "spi_flash.h"
- #include <string.h>
- #include <stdlib.h>
- #ifdef PRINTF_STDLIB
- #include <stdio.h>
- #endif
- #ifdef PRINTF_CUSTOM
- #include "tinystdio.h"
- #endif
- #define MAX_DRV_NUM 2 // Текущее число поддерживаемых дисков
- SemaphoreHandle_t spiFlashMutex;
- FIL update_file; // Файл прошивки
- FATFS *disks[MAX_DRV_NUM];
- static unsigned long writePtr[MAX_DRV_NUM] = {0, 0}; // Указатель на позицию для записи в файл
- static uint32_t strCount = 0; // Число строк в файле
- static uint32_t pageCount = 0; // Число страниц в файле
- char file_path[32];
- static bool fSecDrvEn = false; // Флаг присутствия второстепенного диска
- static bool fPrimDrvEn = false; // Флаг присутствия основного диска
- static bool fatfs_init = false;
- //
- bool InitFS(BYTE drv)
- {
- FRESULT res;
- FATFS *disk;
- DWORD free;
- uint32_t space;
-
- spiFlashMutex = xSemaphoreCreateMutex();
- snprintf(file_path, sizeof(file_path), "%u:", drv);
- disk = pvPortMalloc(sizeof(FATFS));
- if (disk == NULL) {
- printf("DRIVE %u: malloc error\n\r", drv);
- fatfs_init = true;
- return false;
- }
-
- // Монтировать диск
- res = f_mount(disk, "", 1);
-
- // Создать файловую систему
- if (res != FR_OK) {
- res = f_mkfs(file_path,0,0);
- }
- f_getfree("/", &free, &disk);
- space = free * disk->ssize;
-
- if (space == 0) {
- f_mkfs(file_path,0,0);
- f_getfree("/", &free, &disk);
- space = free * disk->ssize;
- }
- res = f_chdir(file_path);
- if (res == FR_NO_FILESYSTEM)
- {
- printf("DRIVE %u: no filesystem found\n\r", drv);
- switch(drv)
- {
- case SPI_FLASH:
- spi_flash_erase_sector(0,0);
- spi_flash_erase_sector(1,0);
- spi_flash_erase_sector(2,0);
- spi_flash_erase_sector(3,0);
- break;
- }
- f_mkfs(file_path,0,0);
- if (f_chdir(file_path) != FR_OK) {
- printf("DRIVE %u: filesystem error\n\r", drv);
- vPortFree(disk);
- fatfs_init = true;
- return false;
- }
- else {
- printf("DRIVE %u: filesystem created successfully\n\r", drv);
- }
- }
- else if (res == FR_NOT_READY) {
- printf("DRIVE %u: not ready\n\r", drv);
- printf("DRIVE %u: File system is not initialized. Error!\n\r", drv);
- vPortFree(disk);
- fatfs_init = true;
- return false;
- }
- else if(res == FR_OK)
- {
- // Проверка файла лога
- res = f_open(&update_file, LOG_NAME, FA_READ);
- if (res != FR_OK) {
- res = f_open(&update_file, LOG_NAME, FA_WRITE | FA_CREATE_NEW);
- if (res != FR_OK) {
- f_close(&update_file);
- printf("DRIVE %u: File system is not initialized. Error!\n\r", drv);
- fatfs_init = true;
- return false;
- }
- }
- f_close(&update_file);
- }
- printf("DRIVE %u: filesystem initialized successfully\n\r", drv);
- fatfs_init = true;
- return true;
- }
- /**
- * @brief Возвращает число файлов в папке
- * @param *path имя папки в виде "/LOG"
- * @retval
- */
- uint32_t GetFilesCount(char *path)
- {
- FRESULT res;
- FILINFO fno;
- DIR dir;
- char *fn;
- uint32_t fileCount;
-
- res = f_opendir(&dir, path);
-
- if (res != FR_OK)
- return 0; // Не удалось открыть директорию
-
- for (;;)
- {
- res = f_readdir(&dir, &fno); // Чтение объекта директории
-
- // Останов цикла при ошибке или при достижении конца списка директории
- if (res != FR_OK || fno.fname[0] == 0)
- return fileCount;
-
- if (fno.fname[0] == '.')
- continue; // Игнорирование элемента 'точка'
-
- fn = fno.fname;
- if (!(fno.fattrib & AM_DIR))
- { // Это директория
- fileCount++;
- DBG printf("%s\r\n",fn);
- }
- else
- {
- DBG printf("%s/%s\r\n", path, fn);
- }
- }
- }
- /* Get fs file raw data */
- uint32_t GetFileData(BYTE drv, char *file_name, unsigned long ptr, char *str, uint32_t size)
- {
- unsigned long readPtr;
- FRESULT res;
- uint32_t count = 0;
- res = f_open(&update_file, file_name, FA_WRITE);
- if (res != FR_OK) {
- f_close(&update_file);
- return 0;
- }
- readPtr = ptr;
- res = f_lseek(&update_file, readPtr);
- if (res != FR_OK) {
- f_close(&update_file);
- return 0;
- }
- res = f_read(&update_file, str, size, (UINT *)&count);
- if (res != FR_OK) {
- f_close(&update_file);
- return 0;
- }
- f_close(&update_file);
- return count;
- }
- /* Put fs file raw data */
- uint32_t PutFileData(BYTE drv, char *file_name, unsigned long ptr, char *str, uint32_t size, bool truncate)
- {
- FRESULT res;
- uint32_t count = 0;
-
- if (xSemaphoreTake(spiFlashMutex, 2000) != pdTRUE)
- return 0;
- res = f_open(&update_file, file_name, FA_WRITE);
- if (res != FR_OK) {
- f_close(&update_file);
- xSemaphoreGive(spiFlashMutex);
- return 0;
- }
- if( ptr == 1 ){
- res = f_lseek(&update_file, 0);
- }
- else{
- res = f_lseek(&update_file, update_file.fsize);
- }
- if (res != FR_OK) {
- f_close(&update_file);
- xSemaphoreGive(spiFlashMutex);
- return 0;
- }
- res = f_write(&update_file, str, size, (UINT *)&count);
- if (res != FR_OK) {
- f_close(&update_file);
- xSemaphoreGive(spiFlashMutex);
- return 0;
- }
- if (truncate) {
- res = f_truncate(&update_file);
- if (res != FR_OK) {
- xSemaphoreGive(spiFlashMutex);
- }
- }
-
- f_close(&update_file);
- xSemaphoreGive(spiFlashMutex);
-
- return count;
- }
- //
- void EraseFlash()
- {
- if (xSemaphoreTake(spiFlashMutex, 10000) != pdTRUE)
- return;
- spi_flash_erase_sector(0,0);
- spi_flash_erase_sector(1,0);
- spi_flash_erase_sector(2,0);
- spi_flash_erase_sector(3,0);
- xSemaphoreGive(spiFlashMutex);
- }
- //
- void flash_check_space(FATFS *fs)
- {
- DWORD fre_clust, fre_sect;
-
- // Получение информации о томе и количество свободных кластеров
- f_getfree(0, &fre_clust, &fs);
- fre_sect = fre_clust * fs->csize;
- //availableSpace = fre_sect/2;
- }
- //
- bool fatfs_isinit(void)
- {
- return fatfs_init;
- }
|