[update][littlefs] add easyflash porting for littlefs

This commit is contained in:
jzlv 2023-11-17 16:19:38 +08:00
parent f7a325f047
commit 0f6fe31094
15 changed files with 747 additions and 104 deletions

View File

@ -11,7 +11,15 @@ 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})
endif()
endif()

View File

@ -0,0 +1,52 @@
/*
* This file is the header file that adapts LittleFS to EasyFlash4.
*/
#ifndef EASYFLASH_H_
#define EASYFLASH_H_
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/* EasyFlash error code */
typedef enum {
EF_NO_ERR,
EF_ERASE_ERR,
EF_READ_ERR,
EF_WRITE_ERR,
EF_ENV_NAME_ERR,
EF_ENV_NAME_EXIST,
EF_ENV_FULL,
EF_ENV_INIT_FAILED,
EF_ENV_ARG_ERR,
} EfErrCode;
/* easyflash.c */
EfErrCode easyflash_init(void);
/* only supported on ef_env.c */
size_t ef_get_env_blob(const char *key, void *value_buf, size_t buf_len, size_t *saved_value_len);
EfErrCode ef_set_env_blob(const char *key, const void *value_buf, size_t buf_len);
char *ef_get_env(const char *key) __attribute__((deprecated("Not recommended, use ef_get_env_blob instead")));
EfErrCode ef_set_env(const char *key, const char *value);
EfErrCode ef_del_env(const char *key);
EfErrCode ef_save_env(void);
/* clear all env */
EfErrCode ef_env_set_default(void);
EfErrCode ef_set_and_save_env(const char *key, const char *value);
EfErrCode ef_del_and_save_env(const char *key);
#ifdef __cplusplus
}
#endif
#endif /* EASYFLASH_H_ */

View File

@ -0,0 +1,298 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <errno.h>
#ifdef CONFIG_FREERTOS
#include <FreeRTOS.h>
#include <semphr.h>
#endif
#define DBG_TAG "LFS"
#include "log.h"
#include "lfs.h"
#include "lfs_port.h"
#include "easyflash.h"
static lfs_t *lfs = NULL;
static char key_buffer[64];
#ifndef LFS_EF_NAMESPACE
#define LFS_EF_NAMESPACE "/_ef4_kvs_"
#endif
#ifdef CONFIG_FREERTOS
static SemaphoreHandle_t env_giant_lock = NULL;
#endif
/* littlefs init */
EfErrCode
easyflash_init(void)
{
struct lfs_info stat;
int32_t ret;
lfs = lfs_xip_init();
if (lfs == NULL) {
LOG_E("littlefs backend init failed.\r\n");
return EF_ENV_INIT_FAILED;
}
#ifdef CONFIG_FREERTOS
#if configUSE_RECURSIVE_MUTEXES
env_giant_lock = xSemaphoreCreateRecursiveMutex();
#else
env_giant_lock = xSemaphoreCreateMutex();
#endif
#endif
/* init namespace */
ret = lfs_stat(lfs, LFS_EF_NAMESPACE, &stat);
if (ret == LFS_ERR_OK) {
if (stat.type == LFS_TYPE_DIR) {
return EF_NO_ERR;
} else if (stat.type == LFS_TYPE_REG) {
LOG_E("namespace directory conflicts with standard file.\r\n");
return EF_ENV_INIT_FAILED;
}
}
ret = lfs_mkdir(lfs, LFS_EF_NAMESPACE);
if (ret != LFS_ERR_OK) {
errno = -ret;
LOG_E("create namespace directory failed.\r\n");
return EF_ENV_INIT_FAILED;
}
return EF_NO_ERR;
}
#ifdef CONFIG_FREERTOS
static void ef_giant_lock(void)
{
#if configUSE_RECURSIVE_MUTEXES
xSemaphoreTakeRecursive(env_giant_lock, portMAX_DELAY);
#else
xSemaphoreTake(env_giant_lock, portMAX_DELAY);
#endif
}
static void ef_giant_unlock(void)
{
#if configUSE_RECURSIVE_MUTEXES
xSemaphoreGiveRecursive(env_giant_lock);
#else
xSemaphoreGive(env_giant_lock);
#endif
}
#define EF_GIANT_LOCK() ef_giant_lock()
#define EF_GIANT_UNLOCK(ret) \
ef_giant_unlock(); \
return (ret)
#else
#define EF_GIANT_LOCK()
#define EF_GIANT_UNLOCK(ret) return (ret)
#endif
/* only supported on ef_env.c */
size_t
ef_get_env_blob(const char *key, void *value_buf, size_t buf_len, size_t *saved_value_len)
{
lfs_file_t file;
int32_t ret, read_len;
if (lfs == NULL) {
return 0;
}
if (key == NULL || value_buf == NULL || buf_len == 0) {
return 0;
}
EF_GIANT_LOCK();
ret = snprintf(key_buffer, sizeof(key_buffer), "%s/%s", LFS_EF_NAMESPACE, key);
if (ret >= sizeof(key_buffer)) {
LOG_E("key name is too long to truncated.\r\n");
EF_GIANT_UNLOCK(0);
}
ret = lfs_file_open(lfs, &file, key_buffer, LFS_O_RDONLY);
if (ret != LFS_ERR_OK) {
errno = -ret;
EF_GIANT_UNLOCK(0);
}
ret = lfs_file_read(lfs, &file, value_buf, buf_len);
if (ret < 0) {
LOG_E("lfs_file_read failed with errno:%d.\r\n", ret);
errno = -ret;
lfs_file_close(lfs, &file);
EF_GIANT_UNLOCK(0);
}
read_len = ret;
if (saved_value_len != NULL) {
ret = lfs_file_size(lfs, &file);
if (ret < 0) {
LOG_E("lfs_file_size failed with errno:%d.\r\n", ret);
lfs_file_close(lfs, &file);
errno = -ret;
EF_GIANT_UNLOCK(0);
}
*saved_value_len = ret;
}
lfs_file_close(lfs, &file);
EF_GIANT_UNLOCK(read_len);
}
EfErrCode
ef_set_env_blob(const char *key, const void *value_buf, size_t buf_len)
{
lfs_file_t file;
int32_t ret;
if (lfs == NULL) {
return EF_ENV_INIT_FAILED;
}
if (key == NULL || value_buf == NULL || buf_len == 0) {
return EF_ENV_ARG_ERR;
}
EF_GIANT_LOCK();
ret = snprintf(key_buffer, sizeof(key_buffer), "%s/%s", LFS_EF_NAMESPACE, key);
if (ret >= sizeof(key_buffer)) {
LOG_E("key name is too long to truncated.\r\n");
EF_GIANT_UNLOCK(EF_ENV_NAME_ERR);
}
ret = lfs_file_open(lfs, &file, key_buffer, LFS_O_RDWR | LFS_O_CREAT);
if (ret != LFS_ERR_OK) {
errno = -ret;
LOG_E("lfs_file_open failed with errno:%d\r\n", ret);
EF_GIANT_UNLOCK(EF_WRITE_ERR);
}
ret = lfs_file_truncate(lfs, &file, buf_len);
if (ret != LFS_ERR_OK) {
errno = -ret;
LOG_E("lfs_file_truncate failed with errno:%d\r\n", ret);
lfs_file_close(lfs, &file);
EF_GIANT_UNLOCK(EF_WRITE_ERR);
}
ret = lfs_file_write(lfs, &file, value_buf, buf_len);
if (ret != buf_len) {
errno = -ret;
LOG_E("lfs_file_write failed with errno:%d.\r\n", ret);
lfs_file_close(lfs, &file);
EF_GIANT_UNLOCK(EF_WRITE_ERR);
}
lfs_file_close(lfs, &file);
EF_GIANT_UNLOCK(EF_NO_ERR);
}
EfErrCode
ef_del_env(const char *key)
{
int32_t ret;
if (lfs == NULL) {
return EF_ENV_INIT_FAILED;
}
if (key == NULL) {
return EF_ENV_ARG_ERR;
}
ret = snprintf(key_buffer, sizeof(key_buffer), "%s/%s", LFS_EF_NAMESPACE, key);
if (ret >= sizeof(key_buffer)) {
LOG_E("key name is too long to truncated.\r\n");
EF_GIANT_UNLOCK(EF_ENV_NAME_ERR);
}
lfs_remove(lfs, key_buffer);
return EF_ENV_ARG_ERR;
}
/****************************************************************************
* DEPRECATED DEPRECATED-DEPRECATED-DEPRECATED-DEPRECATED-DEPRECATED
***************************************************************************/
static bool ef_is_str(uint8_t *value, size_t len)
{
#define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
size_t i;
for (i = 0; i < len; i++) {
if (!__is_print(value[i])) {
return false;
}
}
return true;
}
/****************************************************************************
* DEPRECATED DEPRECATED-DEPRECATED-DEPRECATED-DEPRECATED-DEPRECATED
***************************************************************************/
char *
ef_get_env(const char *key)
{
#ifndef EF_STR_ENV_VALUE_MAX_SIZE
#define EF_STR_ENV_VALUE_MAX_SIZE (3979)
#endif
static char value[EF_STR_ENV_VALUE_MAX_SIZE + 1];
size_t get_size;
printf("WARNING!!! ef_get_env is deprecated, use ef_get_env_blob instead.\r\n");
get_size = ef_get_env_blob(key, value, EF_STR_ENV_VALUE_MAX_SIZE, NULL);
if (get_size > 0 && ef_is_str((uint8_t *)value, get_size)) {
value[get_size] = '\0';
return value;
} else {
LOG_W("The ENV value isn't string. Could not be returned\r\n");
return NULL;
}
}
EfErrCode
ef_set_env(const char *key, const char *value)
{
return ef_set_env_blob(key, value, strlen(value));
}
EfErrCode
ef_save_env(void)
{
return EF_NO_ERR;
}
/* clear all env */
EfErrCode
ef_env_set_default(void)
{
return EF_ENV_ARG_ERR;
}
EfErrCode
ef_set_and_save_env(const char *key, const char *value)
{
return ef_set_env(key, value);
}
EfErrCode
ef_del_and_save_env(const char *key)
{
return ef_del_env(key);
}

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 = 16,
.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

@ -0,0 +1,9 @@
cmake_minimum_required(VERSION 3.15)
include(proj.conf)
find_package(bouffalo_sdk REQUIRED HINTS $ENV{BL_SDK_BASE})
sdk_set_main_file(main.c)
project(easyflash)

View File

@ -0,0 +1,13 @@
SDK_DEMO_PATH ?= .
BL_SDK_BASE ?= $(SDK_DEMO_PATH)/../..
export BL_SDK_BASE
CHIP ?= bl616
BOARD ?= bl616dk
CROSS_COMPILE ?= riscv64-unknown-elf-
# add custom cmake definition
#cmake_definition+=-Dxxx=sss
include $(BL_SDK_BASE)/project.build

View File

@ -0,0 +1,44 @@
# easyflash
## Support CHIP
| CHIP | Remark |
|:----------------:|:------:|
|BL602/BL604 | |
|BL702/BL704/BL706 | |
|BL616/BL618 | |
|BL808 | |
## Compile
- BL602/BL604
```
make CHIP=bl602 BOARD=bl602dk
```
- BL702/BL704/BL706
```
make CHIP=bl702 BOARD=bl702dk
```
- BL616/BL618
```
make CHIP=bl616 BOARD=bl616dk
```
- BL808
```
make CHIP=bl808 BOARD=bl808dk CPU_ID=m0
make CHIP=bl808 BOARD=bl808dk CPU_ID=d0
```
## Flash
```
make flash CHIP=chip_name COMX=xxx # xxx is your com name
```

View File

@ -0,0 +1,20 @@
[cfg]
# 0: no erase, 1:programmed section erase, 2: chip erase
erase = 1
# skip mode set first para is skip addr, second para is skip len, multi-segment region with ; separated
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/easyflash_$(CHIPNAME).bin
address = @partition

67
examples/easyflash/main.c Normal file
View File

@ -0,0 +1,67 @@
#include "bflb_mtimer.h"
#include "board.h"
#include "bflb_mtd.h"
#include "easyflash.h"
uint8_t test_data[] = { "1234567890" };
uint8_t read_buffer[100];
#define WIFI_SSID_KEY "wifi.ssid"
#define WIFI_PASSWD_KEY "wifi.passwd"
int main(void)
{
board_init();
/* 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"
device = 0
address0 = 0x3E9000
size0 = 0x8000
address1 = 0
size1 = 0
# compressed image must set len,normal image can left it to 0
len = 0
# If header is 1, it will add the header.
header = 0
# If header is 1 and security is 1, It will be encrypted.
security= 0
*/
bflb_mtd_init();
easyflash_init();
printf("errno: %d\r\n", errno);
memset(read_buffer, 0, sizeof(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_save_env();
char ssid[33];
char passwd[65];
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);
}
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("easyflash case success\r\n");
while (1) {
}
}

View File

@ -0,0 +1,5 @@
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)