[refactor] giveup easyflash, use littlefs instead

This commit is contained in:
jzlv 2023-12-08 11:01:06 +08:00
parent 97845af17b
commit 81b4d941c9
9 changed files with 299 additions and 120 deletions

View File

@ -11,6 +11,14 @@ sdk_library_add_sources(port/lfs_xip_flash.c)
sdk_add_include_directories(port)
sdk_add_compile_definitions(-DCONFIG_LITTLEFS)
if(CONFIG_FREERTOS)
sdk_add_compile_definitions(-DLFS_THREADSAFE)
endif()
if(CONFIG_LITTLEFS_KV_EASYFLASH)
sdk_library_add_sources(easyflash_port/lfs_easyflash.c)
sdk_add_include_directories(easyflash_port)
endif()
if(CONFIG_LITTLEFS_FLASH_ADDRESS)
sdk_add_compile_definitions(-DCONFIG_LITTLEFS_FLASH_ADDRESS=${CONFIG_LITTLEFS_FLASH_ADDRESS})

View File

@ -3,11 +3,13 @@
#include "lfs.h"
extern int lfs_xip_flash_read(const struct lfs_config *c, lfs_block_t block,
lfs_off_t off, void *buffer, lfs_size_t size);
extern int lfs_xip_flash_prog(const struct lfs_config *c, lfs_block_t block,
lfs_off_t off, const void *buffer, lfs_size_t size);
extern int lfs_xip_flash_erase(const struct lfs_config *c, lfs_block_t block);
extern int lfs_xip_flash_sync(const struct lfs_config *c);
lfs_t *lfs_xip_init(void);
#endif
int lfs_xip_flash_read(const struct lfs_config *c, lfs_block_t block,
lfs_off_t off, void *buffer, lfs_size_t size);
int lfs_xip_flash_prog(const struct lfs_config *c, lfs_block_t block,
lfs_off_t off, const void *buffer, lfs_size_t size);
int lfs_xip_flash_erase(const struct lfs_config *c, lfs_block_t block);
int lfs_xip_flash_sync(const struct lfs_config *c);
#endif

View File

@ -1,26 +1,179 @@
#include <assert.h>
#include <errno.h>
#include "lfs.h"
#include "bflb_flash.h"
#include "bflb_l1c.h"
#include "bflb_mtd.h"
#ifdef CONFIG_FREERTOS
#include "FreeRTOS.h"
#include "semphr.h"
#endif
#include "lfs_port.h"
#define DBG_TAG "LFS"
#include "log.h"
/*!< use memory area after 512k */
#ifdef CONFIG_LITTLEFS_FLASH_ADDRESS
#define LITTLEFS_FLASH_SIZE (0x71000)
#endif
#define LITTLEFS_FLASH_BLOCK_SIZE 4096
#define LITTLEFS_FLASH_BLOCK_CYCLE 500
static lfs_t lfs;
static char lfs_inited = 0;
#if defined(LFS_THREADSAFE) && defined(CONFIG_FREERTOS)
static int lfs_xip_giant_lock(const struct lfs_config *c);
static int lfs_xip_giant_unlock(const struct lfs_config *c);
#endif
static struct lfs_context {
uint32_t flash_addr;
#ifdef CONFIG_FREERTOS
SemaphoreHandle_t fs_giant_lock;
#endif
} lfs_xip_ctx;
/*!< configuration of the filesystem is provided by this struct */
static struct lfs_config cfg = {
.context = &lfs_xip_ctx,
// block device operations
.read = lfs_xip_flash_read,
.prog = lfs_xip_flash_prog,
.erase = lfs_xip_flash_erase,
.sync = lfs_xip_flash_sync,
#if defined(LFS_THREADSAFE) && defined(CONFIG_FREERTOS)
.lock = lfs_xip_giant_lock,
.unlock = lfs_xip_giant_unlock,
#endif
// block device configuration
.read_size = 256,
.prog_size = 256,
.lookahead_size = 256,
.cache_size = 512,
.block_size = LITTLEFS_FLASH_BLOCK_SIZE,
.block_cycles = LITTLEFS_FLASH_BLOCK_CYCLE,
};
lfs_t *lfs_xip_init(void)
{
int ret;
if (lfs_inited) {
return &lfs;
}
#ifndef CONFIG_LITTLEFS_FLASH_ADDRESS
#error "must define CONFIG_LITTLEFS_FLASH_ADDRESS"
bflb_mtd_info_t info;
bflb_mtd_handle_t handle;
ret = bflb_mtd_open(BFLB_MTD_PARTITION_NAME_PSM, &handle, BFLB_MTD_OPEN_FLAG_BUSADDR);
if (ret < 0) {
LOG_E("no valid PSM partition found\r\n");
errno = LFS_ERR_IO;
return NULL;
}
memset(&info, 0, sizeof(info));
bflb_mtd_info(handle, &info);
LOG_I("Found valid PSM partition, XIP addr %08x, flash addr %08x, size %d\r\n",
info.xip_addr,
info.offset,
info.size);
lfs_xip_ctx.flash_addr = info.offset;
cfg.block_count = info.size / LITTLEFS_FLASH_BLOCK_SIZE;
bflb_mtd_close(handle);
#else
lfs_xip_ctx.flash_addr = CONFIG_LITTLEFS_FLASH_ADDRESS;
cfg.block_count = LITTLEFS_FLASH_SIZE / LITTLEFS_FLASH_BLOCK_SIZE;
#endif
#ifdef CONFIG_FREERTOS
#if configUSE_RECURSIVE_MUTEXES
lfs_xip_ctx.fs_giant_lock = xSemaphoreCreateRecursiveMutex();
#else
lfs_xip_ctx.fs_giant_lock = xSemaphoreCreateMutex();
#endif
#endif
// mount the filesystem
ret = lfs_mount(&lfs, &cfg);
// reformat if we can't mount the filesystem
// this should only happen on the first boot
if (ret == LFS_ERR_CORRUPT) {
LOG_W("try to reformat \r\n");
ret = lfs_format(&lfs, &cfg);
if (ret) {
LOG_F("reformat fail\r\n");
errno = LFS_ERR_CORRUPT;
return NULL;
}
LOG_I("reformat success\r\n");
ret = lfs_mount(&lfs, &cfg);
if (ret) {
errno = ret;
return NULL;
}
} else if (ret != LFS_ERR_OK) {
errno = ret;
return NULL;
}
LOG_I("mount success\r\n");
lfs_inited = 1;
return &lfs;
}
#if defined(LFS_THREADSAFE) && defined(CONFIG_FREERTOS)
static int lfs_xip_giant_lock(const struct lfs_config *c)
{
struct lfs_context *ctx = c->context;
#if configUSE_RECURSIVE_MUTEXES
xSemaphoreTakeRecursive(ctx->fs_giant_lock, portMAX_DELAY);
#else
xSemaphoreTake(ctx->fs_giant_lock, portMAX_DELAY);
#endif
return 0;
}
static int lfs_xip_giant_unlock(const struct lfs_config *c)
{
struct lfs_context *ctx = c->context;
#if configUSE_RECURSIVE_MUTEXES
xSemaphoreGiveRecursive(ctx->fs_giant_lock);
#else
xSemaphoreGive(ctx->fs_giant_lock);
#endif
return 0;
}
#endif
/*****************************************************************************
* @brief Read a region in a block. Negative error codes are propagated
* to the user.
* @param[in] c
* @param[in] block
* @param[in] off
* @param[out] buffer
* @param[in] size
*
* @retval int
* @param[in] c
* @param[in] block
* @param[in] off
* @param[out] buffer
* @param[in] size
*
* @retval int
*****************************************************************************/
int lfs_xip_flash_read(const struct lfs_config *c, lfs_block_t block,
lfs_off_t off, void *buffer, lfs_size_t size)
{
return bflb_flash_read(CONFIG_LITTLEFS_FLASH_ADDRESS + block * c->block_size + off,
struct lfs_context *ctx = c->context;
return bflb_flash_read(ctx->flash_addr + block * c->block_size + off,
(uint8_t *)buffer, size);
}
@ -28,18 +181,19 @@ int lfs_xip_flash_read(const struct lfs_config *c, lfs_block_t block,
* @brief Program a region in a block. The block must have previously
* been erased. Negative error codes are propagated to the user.
* May return LFS_ERR_CORRUPT if the block should be considered bad.
* @param[in] c
* @param[in] block
* @param[in] off
* @param[in] buffer
* @param[in] size
*
* @retval int
* @param[in] c
* @param[in] block
* @param[in] off
* @param[in] buffer
* @param[in] size
*
* @retval int
*****************************************************************************/
int lfs_xip_flash_prog(const struct lfs_config *c, lfs_block_t block,
lfs_off_t off, const void *buffer, lfs_size_t size)
{
return bflb_flash_write(CONFIG_LITTLEFS_FLASH_ADDRESS + block * c->block_size + off,
struct lfs_context *ctx = c->context;
return bflb_flash_write(ctx->flash_addr + block * c->block_size + off,
(uint8_t *)buffer, size);
}
@ -48,25 +202,26 @@ int lfs_xip_flash_prog(const struct lfs_config *c, lfs_block_t block,
* The state of an erased block is undefined. Negative error codes
* are propagated to the user.
* May return LFS_ERR_CORRUPT if the block should be considered bad.
* @param[in] c
* @param[in] block
*
* @retval int
* @param[in] c
* @param[in] block
*
* @retval int
*****************************************************************************/
int lfs_xip_flash_erase(const struct lfs_config *c, lfs_block_t block)
{
return bflb_flash_erase(CONFIG_LITTLEFS_FLASH_ADDRESS + block * c->block_size, c->block_size);
struct lfs_context *ctx = c->context;
return bflb_flash_erase(ctx->flash_addr + block * c->block_size, c->block_size);
}
/*****************************************************************************
* @brief Sync the state of the underlying block device. Negative error
* @brief Sync the state of the underlying block device. Negative error
* codes are propagated to the user.
* @param[in] c
*
* @retval int
* @param[in] c
*
* @retval int
*****************************************************************************/
int lfs_xip_flash_sync(const struct lfs_config *c)
{
/*!< if use xip, may need to clean cache */
return 0;
}
}

View File

@ -8,15 +8,16 @@ uint8_t read_buffer[100];
#define WIFI_SSID_KEY "wifi.ssid"
#define WIFI_PASSWD_KEY "wifi.passwd"
#define TEST_KEY1 "g/hwaddr"
int main(void)
{
board_init();
/* Partition and boot2 must be use, and we can only operate partition **psm** with easyflash
*
/* Partition and boot2 must be use, and we can only operate partition **psm** with easyflash
*
* partition_cfg with psm:
*
*
[[pt_entry]]
type = 3
name = "PSM"
@ -35,41 +36,82 @@ int main(void)
*/
bflb_mtd_init();
easyflash_init();
printf("errno: %d\r\n", errno);
memset(read_buffer, 0, sizeof(read_buffer));
ef_port_erase(0x0, 4096);
ef_port_write(0x0, test_data, sizeof(test_data));
ef_port_read(0x0, read_buffer, sizeof(test_data));
if (memcmp(read_buffer, test_data, sizeof(test_data))) {
printf("easyflash fail\r\n");
while (1) {
}
}
printf("write data: %s\r\n", read_buffer);
printf("ef set env\r\n");
ef_set_and_save_env(WIFI_SSID_KEY, (const char *)"helloworld");
ef_set_and_save_env(WIFI_PASSWD_KEY, (const char *)"helloworld2023");
ef_set_and_save_env(TEST_KEY1, (const char *)"11223344");
ef_save_env();
char ssid[33];
char passwd[65];
char hwaddr[33];
int ret;
printf("ef get env\r\n");
if (ef_get_env(WIFI_SSID_KEY) != NULL) {
ret = ef_get_env_blob(WIFI_SSID_KEY, ssid, sizeof(ssid), NULL);
ssid[ret] = 0;
printf("ssid:%s\r\n",ssid);
printf("ssid:%s\r\n", ssid);
}
if (ef_get_env(WIFI_PASSWD_KEY) != NULL) {
ret = ef_get_env_blob(WIFI_PASSWD_KEY, passwd, sizeof(passwd), NULL);
passwd[ret] = 0;
printf("passwd:%s\r\n",passwd);
printf("passwd:%s\r\n", passwd);
}
ret = ef_get_env_blob(TEST_KEY1, hwaddr, sizeof(hwaddr), NULL);
hwaddr[ret] = 0;
if (ret == 0) {
printf("read key1 failed\r\n");
} else {
printf("hwaddr:%s\r\n", hwaddr);
}
ret = ef_get_env_blob_offset(TEST_KEY1, hwaddr, sizeof(hwaddr), NULL, 2);
hwaddr[ret] = 0;
if (ret == 0) {
printf("read key1 failed\r\n");
} else {
printf("hwaddr+2:%s\r\n", hwaddr);
}
ret = ef_get_env_blob_offset(TEST_KEY1, hwaddr, sizeof(hwaddr), NULL, 3);
hwaddr[ret] = 0;
if (ret == 0) {
printf("read key1 failed\r\n");
} else {
printf("hwaddr+3:%s\r\n", hwaddr);
}
ret = ef_get_env_blob_offset(TEST_KEY1, hwaddr, sizeof(hwaddr), NULL, 100);
hwaddr[ret] = 0;
if (ret == 0) {
printf("read key1 failed\r\n");
} else {
printf("hwaddr+100:%s\r\n", hwaddr);
}
ret = ef_get_env_blob("aa/bb", hwaddr, sizeof(hwaddr), NULL);
hwaddr[ret] = 0;
if (ret == 0) {
printf("read aa/bb failed\r\n");
} else {
printf("hwaddr:%s\r\n", hwaddr);
}
ef_print_env();
printf("clear all kv\r\n");
/* reset all kv */
ef_env_set_default();
ef_print_env();
printf("easyflash case success\r\n");
while (1) {
}

View File

@ -1,3 +1,5 @@
set(CONFIG_EASYFLASH4 1)
set(CONFIG_LITTLEFS 1)
set(CONFIG_LITTLEFS_KV_EASYFLASH 1)
set(CONFIG_BFLB_MTD 1)
set(CONFIG_PARTITION 1)

View File

@ -6,6 +6,14 @@ skip_mode = 0x0, 0x0
# 0: not use isp mode, #1: isp mode
boot2_isp_mode = 0
[boot2]
filedir = ./build/build_out/boot2_*.bin
address = 0x000000
[partition]
filedir = ./build/build_out/partition*.bin
address = 0xE000
[FW]
filedir = ./build/build_out/littlefs_$(CHIPNAME).bin
address = 0x000000
address = @partition

View File

@ -2,7 +2,7 @@
#include "arch_psm.h"
extern lfs_t lfs;
extern lfs_t *lfs;
#ifndef CONFIG_KV_PSM_PATH
#define CONFIG_KV_PSM_PATH ""
@ -40,11 +40,11 @@ int arch_psm_get_value(const char *name_space, const char *key, void *value, siz
snprintf(name, CONFIG_KV_PSM_KEY_LEN, PSM_KV_FORMAT, CONFIG_KV_PSM_PATH, name_space, key);
fd = lfs_file_open(&lfs, &file, name, LFS_O_RDONLY);
fd = lfs_file_open(lfs, &file, name, LFS_O_RDONLY);
if (fd < 0)
return -1;
ret = lfs_stat(&lfs, name, &info);
ret = lfs_stat(lfs, name, &info);
if (ret < 0)
goto bail;
@ -53,11 +53,11 @@ int arch_psm_get_value(const char *name_space, const char *key, void *value, siz
if (payload > length)
goto bail;
ret = lfs_file_read(&lfs, &file, value, payload);
ret = lfs_file_read(lfs, &file, value, payload);
if (ret != payload)
goto bail;
ret = lfs_file_read(&lfs, &file, &crc, sizeof(uint8_t));
ret = lfs_file_read(lfs, &file, &crc, sizeof(uint8_t));
if (ret != sizeof(uint8_t))
goto bail;
@ -65,7 +65,7 @@ int arch_psm_get_value(const char *name_space, const char *key, void *value, siz
ret = -1;
bail:
lfs_file_close(&lfs, &file);
lfs_file_close(lfs, &file);
return ret > 0 ? payload : ret;
}
@ -86,29 +86,29 @@ int arch_psm_set_value(const char *name_space, const char *key, const void *valu
snprintf(name, CONFIG_KV_PSM_KEY_LEN, PSM_KV_FORMAT, CONFIG_KV_PSM_PATH, name_space, key);
ret = lfs_stat(&lfs, name, &info);
ret = lfs_stat(lfs, name, &info);
if (ret < 0) {
oflags = LFS_O_RDWR | LFS_O_CREAT;
} else {
oflags = LFS_O_RDWR | LFS_O_TRUNC;
}
fd = lfs_file_open(&lfs, &file, name, oflags);
fd = lfs_file_open(lfs, &file, name, oflags);
if (fd < 0)
return -1;
ret = lfs_file_write(&lfs, &file, value, length);
ret = lfs_file_write(lfs, &file, value, length);
if (ret != length)
goto bail;
crc = kvs_crc8((uint8_t *)value, length);
ret = lfs_file_write(&lfs, &file, &crc, sizeof(uint8_t));
ret = lfs_file_write(lfs, &file, &crc, sizeof(uint8_t));
bail:
ret_close = lfs_file_close(&lfs, &file);
ret_close = lfs_file_close(lfs, &file);
if ((ret_close < 0) && (oflags & LFS_O_CREAT)) {
lfs_remove(&lfs, name);
lfs_remove(lfs, name);
}
return ret < 0 ? ret : (ret_close < 0 ? ret_close : length);
@ -125,7 +125,7 @@ int arch_psm_erase_key(const char *name_space, const char *key)
snprintf(name, CONFIG_KV_PSM_KEY_LEN, PSM_KV_FORMAT, CONFIG_KV_PSM_PATH, name_space, key);
lfs_remove(&lfs, name);
lfs_remove(lfs, name);
return 0;
}

View File

@ -30,6 +30,7 @@
#include "bflb_l1c.h"
#include "bflb_uart.h"
#include "board.h"
#include "bflb_mtd.h"
#include "log.h"
#include "lfs.h"
@ -39,40 +40,14 @@
* Pre-processor Definitions
****************************************************************************/
/*!< use memory area after 512k */
#define LITTLEFS_FLASH_SIZE (0x71000)
#define LITTLEFS_FLASH_BLOCK_SIZE 4096
#define LITTLEFS_FLASH_BLOCK_COUNT (LITTLEFS_FLASH_SIZE / LITTLEFS_FLASH_BLOCK_SIZE)
#define LITTLEFS_FLASH_BLOCK_CYCLE 500
/****************************************************************************
* Private Data
****************************************************************************/
static struct bflb_device_s *uart0;
lfs_t lfs;
lfs_t *lfs;
lfs_file_t file;
/*!< configuration of the filesystem is provided by this struct */
const struct lfs_config cfg = {
// block device operations
.read = lfs_xip_flash_read,
.prog = lfs_xip_flash_prog,
.erase = lfs_xip_flash_erase,
.sync = lfs_xip_flash_sync,
// block device configuration
.read_size = 16,
.prog_size = 16,
.lookahead_size = 16,
.cache_size = 16,
.block_size = LITTLEFS_FLASH_BLOCK_SIZE,
.block_count = LITTLEFS_FLASH_BLOCK_COUNT,
.block_cycles = LITTLEFS_FLASH_BLOCK_CYCLE,
};
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
@ -88,45 +63,30 @@ SHELL_CMD_EXPORT_ALIAS(cmd_kv_test, kv_test, shell kv test);
int main(void)
{
board_init();
bflb_mtd_init();
uart0 = bflb_device_get_by_name("uart0");
shell_init_with_task(uart0);
// mount the filesystem
int err = lfs_mount(&lfs, &cfg);
// reformat if we can't mount the filesystem
// this should only happen on the first boot
if (err) {
LOG_W("try to reformat \r\n");
err = lfs_format(&lfs, &cfg);
if (err) {
LOG_F("reformat fail\r\n");
_CALL_ERROR();
}
LOG_I("reformat success\r\n");
err = lfs_mount(&lfs, &cfg);
if (err) {
LOG_F("mount fail\r\n");
_CALL_ERROR();
}
lfs = lfs_xip_init();
if (lfs == NULL) {
LOG_F("lfs_xip_init failed. errno: %d\r\n", errno);
while (1)
;
}
LOG_I("mount success\r\n");
// read current count
uint32_t boot_count = 0;
lfs_file_open(&lfs, &file, "boot_count", LFS_O_RDWR | LFS_O_CREAT);
lfs_file_read(&lfs, &file, &boot_count, sizeof(boot_count));
lfs_file_open(lfs, &file, "boot_count", LFS_O_RDWR | LFS_O_CREAT);
lfs_file_read(lfs, &file, &boot_count, sizeof(boot_count));
// update boot count
boot_count += 1;
lfs_file_rewind(&lfs, &file);
lfs_file_write(&lfs, &file, &boot_count, sizeof(boot_count));
lfs_file_rewind(lfs, &file);
lfs_file_write(lfs, &file, &boot_count, sizeof(boot_count));
// remember the storage is not updated until the file is closed successfully
lfs_file_close(&lfs, &file);
lfs_file_close(lfs, &file);
// release any resources we were using
// lfs_unmount(&lfs);

View File

@ -4,7 +4,10 @@ set(CONFIG_MBEDTLS 1)
set(CONFIG_SHELL 1)
set(CONFIG_LITTLEFS 1)
set(CONFIG_LITTLEFS_FLASH_ADDRESS 0x378000)
set(CONFIG_LITTLEFS_KV_EASYFLASH 1)
set(CONFIG_BFLB_MTD 1)
set(CONFIG_PARTITION 1)
# Config
## mbedtls
@ -23,4 +26,3 @@ add_definitions(-DCONFIG_KV_TEST_FILE_OPER_SUM=20000)
add_definitions(-DCONFIG_KV_TEST_FILE_OPER_PERIOD=1000)
add_definitions(-DCONFIG_KV_PSM_KEY_LEN=64)
# add_definitions(-DLFS_YES_TRACE)