Files

206 lines
5.0 KiB
C

#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 ? "<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 */