| 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;}
 |