Compare commits

..

21 Commits

Author SHA1 Message Date
朱天龙 (Armink) a67fffcb4a
Merge pull request #159 from shiyj/master
[fix] 当环形缓冲的开始地址大于结束地址时,index转成地址时要加上log_area_start_addr
2 years ago
shiyj f9adf31468 [fix] 当环形缓冲的开始地址大于结束地址时,index转成地址时要加上log_area_start_addr
由于整个存储的起始地址不一定是LOG_AREA_SIZE的倍数,不可通过取余获取偏移
2 years ago
朱天龙 (Armink) 7b2073086a
Merge pull request #157 from kaidegit/patch-1
修复被cpp调用时的一点小问题
2 years ago
Kai 9e525c7475
add extern c if cpp 2 years ago
朱天龙 (Armink) bee1918ebd
Merge pull request #155 from i-jaffer/develop
[fix] fix byte alignment logic judgment error bug.
3 years ago
jaffer cbb16391b1 Merge branch 'fix/align_judge_bug' into develop 3 years ago
jaffer ac971cb63d [feat]fix byte alignment logic judgment error bug.
Signed-off-by: jaffer <jaffer.work@foxmail.com>
3 years ago
朱天龙 (Armink) f732982f71
Merge pull request #149 from i-jaffer/feat/calcu_usage
[feat]增加log总大小计算接口
3 years ago
Jaffer 90bc6d5c06
Merge pull request #1 from i-jaffer/feat/calcu_usage
Merge from feat/calcu_usage to develop.
3 years ago
jaffer 06370af0a2 [feat]增加log总大小计算接口。
Signed-off-by: jaffer <jaffer.work@foxmail.com>
3 years ago
朱天龙 (Armink) aaa168123f
Merge pull request #148 from i-jaffer/master
[fix][log]修复log index2addr 计算溢出风险以及优化 ef_log_read 函数参数错误判断处理 #146 #147
3 years ago
jaffer a5f09478f7 [fix]修复log index2addr 溢出实际物理地址空间风险
Signed-off-by: jaffer <jaffer.work@foxmail.com>
3 years ago
jaffer af12a8e8a7 [fix]优化日志log读取函数接口参数错误判断处理
Signed-off-by: jaffer <jaffer.work@foxmail.com>
3 years ago
朱天龙 (Armink) 91eb583605
Merge pull request #139 from iysheng/master
1. Fix compile error with incompatible types and function argument mismatch in README
3 years ago
朱天龙 (Armink) 4e992a8917
Merge pull request #145 from wu1045718093/perf-first-write-speed
[优化]优化启动时读写速度
3 years ago
teng.wu c5b48a4736 [优化]优化启动时读写速度 3 years ago
iysheng c2879bbf75 1. Fix compile error with incompatible types
2. Fix function argument mismatch in README
4 years ago
朱天龙 (Armink) f886316b3f
Merge pull request #128 from mx1117/master
Update ef_env.c
4 years ago
mx1117 d80224448a Update ef_env.c
EF_WG_ALIGN_DOWN(size) 可能为0,需要额外判断以避免某些芯片flash写0长度数据出错。
4 years ago
armink ef3556f202 【更新】图片素材
Signed-off-by: armink <armink.ztl@gmail.com>
5 years ago
armink 173b09d718 【完善】说明文档
Signed-off-by: armink <armink.ztl@gmail.com>
6 years ago

@ -4,6 +4,8 @@
## 1、介绍[English](#1-introduction)
> **提示** :从 EasyFlash V4.1 后,基于 EasyFlash 全新设计开发的 [FlashDB](https://github.com/armink/FlashDB) 开源项目正式上线新集成了时序数据库、多分区管理多数据库实例等功能也从一定程度上提升了整体性能欢迎关注https://github.com/armink/FlashDB 。同时,现有的 EasyFlash 也会继续维护。
[EasyFlash](https://github.com/armink/EasyFlash)是一款开源的轻量级嵌入式Flash存储器库方便开发者更加轻松的实现基于Flash存储器的常见应用开发。非常适合智能家居、可穿戴、工控、医疗、物联网等需要断电存储功能的产品资源占用极低支持各种 MCU 片上存储器。该库主要包括 **三大实用功能**
- **ENV** 快速保存产品参数,支持 **写平衡(磨损平衡)** 及 **掉电保护** 功能
@ -18,7 +20,13 @@ EasyFlash不仅能够实现对产品的 **设定参数** 或 **运行日志**
非常适合应用在小型的不带文件系统的产品中,方便开发人员快速定位、查找系统发生崩溃或死机的原因。同时配合[EasyLogger](https://github.com/armink/EasyLogger)(我开源的超轻量级、高性能C日志库它提供与EasyFlash的无缝接口)一起使用轻松实现C日志的Flash存储功能。
### 1.1、V4.0 NG 模式
### 1.1 两种 ENV 模式
目前 ENV 功能有两种主要模式,一种为 V4.0 带来的 **NG** 模式,还有一种为延续 V3.0 的 **legacy** 模式
#### 1.1.1、V4.0 引入的 NG 模式
> 对应源码文件为: `ef_env.c`
自 2019 年春节后EasyFlash 经过 4 年多的迭代,结合众多开发者的需求及建议,终于发布了 V4.0 版本,该版本中的 ENV 功能被命名为 **NG** (Next Generation) 模式,这是一个完全重构的新版本,具有以下新特性:
@ -33,6 +41,26 @@ EasyFlash不仅能够实现对产品的 **设定参数** 或 **运行日志**
V4.0 设计及内部原理V4.0 迁移指南等更多内容请继续阅读下面的 [文档章节](#3文档)
> **注意** :个别 Flash 存在无法逆序写入的问题,例如 STM32L4 片内 Flash所以无法使用 NG 模式,这种情况下建议使用 V3.0 的 legacy 模式
#### 1.1.2、延续 V3.0 的 legacy 模式
> 对应源码文件为: `ef_env_legacy.c``ef_env_legacy_wl.c`
**legacy** 模式也具有磨损平衡及掉电保护功能,相比于 V 4.0 NG 模式,使用 legacy 模式,需要有额外的 RAM 空间来临时缓存每个 ENV ,最终调用 save 接口,统一擦除扇区再存储到 Flash 上。
#### 1.1.3 ENV 模式对比
| | V4.0 NG 模式 | V3.0 legacy 模式 |
| -------------------- | ------------------------------------------ | ------------------------ |
| RAM 资源占用 | 低 | 高 |
| 支持 Flash 全面性 | 个别 Flash 受限:例如 STM32L4 片内 | 比较全面 |
| 是否需要 GC 垃圾回收 | 需要 GC ,这会导致触发 GC 时,写入速度变慢 | 不需要 |
| value 类型限制 | 无限制 | 对字符串类型支持的比较好 |
| 掉电保护 | 支持 | 支持 |
| 磨损平衡 | 支持 | 支持 |
| 增量升级 | 支持 | 支持 |
### 1.2、资源占用
```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

@ -85,6 +85,7 @@ EfErrCode ef_log_read(size_t index, uint32_t *log, size_t size);
EfErrCode ef_log_write(const uint32_t *log, size_t size);
EfErrCode ef_log_clean(void);
size_t ef_log_get_used_size(void);
size_t ef_log_get_total_size(void);
#endif
/* ef_utils.c */

@ -59,6 +59,9 @@
* only support 1(nor flash)/ 8(stm32f4)/ 32(stm32f1) */
#define EF_WRITE_GRAN /* @note you must define it for a value */
/* The size of read_env and continue_ff_addr function used*/
#define EF_READ_BUF_SIZE 32 /* @default 32, Larger numbers can improve first-time speed of alloc_env but require more stack space*/
/*
*
* This all Backup Area Flash storage index. All used flash area configure is under here.

@ -142,7 +142,7 @@ ef_set_struct("
/* 获取结构体类型环境变量 */
Student *student;
ef_get_struct("张三学生", student, stu_get_cb);
student = ef_get_struct("张三学生", stu_get_cb);
/* 打印获取到的结构体内容 */
printf("姓名:%s 籍贯:%s \n", student->name, student->hometown.name);

@ -82,7 +82,7 @@ long ef_get_long(const char *key) {
return atol(value);
} else {
EF_INFO("Couldn't find this ENV(%s)!\n", key);
return NULL;
return 0;
}
}
@ -96,7 +96,7 @@ double ef_get_double(const char *key) {
return atof(value);
} else {
EF_INFO("Couldn't find this ENV(%s)!\n", key);
return NULL;
return 0;
}
}

@ -33,6 +33,10 @@
#include <stdbool.h>
#include "struct2json\inc\s2j.h"
#ifdef __cplusplus
extern "C" {
#endif
/* EasyFlash types plugin's software version number */
#define EF_TYPES_SW_VERSION "0.11.03"
@ -73,4 +77,8 @@ EfErrCode ef_set_double_array(const char *key, double *value, size_t len);
EfErrCode ef_set_string_array(const char *key, char **value, size_t len);
EfErrCode ef_set_struct(const char *key, void *value, ef_types_set_cb set_cb);
#ifdef __cplusplus
}
#endif
#endif /* EF_TYPES_H_ */

@ -424,7 +424,7 @@ static bool get_env_from_cache(const char *name, size_t name_len, uint32_t *addr
*/
static uint32_t continue_ff_addr(uint32_t start, uint32_t end)
{
uint8_t buf[32], last_data = 0x00;
uint8_t buf[EF_READ_BUF_SIZE], last_data = 0x00;
size_t i, addr = start, read_size;
for (; start < end; start += sizeof(buf)) {
@ -522,7 +522,7 @@ static uint32_t get_next_env_addr(sector_meta_data_t sector, env_node_obj_t pre_
static EfErrCode read_env(env_node_obj_t env)
{
struct env_hdr_data env_hdr;
uint8_t buf[32];
uint8_t buf[EF_READ_BUF_SIZE];
uint32_t calc_crc32 = 0, crc_data_len, env_name_addr;
EfErrCode result = EF_NO_ERR;
size_t len, size;
@ -1194,16 +1194,11 @@ static uint32_t new_env(sector_meta_data_t sector, size_t env_size)
__retry:
if ((empty_env = alloc_env(sector, env_size)) == FAILED_ADDR) {
if (gc_request && !already_gc) {
EF_DEBUG("Warning: Alloc an ENV (size %d) failed when new ENV. Now will GC then retry.\n", env_size);
gc_collect();
already_gc = true;
goto __retry;
} else {
EF_DEBUG("Error: Alloc an ENV (size %d) failed after GC. ENV full.\n", env_size);
gc_request = false;
}
if ((empty_env = alloc_env(sector, env_size)) == FAILED_ADDR && gc_request && !already_gc) {
EF_DEBUG("Warning: Alloc an ENV (size %d) failed when new ENV. Now will GC then retry.\n", env_size);
gc_collect();
already_gc = true;
goto __retry;
}
return empty_env;
@ -1291,9 +1286,13 @@ static EfErrCode align_write(uint32_t addr, const uint32_t *buf, size_t size)
#endif
memset(align_data, 0xFF, align_data_size);
result = ef_port_write(addr, buf, EF_WG_ALIGN_DOWN(size));
align_remain = EF_WG_ALIGN_DOWN(size);//use align_remain temporary to save aligned size.
if(align_remain > 0){//it may be 0 in this function.
result = ef_port_write(addr, buf, align_remain);
}
align_remain = size - EF_WG_ALIGN_DOWN(size);
align_remain = size - align_remain;
if (result == EF_NO_ERR && align_remain) {
memcpy(align_data, (uint8_t *)buf + EF_WG_ALIGN_DOWN(size), align_remain);
result = ef_port_write(addr + EF_WG_ALIGN_DOWN(size), (uint32_t *) align_data, align_data_size);

@ -410,6 +410,23 @@ size_t ef_log_get_used_size(void) {
return physical_size - header_total_num * LOG_SECTOR_HEADER_SIZE;
}
/**
* Get log flash total size.
*
* @return log flash total size. @note NOT contain sector headers
*/
size_t ef_log_get_total_size(void) {
size_t header_total_num = 0;
/* must be call this function after initialize OK */
if (!init_ok) {
return 0;
}
header_total_num = LOG_AREA_SIZE / EF_ERASE_MIN_SIZE;
return LOG_AREA_SIZE - header_total_num * LOG_SECTOR_HEADER_SIZE;
}
/**
* Sequential reading log data. It will ignore sector headers.
*
@ -457,14 +474,15 @@ static uint32_t log_index2addr(size_t index) {
size_t sector_num = index / (EF_ERASE_MIN_SIZE - LOG_SECTOR_HEADER_SIZE) + 1;
header_total_offset = sector_num * LOG_SECTOR_HEADER_SIZE;
uint32_t virtual_addr = log_start_addr + index + header_total_offset;
if (log_start_addr < log_end_addr) {
return log_start_addr + index + header_total_offset;
return virtual_addr;
} else {
if (log_start_addr + index + header_total_offset < log_area_start_addr + LOG_AREA_SIZE) {
return log_start_addr + index + header_total_offset;
return virtual_addr;
} else {
return log_start_addr + index + header_total_offset - LOG_AREA_SIZE;
// the address will restart from the first sector address.
return virtual_addr - (log_area_start_addr + LOG_AREA_SIZE) + log_area_start_addr;
}
}
}
@ -490,8 +508,14 @@ EfErrCode ef_log_read(size_t index, uint32_t *log, size_t size) {
return result;
}
EF_ASSERT(size % 4 == 0);
EF_ASSERT(index < cur_using_size);
if (size % 4 != 0) {
EF_DEBUG("Error: size must be word aligned.");
return EF_READ_ERR;
}
if (index >= cur_using_size) {
EF_DEBUG("Error: index out of ranges, current using size is %d", cur_using_size);
return EF_READ_ERR;
}
if (index + size > cur_using_size) {
EF_DEBUG("Warning: Log read size out of bound. Cut read size.\n");

Loading…
Cancel
Save