Compare commits

..

No commits in common. 'master' and '4.0.0' have entirely different histories.

@ -1,6 +1,6 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2014-2020 Armink (armink.ztl@gmail.com) Copyright (c) 2014-2019 Armink (armink.ztl@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the a copy of this software and associated documentation files (the

@ -1,11 +1,9 @@
# EasyFlash # EasyFlash
[![GitHub release](https://img.shields.io/github/release/armink/EasyFlash.svg)](https://github.com/armink/EasyFlash/releases/latest) [![GitHub commits](https://img.shields.io/github/commits-since/armink/EasyFlash/4.1.0.svg)](https://github.com/armink/EasyFlash/compare/4.1.0...master) [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/armink/EasyFlash/master/LICENSE) [![GitHub release](https://img.shields.io/github/release/armink/EasyFlash.svg)](https://github.com/armink/EasyFlash/releases/latest) [![GitHub commits](https://img.shields.io/github/commits-since/armink/EasyFlash/3.3.0.svg)](https://github.com/armink/EasyFlash/compare/3.3.0...master) [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/armink/EasyFlash/master/LICENSE)
## 1、介绍[English](#1-introduction) ## 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 片上存储器。该库主要包括 **三大实用功能** [EasyFlash](https://github.com/armink/EasyFlash)是一款开源的轻量级嵌入式Flash存储器库方便开发者更加轻松的实现基于Flash存储器的常见应用开发。非常适合智能家居、可穿戴、工控、医疗、物联网等需要断电存储功能的产品资源占用极低支持各种 MCU 片上存储器。该库主要包括 **三大实用功能**
- **ENV** 快速保存产品参数,支持 **写平衡(磨损平衡)** 及 **掉电保护** 功能 - **ENV** 快速保存产品参数,支持 **写平衡(磨损平衡)** 及 **掉电保护** 功能
@ -20,13 +18,7 @@ EasyFlash不仅能够实现对产品的 **设定参数** 或 **运行日志**
非常适合应用在小型的不带文件系统的产品中,方便开发人员快速定位、查找系统发生崩溃或死机的原因。同时配合[EasyLogger](https://github.com/armink/EasyLogger)(我开源的超轻量级、高性能C日志库它提供与EasyFlash的无缝接口)一起使用轻松实现C日志的Flash存储功能。 非常适合应用在小型的不带文件系统的产品中,方便开发人员快速定位、查找系统发生崩溃或死机的原因。同时配合[EasyLogger](https://github.com/armink/EasyLogger)(我开源的超轻量级、高性能C日志库它提供与EasyFlash的无缝接口)一起使用轻松实现C日志的Flash存储功能。
### 1.1 两种 ENV 模式 ### 1.1、V4.0 NG 模式
目前 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) 模式,这是一个完全重构的新版本,具有以下新特性: 自 2019 年春节后EasyFlash 经过 4 年多的迭代,结合众多开发者的需求及建议,终于发布了 V4.0 版本,该版本中的 ENV 功能被命名为 **NG** (Next Generation) 模式,这是一个完全重构的新版本,具有以下新特性:
@ -35,32 +27,12 @@ EasyFlash不仅能够实现对产品的 **设定参数** 或 **运行日志**
- ENV 操作效率比以前的模式高,充分利用剩余空闲区域,擦除次数及操作时间显著降低; - ENV 操作效率比以前的模式高,充分利用剩余空闲区域,擦除次数及操作时间显著降低;
- **原生支持** 磨损平衡、掉电保护功能 V4.0 之前需要占用额外的 Flash 扇区); - **原生支持** 磨损平衡、掉电保护功能 V4.0 之前需要占用额外的 Flash 扇区);
- ENV 支持 **增量升级** ,固件升级后 ENV 也支持升级; - ENV 支持 **增量升级** ,固件升级后 ENV 也支持升级;
- 支持大数据存储模式,**长度无限制**,数据可在多个 Flash 扇区上顺序存储。像脚本程序、音频等占用 Flash 超过 1 个扇区的资源也都可以存入 ENV即将在 V4.2 支持); - 支持大数据存储模式,**长度无限制**,数据可在多个 Flash 扇区上顺序存储。像脚本程序、音频等占用 Flash 超过 1 个扇区的资源也都可以存入 ENV即将在 V4.1 支持);
- 支持 **数据加密** ,提升存储的安全性,物联网时代的必备功能(即将在 V4.3 支持); - 支持 **数据加密** ,提升存储的安全性,物联网时代的必备功能(即将在 V4.2 支持);
- 支持 **数据压缩** ,减低 Flash 占用(即将在 V4.4 支持); - 支持 **数据压缩** ,减低 Flash 占用(即将在 V4.3 支持);
V4.0 设计及内部原理V4.0 迁移指南等更多内容请继续阅读下面的 [文档章节](#3文档) 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、资源占用 ### 1.2、资源占用
``` ```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 18 KiB

@ -45,11 +45,10 @@
| ---------------------- | -------- | ------------ | ------------------------- | | ---------------------- | -------- | ------------ | ------------------------- |
| STM32F1 片内 Flash | 4bytes | 1K/2K | 均匀分布 | | STM32F1 片内 Flash | 4bytes | 1K/2K | 均匀分布 |
| STM32F2/F4 片内 Flash | 1byte | 16K/64K/128K | 最大的有128K最小的有16K | | STM32F2/F4 片内 Flash | 1byte | 16K/64K/128K | 最大的有128K最小的有16K |
| STM32L4 片内 Flash | 8bytes | 4K | 均匀分布 |
| Nor FlashSPI-Flash | 1bit | 4K | 均匀分布 | | Nor FlashSPI-Flash | 1bit | 4K | 均匀分布 |
> **注意** > **注意** 务必保证熟悉Flash规格后再继续下章节。
> - 1、务必保证熟悉Flash规格后再继续下章节
> - 2、V4.0 新模式暂时无法使用在 STM32L4 片内 Flash 上L4 只能使用 V3.0 版本或者 V4.0 的 EF_ENV_USING_LEGACY_MODE 模式
## 4、移植接口 ## 4、移植接口
@ -218,7 +217,7 @@ static const ef_env default_env_set[] = {
### 5.5 Flash 写入粒度 ### 5.5 Flash 写入粒度
- 操作方法:修改`EF_WRITE_GRAN`宏对应值即可单位bit仅支持1/8/32 - 操作方法:修改`EF_WRITE_GRAN`宏对应值即可单位bit仅支持1/8/32/64
### 5.5 备份区 ### 5.5 备份区

@ -30,24 +30,75 @@
#ifndef EASYFLASH_H_ #ifndef EASYFLASH_H_
#define EASYFLASH_H_ #define EASYFLASH_H_
#include <ef_cfg.h>
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include <stdbool.h> #include <stdbool.h>
#include <ef_cfg.h>
#include <ef_def.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/* EasyFlash debug print function. Must be implement by user. */
#ifdef PRINT_DEBUG
#define EF_DEBUG(...) ef_log_debug(__FILE__, __LINE__, __VA_ARGS__)
#else
#define EF_DEBUG(...)
#endif
/* EasyFlash routine print function. Must be implement by user. */
#define EF_INFO(...) ef_log_info(__VA_ARGS__)
/* EasyFlash assert for developer. */
#define EF_ASSERT(EXPR) \
if (!(EXPR)) \
{ \
EF_DEBUG("(%s) has assert failed at %s.\n", #EXPR, __FUNCTION__); \
while (1); \
}
/**
* ENV version number defined by user.
* Please change it when your firmware add a new ENV to default_env_set.
*/
#ifndef EF_ENV_VER_NUM
#define EF_ENV_VER_NUM 0
#endif
/* EasyFlash software version number */
#define EF_SW_VERSION "4.0.0"
#define EF_SW_VERSION_NUM 0x40000
typedef struct _ef_env {
char *key;
void *value;
size_t value_len;
} ef_env, *ef_env_t;
/* 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,
} EfErrCode;
/* the flash sector current status */
typedef enum {
EF_SECTOR_EMPTY,
EF_SECTOR_USING,
EF_SECTOR_FULL,
} EfSecrorStatus;
/* easyflash.c */ /* easyflash.c */
EfErrCode easyflash_init(void); EfErrCode easyflash_init(void);
#ifdef EF_USING_ENV #ifdef EF_USING_ENV
/* only supported on ef_env.c */ /* 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); size_t ef_get_env_blob(const char *key, void *value_buf, size_t buf_len, size_t *saved_value_len);
bool ef_get_env_obj(const char *key, env_node_obj_t env);
size_t ef_read_env_value(env_node_obj_t env, uint8_t *value_buf, size_t buf_len);
EfErrCode ef_set_env_blob(const char *key, const void *value_buf, size_t buf_len); EfErrCode ef_set_env_blob(const char *key, const void *value_buf, size_t buf_len);
/* ef_env.c, ef_env_legacy_wl.c and ef_env_legacy.c */ /* ef_env.c, ef_env_legacy_wl.c and ef_env_legacy.c */
@ -85,7 +136,6 @@ 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_write(const uint32_t *log, size_t size);
EfErrCode ef_log_clean(void); EfErrCode ef_log_clean(void);
size_t ef_log_get_used_size(void); size_t ef_log_get_used_size(void);
size_t ef_log_get_total_size(void);
#endif #endif
/* ef_utils.c */ /* ef_utils.c */

@ -40,10 +40,6 @@
* Please change it when your firmware add a new ENV to default_env_set. * Please change it when your firmware add a new ENV to default_env_set.
*/ */
#define EF_ENV_VER_NUM /* @note you must define it for a value, such as 0 */ #define EF_ENV_VER_NUM /* @note you must define it for a value, such as 0 */
/* MCU Endian Configuration, default is Little Endian Order. */
/* #define EF_BIG_ENDIAN */
#endif /* EF_USING_ENV */ #endif /* EF_USING_ENV */
/* using IAP function */ /* using IAP function */
@ -56,12 +52,9 @@
#define EF_ERASE_MIN_SIZE /* @note you must define it for a value */ #define EF_ERASE_MIN_SIZE /* @note you must define it for a value */
/* the flash write granularity, unit: bit /* the flash write granularity, unit: bit
* only support 1(nor flash)/ 8(stm32f4)/ 32(stm32f1) */ * only support 1(nor flash)/ 8(stm32f4)/ 32(stm32f1)/ 64(stm32l4) */
#define EF_WRITE_GRAN /* @note you must define it for a value */ #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. * This all Backup Area Flash storage index. All used flash area configure is under here.

@ -1,124 +0,0 @@
/*
* This file is part of the EasyFlash Library.
*
* Copyright (c) 2019-2020, Armink, <armink.ztl@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* 'Software'), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Function: It is the definitions head file for this library.
* Created on: 2019-11-20
*/
#ifndef EF_DEF_H_
#define EF_DEF_H_
#ifdef __cplusplus
extern "C" {
#endif
/* EasyFlash software version number */
#define EF_SW_VERSION "4.1.99"
#define EF_SW_VERSION_NUM 0x40199
/*
* ENV version number defined by user.
* Please change it when your firmware add a new ENV to default_env_set.
*/
#ifndef EF_ENV_VER_NUM
#define EF_ENV_VER_NUM 0
#endif
/* the ENV max name length must less then it */
#ifndef EF_ENV_NAME_MAX
#define EF_ENV_NAME_MAX 32
#endif
/* EasyFlash debug print function. Must be implement by user. */
#ifdef PRINT_DEBUG
#define EF_DEBUG(...) ef_log_debug(__FILE__, __LINE__, __VA_ARGS__)
#else
#define EF_DEBUG(...)
#endif
/* EasyFlash routine print function. Must be implement by user. */
#define EF_INFO(...) ef_log_info(__VA_ARGS__)
/* EasyFlash assert for developer. */
#define EF_ASSERT(EXPR) \
if (!(EXPR)) \
{ \
EF_DEBUG("(%s) has assert failed at %s.\n", #EXPR, __FUNCTION__); \
while (1); \
}
typedef struct _ef_env {
char *key;
void *value;
size_t value_len;
} ef_env, *ef_env_t;
/* 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,
} EfErrCode;
/* the flash sector current status */
typedef enum {
EF_SECTOR_EMPTY,
EF_SECTOR_USING,
EF_SECTOR_FULL,
} EfSecrorStatus;
enum env_status {
ENV_UNUSED,
ENV_PRE_WRITE,
ENV_WRITE,
ENV_PRE_DELETE,
ENV_DELETED,
ENV_ERR_HDR,
ENV_STATUS_NUM,
};
typedef enum env_status env_status_t;
struct env_node_obj {
env_status_t status; /**< ENV node status, @see node_status_t */
bool crc_is_ok; /**< ENV node CRC32 check is OK */
uint8_t name_len; /**< name length */
uint32_t magic; /**< magic word(`K`, `V`, `4`, `0`) */
uint32_t len; /**< ENV node total length (header + name + value), must align by EF_WRITE_GRAN */
uint32_t value_len; /**< value length */
char name[EF_ENV_NAME_MAX]; /**< name */
struct {
uint32_t start; /**< ENV node start address */
uint32_t value; /**< value start address */
} addr;
};
typedef struct env_node_obj *env_node_obj_t;
#ifdef __cplusplus
}
#endif
#endif /* EF_DEF_H_ */

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

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

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

@ -1,7 +1,7 @@
/* /*
* This file is part of the EasyFlash Library. * This file is part of the EasyFlash Library.
* *
* Copyright (c) 2015-2019, Armink, <armink.ztl@gmail.com> * Copyright (c) 2015, Armink, <armink.ztl@gmail.com>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
@ -64,6 +64,8 @@ EfErrCode ef_port_init(ef_env const **default_env, size_t *default_env_size) {
EfErrCode ef_port_read(uint32_t addr, uint32_t *buf, size_t size) { EfErrCode ef_port_read(uint32_t addr, uint32_t *buf, size_t size) {
EfErrCode result = EF_NO_ERR; EfErrCode result = EF_NO_ERR;
EF_ASSERT(size % 4 == 0);
/* You can add your code under here. */ /* You can add your code under here. */
return result; return result;
@ -103,6 +105,8 @@ EfErrCode ef_port_erase(uint32_t addr, size_t size) {
EfErrCode ef_port_write(uint32_t addr, const uint32_t *buf, size_t size) { EfErrCode ef_port_write(uint32_t addr, const uint32_t *buf, size_t size) {
EfErrCode result = EF_NO_ERR; EfErrCode result = EF_NO_ERR;
EF_ASSERT(size % 4 == 0);
/* You can add your code under here. */ /* You can add your code under here. */
return result; return result;

@ -71,11 +71,6 @@ EfErrCode easyflash_init(void) {
size_t default_env_set_size = 0; size_t default_env_set_size = 0;
const ef_env *default_env_set; const ef_env *default_env_set;
EfErrCode result = EF_NO_ERR; EfErrCode result = EF_NO_ERR;
static bool init_ok = false;
if (init_ok) {
return EF_NO_ERR;
}
result = ef_port_init(&default_env_set, &default_env_set_size); result = ef_port_init(&default_env_set, &default_env_set_size);
@ -98,7 +93,6 @@ EfErrCode easyflash_init(void) {
#endif #endif
if (result == EF_NO_ERR) { if (result == EF_NO_ERR) {
init_ok = true;
EF_INFO("EasyFlash V%s is initialize success.\n", EF_SW_VERSION); EF_INFO("EasyFlash V%s is initialize success.\n", EF_SW_VERSION);
} else { } else {
EF_INFO("EasyFlash V%s is initialize fail.\n", EF_SW_VERSION); EF_INFO("EasyFlash V%s is initialize fail.\n", EF_SW_VERSION);

@ -39,6 +39,11 @@
#error "the write gran can be only setting as 1, 8, 32 and 64" #error "the write gran can be only setting as 1, 8, 32 and 64"
#endif #endif
/* the ENV max name length must less then it */
#ifndef EF_ENV_NAME_MAX
#define EF_ENV_NAME_MAX 32
#endif
/* magic word(`E`, `F`, `4`, `0`) */ /* magic word(`E`, `F`, `4`, `0`) */
#define SECTOR_MAGIC_WORD 0x30344645 #define SECTOR_MAGIC_WORD 0x30344645
/* magic word(`K`, `V`, `4`, `0`) */ /* magic word(`K`, `V`, `4`, `0`) */
@ -149,6 +154,17 @@ enum sector_dirty_status {
}; };
typedef enum sector_dirty_status sector_dirty_status_t; typedef enum sector_dirty_status sector_dirty_status_t;
enum env_status {
ENV_UNUSED,
ENV_PRE_WRITE,
ENV_WRITE,
ENV_PRE_DELETE,
ENV_DELETED,
ENV_ERR_HDR,
ENV_STATUS_NUM,
};
typedef enum env_status env_status_t;
struct sector_hdr_data { struct sector_hdr_data {
struct { struct {
uint8_t store[STORE_STATUS_TABLE_SIZE]; /**< sector store status @see sector_store_status_t */ uint8_t store[STORE_STATUS_TABLE_SIZE]; /**< sector store status @see sector_store_status_t */
@ -184,6 +200,21 @@ struct env_hdr_data {
}; };
typedef struct env_hdr_data *env_hdr_data_t; typedef struct env_hdr_data *env_hdr_data_t;
struct env_meta_data {
env_status_t status; /**< ENV node status, @see node_status_t */
bool crc_is_ok; /**< ENV node CRC32 check is OK */
uint8_t name_len; /**< name length */
uint32_t magic; /**< magic word(`K`, `V`, `4`, `0`) */
uint32_t len; /**< ENV node total length (header + name + value), must align by EF_WRITE_GRAN */
uint32_t value_len; /**< value length */
char name[EF_ENV_NAME_MAX]; /**< name */
struct {
uint32_t start; /**< ENV node start address */
uint32_t value; /**< value start address */
} addr;
};
typedef struct env_meta_data *env_meta_data_t;
struct env_cache_node { struct env_cache_node {
uint16_t name_crc; /**< ENV name's CRC32 low 16bit value */ uint16_t name_crc; /**< ENV name's CRC32 low 16bit value */
uint16_t active; /**< ENV node access active degree */ uint16_t active; /**< ENV node access active degree */
@ -424,17 +455,12 @@ 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) static uint32_t continue_ff_addr(uint32_t start, uint32_t end)
{ {
uint8_t buf[EF_READ_BUF_SIZE], last_data = 0x00; uint8_t buf[32], last_data = 0x00;
size_t i, addr = start, read_size; size_t i, addr = start;
for (; start < end; start += sizeof(buf)) { for (; start < end; start += sizeof(buf)) {
if (start + sizeof(buf) < end) { ef_port_read(start, (uint32_t *) buf, sizeof(buf));
read_size = sizeof(buf); for (i = 0; i < sizeof(buf) && start + i < end; i++) {
} else {
read_size = end - start;
}
ef_port_read(start, (uint32_t *) buf, read_size);
for (i = 0; i < read_size; i++) {
if (last_data != 0xFF && buf[i] == 0xFF) { if (last_data != 0xFF && buf[i] == 0xFF) {
addr = start + i; addr = start + i;
} }
@ -469,11 +495,7 @@ static uint32_t find_next_env_addr(uint32_t start, uint32_t end)
for (; start < end; start += (sizeof(buf) - sizeof(uint32_t))) { for (; start < end; start += (sizeof(buf) - sizeof(uint32_t))) {
ef_port_read(start, (uint32_t *) buf, sizeof(buf)); ef_port_read(start, (uint32_t *) buf, sizeof(buf));
for (i = 0; i < sizeof(buf) - sizeof(uint32_t) && start + i < end; i++) { for (i = 0; i < sizeof(buf) - sizeof(uint32_t) && start + i < end; i++) {
#ifndef EF_BIG_ENDIAN /* Little Endian Order */
magic = buf[i] + (buf[i + 1] << 8) + (buf[i + 2] << 16) + (buf[i + 3] << 24); magic = buf[i] + (buf[i + 1] << 8) + (buf[i + 2] << 16) + (buf[i + 3] << 24);
#else /* Big Endian Order */
magic = buf[i + 3] + (buf[i + 2] << 8) + (buf[i + 1] << 16) + (buf[i] << 24);
#endif
if (magic == ENV_MAGIC_WORD && (start + i - ENV_MAGIC_OFFSET) >= start_bak) { if (magic == ENV_MAGIC_WORD && (start + i - ENV_MAGIC_OFFSET) >= start_bak) {
return start + i - ENV_MAGIC_OFFSET; return start + i - ENV_MAGIC_OFFSET;
} }
@ -483,7 +505,7 @@ static uint32_t find_next_env_addr(uint32_t start, uint32_t end)
return FAILED_ADDR; return FAILED_ADDR;
} }
static uint32_t get_next_env_addr(sector_meta_data_t sector, env_node_obj_t pre_env) static uint32_t get_next_env_addr(sector_meta_data_t sector, env_meta_data_t pre_env)
{ {
uint32_t addr = FAILED_ADDR; uint32_t addr = FAILED_ADDR;
@ -507,7 +529,7 @@ static uint32_t get_next_env_addr(sector_meta_data_t sector, env_node_obj_t pre_
addr = find_next_env_addr(addr, sector->addr + SECTOR_SIZE - SECTOR_HDR_DATA_SIZE); addr = find_next_env_addr(addr, sector->addr + SECTOR_SIZE - SECTOR_HDR_DATA_SIZE);
if (addr > sector->addr + SECTOR_SIZE || pre_env->len == 0) { if (addr > sector->addr + SECTOR_SIZE || pre_env->len == 0) {
//TODO 扇区连续模式 //TODO 扇区连续模式
return FAILED_ADDR; return FAILED_ADDR;
} }
} else { } else {
@ -519,10 +541,10 @@ static uint32_t get_next_env_addr(sector_meta_data_t sector, env_node_obj_t pre_
return addr; return addr;
} }
static EfErrCode read_env(env_node_obj_t env) static EfErrCode read_env(env_meta_data_t env)
{ {
struct env_hdr_data env_hdr; struct env_hdr_data env_hdr;
uint8_t buf[EF_READ_BUF_SIZE]; uint8_t buf[32];
uint32_t calc_crc32 = 0, crc_data_len, env_name_addr; uint32_t calc_crc32 = 0, crc_data_len, env_name_addr;
EfErrCode result = EF_NO_ERR; EfErrCode result = EF_NO_ERR;
size_t len, size; size_t len, size;
@ -542,7 +564,7 @@ static EfErrCode read_env(env_node_obj_t env)
env->crc_is_ok = false; env->crc_is_ok = false;
return EF_READ_ERR; return EF_READ_ERR;
} else if (env->len > SECTOR_SIZE - SECTOR_HDR_DATA_SIZE && env->len < ENV_AREA_SIZE) { } else if (env->len > SECTOR_SIZE - SECTOR_HDR_DATA_SIZE && env->len < ENV_AREA_SIZE) {
//TODO 扇区连续模式,或者写入长度没有写入完整 //TODO 扇区连续模式,或者写入长度没有写入完整
EF_ASSERT(0); EF_ASSERT(0);
} }
@ -593,7 +615,6 @@ static EfErrCode read_sector_meta_data(uint32_t addr, sector_meta_data_t sector,
/* check magic word */ /* check magic word */
if (sector->magic != SECTOR_MAGIC_WORD) { if (sector->magic != SECTOR_MAGIC_WORD) {
sector->check_ok = false; sector->check_ok = false;
sector->combined = SECTOR_NOT_COMBINED;
return EF_ENV_INIT_FAILED; return EF_ENV_INIT_FAILED;
} }
sector->check_ok = true; sector->check_ok = true;
@ -608,7 +629,7 @@ static EfErrCode read_sector_meta_data(uint32_t addr, sector_meta_data_t sector,
if (sector->status.store == SECTOR_STORE_EMPTY) { if (sector->status.store == SECTOR_STORE_EMPTY) {
sector->remain = SECTOR_SIZE - SECTOR_HDR_DATA_SIZE; sector->remain = SECTOR_SIZE - SECTOR_HDR_DATA_SIZE;
} else if (sector->status.store == SECTOR_STORE_USING) { } else if (sector->status.store == SECTOR_STORE_USING) {
struct env_node_obj env_meta; struct env_meta_data env_meta;
#ifdef EF_ENV_USING_CACHE #ifdef EF_ENV_USING_CACHE
if (get_sector_from_cache(addr, &sector->empty_env)) { if (get_sector_from_cache(addr, &sector->empty_env)) {
@ -677,8 +698,8 @@ static uint32_t get_next_sector_addr(sector_meta_data_t pre_sec)
} }
} }
static void env_iterator(env_node_obj_t env, void *arg1, void *arg2, static void env_iterator(env_meta_data_t env, void *arg1, void *arg2,
bool (*callback)(env_node_obj_t env, void *arg1, void *arg2)) bool (*callback)(env_meta_data_t env, void *arg1, void *arg2))
{ {
struct sector_meta_data sector; struct sector_meta_data sector;
uint32_t sec_addr; uint32_t sec_addr;
@ -707,24 +728,24 @@ static void env_iterator(env_node_obj_t env, void *arg1, void *arg2,
} }
} }
static bool find_env_cb(env_node_obj_t env, void *arg1, void *arg2) static bool find_env_cb(env_meta_data_t env, void *arg1, void *arg2)
{ {
const char *key = arg1; const char *key = arg1;
bool *find_ok = arg2; bool *find_ok = arg2;
size_t key_len = strlen(key); uint8_t max_len = strlen(key);
if (key_len != env->name_len) { if (max_len < env->name_len) {
return false; max_len = env->name_len;
} }
/* check ENV */ /* check ENV */
if (env->crc_is_ok && env->status == ENV_WRITE && !strncmp(env->name, key, key_len)) { if (env->crc_is_ok && env->status == ENV_WRITE && !strncmp(env->name, key, max_len)) {
*find_ok = true; *find_ok = true;
return true; return true;
} }
return false; return false;
} }
static bool find_env_no_cache(const char *key, env_node_obj_t env) static bool find_env_no_cache(const char *key, env_meta_data_t env)
{ {
bool find_ok = false; bool find_ok = false;
@ -733,7 +754,7 @@ static bool find_env_no_cache(const char *key, env_node_obj_t env)
return find_ok; return find_ok;
} }
static bool find_env(const char *key, env_node_obj_t env) static bool find_env(const char *key, env_meta_data_t env)
{ {
bool find_ok = false; bool find_ok = false;
@ -772,7 +793,7 @@ static bool ef_is_str(uint8_t *value, size_t len)
static size_t get_env(const char *key, void *value_buf, size_t buf_len, size_t *value_len) static size_t get_env(const char *key, void *value_buf, size_t buf_len, size_t *value_len)
{ {
struct env_node_obj env; struct env_meta_data env;
size_t read_len = 0; size_t read_len = 0;
if (find_env(key, &env)) { if (find_env(key, &env)) {
@ -784,44 +805,12 @@ static size_t get_env(const char *key, void *value_buf, size_t buf_len, size_t *
} else { } else {
read_len = buf_len; read_len = buf_len;
} }
if (value_buf){ ef_port_read(env.addr.value, (uint32_t *) value_buf, read_len);
ef_port_read(env.addr.value, (uint32_t *) value_buf, read_len);
}
} else if (value_len) {
*value_len = 0;
} }
return read_len; return read_len;
} }
/**
* Get a ENV object by key name
*
* @param key ENV name
* @param env ENV object
*
* @return TRUE: find the ENV is OK, else return false
*/
bool ef_get_env_obj(const char *key, env_node_obj_t env)
{
bool find_ok = false;
if (!init_ok) {
EF_INFO("ENV isn't initialize OK.\n");
return 0;
}
/* lock the ENV cache */
ef_port_env_lock();
find_ok = find_env(key, env);
/* unlock the ENV cache */
ef_port_env_unlock();
return find_ok;
}
/** /**
* Get a blob ENV value by key name. * Get a blob ENV value by key name.
* *
@ -881,45 +870,6 @@ char *ef_get_env(const char *key)
return NULL; return NULL;
} }
/**
* read the ENV value by ENV object
*
* @param env ENV object
* @param value_buf the buffer for store ENV value
* @param buf_len buffer length
*
* @return the actually read size on successful
*/
size_t ef_read_env_value(env_node_obj_t env, uint8_t *value_buf, size_t buf_len)
{
size_t read_len = 0;
EF_ASSERT(env);
EF_ASSERT(value_buf);
if (!init_ok) {
EF_INFO("ENV isn't initialize OK.\n");
return 0;
}
if (env->crc_is_ok) {
/* lock the ENV cache */
ef_port_env_lock();
if (buf_len > env->value_len) {
read_len = env->value_len;
} else {
read_len = buf_len;
}
ef_port_read(env->addr.value, (uint32_t *) value_buf, read_len);
/* unlock the ENV cache */
ef_port_env_unlock();
}
return read_len;
}
static EfErrCode write_env_hdr(uint32_t addr, env_hdr_data_t env_hdr) { static EfErrCode write_env_hdr(uint32_t addr, env_hdr_data_t env_hdr) {
EfErrCode result = EF_NO_ERR; EfErrCode result = EF_NO_ERR;
/* write the status will by write granularity */ /* write the status will by write granularity */
@ -1066,7 +1016,7 @@ static uint32_t alloc_env(sector_meta_data_t sector, size_t env_size)
return empty_env; return empty_env;
} }
static EfErrCode del_env(const char *key, env_node_obj_t old_env, bool complete_del) { static EfErrCode del_env(const char *key, env_meta_data_t old_env, bool complete_del) {
EfErrCode result = EF_NO_ERR; EfErrCode result = EF_NO_ERR;
uint32_t dirty_status_addr; uint32_t dirty_status_addr;
static bool last_is_complete_del = false; static bool last_is_complete_del = false;
@ -1079,7 +1029,7 @@ static EfErrCode del_env(const char *key, env_node_obj_t old_env, bool complete_
/* need find ENV */ /* need find ENV */
if (!old_env) { if (!old_env) {
struct env_node_obj env; struct env_meta_data env;
/* find ENV */ /* find ENV */
if (find_env(key, &env)) { if (find_env(key, &env)) {
old_env = &env; old_env = &env;
@ -1097,14 +1047,8 @@ static EfErrCode del_env(const char *key, env_node_obj_t old_env, bool complete_
if (!last_is_complete_del && result == EF_NO_ERR) { if (!last_is_complete_del && result == EF_NO_ERR) {
#ifdef EF_ENV_USING_CACHE #ifdef EF_ENV_USING_CACHE
/* delete the ENV in flash and cache */ /* only delete the ENV in flash and cache when only using del_env(key, env, true) in ef_del_env() */
if (key != NULL) { update_env_cache(key, strlen(key), FAILED_ADDR);
/* when using del_env(key, NULL, true) or del_env(key, env, true) in ef_del_env() and set_env() */
update_env_cache(key, strlen(key), FAILED_ADDR);
} else if (old_env != NULL) {
/* when using del_env(NULL, env, true) in move_env() */
update_env_cache(old_env->name, old_env->name_len, FAILED_ADDR);
}
#endif /* EF_ENV_USING_CACHE */ #endif /* EF_ENV_USING_CACHE */
} }
@ -1124,7 +1068,7 @@ static EfErrCode del_env(const char *key, env_node_obj_t old_env, bool complete_
/* /*
* move the ENV to new space * move the ENV to new space
*/ */
static EfErrCode move_env(env_node_obj_t env) static EfErrCode move_env(env_meta_data_t env)
{ {
EfErrCode result = EF_NO_ERR; EfErrCode result = EF_NO_ERR;
uint8_t status_table[ENV_STATUS_TABLE_SIZE]; uint8_t status_table[ENV_STATUS_TABLE_SIZE];
@ -1138,7 +1082,7 @@ static EfErrCode move_env(env_node_obj_t env)
if ((env_addr = alloc_env(&sector, env->len)) != FAILED_ADDR) { if ((env_addr = alloc_env(&sector, env->len)) != FAILED_ADDR) {
if (in_recovery_check) { if (in_recovery_check) {
struct env_node_obj env_bak; struct env_meta_data env_bak;
char name[EF_ENV_NAME_MAX + 1] = { 0 }; char name[EF_ENV_NAME_MAX + 1] = { 0 };
strncpy(name, env->name, env->name_len); strncpy(name, env->name, env->name_len);
/* check the ENV in flash is already create success */ /* check the ENV in flash is already create success */
@ -1225,7 +1169,7 @@ static bool gc_check_cb(sector_meta_data_t sector, void *arg1, void *arg2)
static bool do_gc(sector_meta_data_t sector, void *arg1, void *arg2) static bool do_gc(sector_meta_data_t sector, void *arg1, void *arg2)
{ {
struct env_node_obj env; struct env_meta_data env;
if (sector->check_ok && (sector->status.dirty == SECTOR_DIRTY_TRUE || sector->status.dirty == SECTOR_DIRTY_GC)) { if (sector->check_ok && (sector->status.dirty == SECTOR_DIRTY_TRUE || sector->status.dirty == SECTOR_DIRTY_GC)) {
uint8_t status_table[DIRTY_STATUS_TABLE_SIZE]; uint8_t status_table[DIRTY_STATUS_TABLE_SIZE];
@ -1286,13 +1230,9 @@ static EfErrCode align_write(uint32_t addr, const uint32_t *buf, size_t size)
#endif #endif
memset(align_data, 0xFF, align_data_size); memset(align_data, 0xFF, align_data_size);
align_remain = EF_WG_ALIGN_DOWN(size);//use align_remain temporary to save aligned size. result = ef_port_write(addr, buf, EF_WG_ALIGN_DOWN(size));
if(align_remain > 0){//it may be 0 in this function.
result = ef_port_write(addr, buf, align_remain);
}
align_remain = size - align_remain; align_remain = size - EF_WG_ALIGN_DOWN(size);
if (result == EF_NO_ERR && align_remain) { if (result == EF_NO_ERR && align_remain) {
memcpy(align_data, (uint8_t *)buf + EF_WG_ALIGN_DOWN(size), 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); result = ef_port_write(addr + EF_WG_ALIGN_DOWN(size), (uint32_t *) align_data, align_data_size);
@ -1426,7 +1366,7 @@ EfErrCode ef_del_and_save_env(const char *key)
static EfErrCode set_env(const char *key, const void *value_buf, size_t buf_len) static EfErrCode set_env(const char *key, const void *value_buf, size_t buf_len)
{ {
EfErrCode result = EF_NO_ERR; EfErrCode result = EF_NO_ERR;
static struct env_node_obj env; static struct env_meta_data env;
static struct sector_meta_data sector; static struct sector_meta_data sector;
bool env_is_found = false; bool env_is_found = false;
@ -1577,7 +1517,7 @@ __exit:
return result; return result;
} }
static bool print_env_cb(env_node_obj_t env, void *arg1, void *arg2) static bool print_env_cb(env_meta_data_t env, void *arg1, void *arg2)
{ {
bool value_is_str = true, print_value = false; bool value_is_str = true, print_value = false;
size_t *using_size = arg1; size_t *using_size = arg1;
@ -1630,7 +1570,7 @@ __reload:
*/ */
void ef_print_env(void) void ef_print_env(void)
{ {
struct env_node_obj env; struct env_meta_data env;
size_t using_size = 0; size_t using_size = 0;
if (!init_ok) { if (!init_ok) {
@ -1662,7 +1602,7 @@ static void env_auto_update(void)
if (get_env(VER_NUM_ENV_NAME, &saved_ver_num, sizeof(size_t), NULL) > 0) { if (get_env(VER_NUM_ENV_NAME, &saved_ver_num, sizeof(size_t), NULL) > 0) {
/* check version number */ /* check version number */
if (saved_ver_num != setting_ver_num) { if (saved_ver_num != setting_ver_num) {
struct env_node_obj env; struct env_meta_data env;
size_t i, value_len; size_t i, value_len;
struct sector_meta_data sector; struct sector_meta_data sector;
EF_DEBUG("Update the ENV from version %d to %d.\n", saved_ver_num, setting_ver_num); EF_DEBUG("Update the ENV from version %d to %d.\n", saved_ver_num, setting_ver_num);
@ -1715,7 +1655,7 @@ static bool check_and_recovery_gc_cb(sector_meta_data_t sector, void *arg1, void
return false; return false;
} }
static bool check_and_recovery_env_cb(env_node_obj_t env, void *arg1, void *arg2) static bool check_and_recovery_env_cb(env_meta_data_t env, void *arg1, void *arg2)
{ {
/* recovery the prepare deleted ENV */ /* recovery the prepare deleted ENV */
if (env->crc_is_ok && env->status == ENV_PRE_DELETE) { if (env->crc_is_ok && env->status == ENV_PRE_DELETE) {
@ -1730,7 +1670,7 @@ static bool check_and_recovery_env_cb(env_node_obj_t env, void *arg1, void *arg2
} else if (env->status == ENV_PRE_WRITE) { } else if (env->status == ENV_PRE_WRITE) {
uint8_t status_table[ENV_STATUS_TABLE_SIZE]; uint8_t status_table[ENV_STATUS_TABLE_SIZE];
/* the ENV has not write finish, change the status to error */ /* the ENV has not write finish, change the status to error */
//TODO 绘制异常处理的状态装换图 //TODO 绘制异常处理的状态装换图
write_status(env->addr.start, status_table, ENV_STATUS_NUM, ENV_ERR_HDR); write_status(env->addr.start, status_table, ENV_STATUS_NUM, ENV_ERR_HDR);
return true; return true;
} }
@ -1746,10 +1686,13 @@ static bool check_and_recovery_env_cb(env_node_obj_t env, void *arg1, void *arg2
EfErrCode ef_load_env(void) EfErrCode ef_load_env(void)
{ {
EfErrCode result = EF_NO_ERR; EfErrCode result = EF_NO_ERR;
struct env_node_obj env; struct env_meta_data env;
struct sector_meta_data sector; struct sector_meta_data sector;
size_t check_failed_count = 0; size_t check_failed_count = 0;
/* lock the ENV cache */
ef_port_env_lock();
in_recovery_check = true; in_recovery_check = true;
/* check all sector header */ /* check all sector header */
sector_iterator(&sector, SECTOR_STORE_UNUSED, &check_failed_count, NULL, check_sec_hdr_cb, false); sector_iterator(&sector, SECTOR_STORE_UNUSED, &check_failed_count, NULL, check_sec_hdr_cb, false);
@ -1758,9 +1701,6 @@ EfErrCode ef_load_env(void)
EF_INFO("Warning: All sector header check failed. Set it to default.\n"); EF_INFO("Warning: All sector header check failed. Set it to default.\n");
ef_env_set_default(); ef_env_set_default();
} }
/* lock the ENV cache */
ef_port_env_lock();
/* check all sector header for recovery GC */ /* check all sector header for recovery GC */
sector_iterator(&sector, SECTOR_STORE_UNUSED, NULL, NULL, check_and_recovery_gc_cb, false); sector_iterator(&sector, SECTOR_STORE_UNUSED, NULL, NULL, check_and_recovery_gc_cb, false);

@ -410,23 +410,6 @@ size_t ef_log_get_used_size(void) {
return physical_size - header_total_num * LOG_SECTOR_HEADER_SIZE; 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. * Sequential reading log data. It will ignore sector headers.
* *
@ -474,15 +457,14 @@ static uint32_t log_index2addr(size_t index) {
size_t sector_num = index / (EF_ERASE_MIN_SIZE - LOG_SECTOR_HEADER_SIZE) + 1; size_t sector_num = index / (EF_ERASE_MIN_SIZE - LOG_SECTOR_HEADER_SIZE) + 1;
header_total_offset = sector_num * LOG_SECTOR_HEADER_SIZE; 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) { if (log_start_addr < log_end_addr) {
return virtual_addr; return log_start_addr + index + header_total_offset;
} else { } else {
if (log_start_addr + index + header_total_offset < log_area_start_addr + LOG_AREA_SIZE) { if (log_start_addr + index + header_total_offset < log_area_start_addr + LOG_AREA_SIZE) {
return virtual_addr; return log_start_addr + index + header_total_offset;
} else { } else {
// the address will restart from the first sector address. return log_start_addr + index + header_total_offset - LOG_AREA_SIZE;
return virtual_addr - (log_area_start_addr + LOG_AREA_SIZE) + log_area_start_addr;
} }
} }
} }
@ -508,14 +490,8 @@ EfErrCode ef_log_read(size_t index, uint32_t *log, size_t size) {
return result; return result;
} }
if (size % 4 != 0) { EF_ASSERT(size % 4 == 0);
EF_DEBUG("Error: size must be word aligned."); EF_ASSERT(index < cur_using_size);
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) { if (index + size > cur_using_size) {
EF_DEBUG("Warning: Log read size out of bound. Cut read size.\n"); EF_DEBUG("Warning: Log read size out of bound. Cut read size.\n");

Loading…
Cancel
Save