#include "fs.h" #include "nrf.h" #include "nrf_log.h" #include "FreeRTOS.h" #include "semphr.h" #include "task.h" #if (DEF_GD25D10C_ENABLED) #include "gd25d10c.h" static const block_dev_drv_if_t *p_inst = &gd25d110c; #endif /* ! DEF_GD25D10C_ENABLED */ #if (DEF_FS_ENABLED) static SemaphoreHandle_t m_sem = NULL; static struct lfs_config lfs_config; static lfs_t lfs; static int lfs_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size) { if (c->context == NULL) { return LFS_ERR_IO; } p_inst->read_data(buffer, block * c->block_size + off, size); return LFS_ERR_OK; } static int lfs_prog(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size) { if (c->context == NULL) { return LFS_ERR_IO; } p_inst->page_prog((void *)buffer, block * c->block_size + off, size / c->prog_size); return LFS_ERR_OK; } static int lfs_erase(const struct lfs_config *c, lfs_block_t block) { if (c->context == NULL) { return LFS_ERR_IO; } p_inst->sect_erase(block * c->block_size, 1); return LFS_ERR_OK; } static int lfs_sync(const struct lfs_config *c) { if (c->context == NULL) { return LFS_ERR_IO; } return LFS_ERR_OK; } static int lfs_lock(const struct lfs_config *c) { if (c->context == NULL) { return LFS_ERR_IO; } xSemaphoreTake(m_sem, portMAX_DELAY); return LFS_ERR_OK; } static int lfs_unlock(const struct lfs_config *c) { if (c->context == NULL) { return LFS_ERR_IO; } xSemaphoreGive(m_sem); return LFS_ERR_OK; } void fs_init(void) { m_sem = xSemaphoreCreateMutex(); if (p_inst->init() == BLOCK_DEV_SUCCESS) { lfs_config.context = (void *)p_inst; // block device operations lfs_config.read = lfs_read; lfs_config.prog = lfs_prog; lfs_config.erase = lfs_erase; lfs_config.sync = lfs_sync; lfs_config.lock = lfs_lock; lfs_config.unlock = lfs_unlock; // block device configuration lfs_config.read_size = 1; lfs_config.prog_size = p_inst->page_size; lfs_config.block_size = p_inst->sect_size; lfs_config.block_count = p_inst->sect_count; lfs_config.block_cycles = 5000; lfs_config.cache_size = p_inst->page_size; lfs_config.lookahead_size = sizeof(uint32_t); } if (lfs_mount(&lfs, &lfs_config) < 0) { if (lfs_format(&lfs, &lfs_config) < 0) { __BKPT(255); } if (lfs_mount(&lfs, &lfs_config) < 0) { return; } } } int fs_file_open(file_t *hFile, char *filename, uint32_t attr) { int ret = lfs_file_open(&lfs, hFile, filename, attr); return ret; } int fs_file_write(file_t *hFile, void *write, uint32_t size) { int ret = lfs_file_write(&lfs, hFile, write, size); return ret; } int fs_file_read(file_t *hFile, void *read, uint32_t size) { int ret = lfs_file_read(&lfs, hFile, read, size); return ret; } int fs_file_close(file_t *hFile) { int ret = lfs_file_close(&lfs, hFile); return ret; } int fs_dir(char *path) { int ret = 0; int fileCount = 0; int dirCount = 0; int totalFileSize = 0; char *str = pvPortMalloc(256); lfs_dir_t *dir = pvPortMalloc(sizeof(lfs_dir_t)); struct lfs_info *info = pvPortMalloc(sizeof(struct lfs_info)); snprintf(str, 256, "Directory of %s", path); NRF_LOG_INFO("%s", str); ret = lfs_dir_open(&lfs, dir, path); if (ret == LFS_ERR_OK) { do { ret = lfs_dir_read(&lfs, dir, info); if (ret > 0) { snprintf(str, 256, "%5s%10ld bytes %s", info->type == LFS_TYPE_REG ? " " : info->type == LFS_TYPE_DIR ? "" : "unkown", info->size, info->name); NRF_LOG_INFO("%s", str); switch (info->type) { case LFS_TYPE_REG: fileCount++; totalFileSize += info->size; break; case LFS_TYPE_DIR: dirCount++; break; default: break; } } else { snprintf(str, 256, "%15d dir(s)", dirCount); NRF_LOG_INFO("%s", str); snprintf(str, 256, "%15d file(s), total %d byets", fileCount, totalFileSize); NRF_LOG_INFO("%s", str); } } while (ret > 0); ret = lfs_dir_close(&lfs, dir); } vPortFree(info); vPortFree(dir); vPortFree(str); return ret; } #endif /* !DEF_FS_ENABLED */