204 lines
5.0 KiB
C
204 lines
5.0 KiB
C
#include "FreeRTOS.h"
|
|
|
|
#include "fs.h"
|
|
#include "nrf.h"
|
|
#include "nrf_log.h"
|
|
#include "semphr.h"
|
|
#include "task.h"
|
|
|
|
#if (DEF_ELITE_MODEL == DEF_ELITE_EDC_20)
|
|
#include "gd25d10c.h"
|
|
static const block_dev_drv_if_t *p_inst = &gd25d110c;
|
|
#else
|
|
static const block_drv_if_t *p_inst = NULL;
|
|
#endif
|
|
|
|
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;
|
|
}
|