Delete docs directory

pull/134/head
removedporn 4 years ago committed by GitHub
parent f886316b3f
commit 9350dfdbf4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1 +0,0 @@
# Coming soon...

Binary file not shown.

Before

Width:  |  Height:  |  Size: 268 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 196 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 277 KiB

@ -1,3 +0,0 @@
|File name |Description|
|:----- |:----|
|api.md |API description|

@ -1,4 +0,0 @@
|File or folder name |Description|
|:----- |:----|
|en |English documents|
|zh |中文文档(简体)|

@ -1,299 +0,0 @@
# EasyFlash API 说明
---
所有支持的API接口都在[`\easyflash\inc\easyflash.h`](https://github.com/armink/EasyFlash/blob/master/easyflash/inc/easyflash.h)中声明。以下内容较多,建议使用 **CTRL+F** 搜索。
名词介绍:
- **备份区** 是EasyFlash定义的一个存放环境变量、已下载程序及日志的Flash区域详细存储架构可以参考[`\easyflash\src\easyflash.c`](https://github.com/armink/EasyFlash/blob/master/easyflash/src/easyflash.c#L29-L58)文件头位置的注释说明或[移植文档中关于备份区参数配置](https://github.com/armink/EasyFlash/blob/master/docs/zh/port.md#55-备份区)。
## 1、用户使用接口
### 1.1 初始化
初始化的EasyFlash的各个组件初始化后才可以使用下面的API。
针对环境变量组件,如果 flash 第一次初始化,会自动调用 `ef_env_set_default` ,恢复移植文件中定义的默认环境变量(详见移植文档),之后每次启动会自动检查 flash 中的环境变量状态flash 出现严重损坏时也会恢复环境变量至默认。如果开启增量升级功能,还会做增量升级的检查,版本号不一致时执行增量升级。
```C
EfErrCode easyflash_init(void)
```
### 1.2 环境变量
在 V4.0 以后,环境变量在 EasyFlash 底层都是按照二进制数据格式进行存储,即 **blob 格式** ,这样上层支持传入任意类型。而在 V4.0 之前底层使用的是字符串格式进行存储,字符串格式的环境变量也可以转换为 blob 格式,所以 V4.0 能做到完全兼容以前的 API ,例如:`ef_get_env/ef_set_env` ,这些 API **只能** 给字符串 ENV 使用。
另外字符串 ENV 也有长度的限制,默认 `EF_STR_ENV_VALUE_MAX_SIZE` 配置为 128 字节,超过长度的可能无法使用 `ef_get_env` 获取,只能使用 `ef_get_env_blob` 获取。
#### 1.2.1 获取环境变量
通过环境变量的名字来获取其对应的值。支持两种接口
##### 1.2.1.1 获取 blob 类型环境变量
```C
size_t ef_get_env_blob(const char *key, void *value_buf, size_t buf_len, size_t *save_value_len)
```
|参数 |描述|
|:----- |:----|
|key |环境变量名称|
|value_buf |存放环境变量的缓冲区|
|buf_len |该缓冲区的大小|
|save_value_len |返回该环境变量实际存储在 flash 中的大小|
|返回 |成功存放至缓冲区中的数据长度|
示例:
```C
char value[32];
size_t len;
/* 如果环境变量长度未知,可以先获取 Flash 上存储的实际长度,将通过 len 返回 */
ef_get_env_blob("key", NULL, 0, &len);
/* 如果长度已知,使用 value 缓冲区,存放读取回来的环境变量值数据,并将实际长度返回 */
len = ef_get_env_blob("key", value, sizeof(value) , NULL);
```
##### 1.2.1.2 获取字符串类型环境变量
**注意**
- 该函数**已废弃**,不推荐继续使用,可以使用上面的函数替代;
- 该函数不允许连续使用,使用时需使用 strdup 包裹,确保每次返回回来的字符串内存空间独立;
- 该函数不支持可重入,返回的值位于函数内部缓冲区,出于安全考虑,请加锁保护。
```C
char *ef_get_env(const char *key)
```
|参数 |描述|
|:----- |:----|
|key |环境变量名称|
|返回 |环境变量值|
#### 1.2.2 设置环境变量
使用此方法可以实现对环境变量的增加、修改及删除功能。
- **增加** :当环境变量表中不存在该名称的环境变量时,则会执行新增操作;
- **修改** :入参中的环境变量名称在当前环境变量表中存在,则把该环境变量值修改为入参中的值;
- **删除**当入参中的value为NULL时则会删除入参名对应的环境变量。
##### 1.2.1.1 设置 blob 类型环境变量
```C
EfErrCode ef_set_env_blob(const char *key, const void *value_buf, size_t buf_len)
```
|参数 |描述|
|:----- |:----|
|key |环境变量名称|
|value_buf |环境变量值缓冲区|
|buf_len |缓冲区长度,即值的长度|
##### 1.2.1.2 设置字符串类型环境变量
```C
EfErrCode ef_set_env(const char *key, const char *value)
```
|参数 |描述|
|:----- |:----|
|key |环境变量名称|
|value |环境变量值|
#### 1.2.3 删除环境变量
使用此方法可以实现对环境变量的删除功能。
```c
EfErrCode ef_del_env(const char *key)
```
| 参数 | 描述 |
| :--- | :----------- |
| key | 环境变量名称 |
#### 1.2.4 重置环境变量
将内存中的环境变量表重置为默认值。关于默认环境变量的设定方法可以参考移植文档。
```C
EfErrCode ef_env_set_default(void)
```
#### 1.2.5 打印环境变量
通过在移植接口([`\easyflash\port\ef_port.c`](https://github.com/armink/EasyFlash/blob/master/easyflash/port/ef_port.c))中定义的`ef_print`打印方法来将Flash中的所有环境变量输出出来。
```C
void ef_print_env(void)
```
### 1.3 在线升级
#### 1.3.1 擦除备份区中的应用程序
```C
EfErrCode ef_erase_bak_app(size_t app_size)
```
#### 1.3.2 擦除用户的应用程序
注意:请不要在应用程序中调用该方法
```C
EfErrCode ef_erase_user_app(uint32_t user_app_addr, size_t user_app_size)
```
|参数 |描述|
|:----- |:----|
|user_app_addr |用户应用程序入口地址|
|user_app_size |用户应用程序大小|
#### 1.3.3 通过用户指定的擦除方法来擦除应用程序
当用户的应用程序与备份区 **不在同一个** Flash 时,则需要用户额外指定擦除应用程序的方法。而 `ef_erase_user_app` 会使用移植文件中的 `ef_port_erase` 方法进行擦除,除此之外的其余功能,两个方法均一致。
注意:请不要在应用程序中调用该方法
```C
EfErrCode ef_erase_spec_user_app(uint32_t user_app_addr, size_t app_size,
EfErrCode (*app_erase)(uint32_t addr, size_t size));
```
|参数 |描述|
|:----- |:----|
|user_app_addr |用户应用程序入口地址|
|user_app_size |用户应用程序大小|
|app_erase |用户指定应用程序擦写方法|
#### 1.3.4 擦除Bootloader
注意请不要在Bootloader中调用该方法
```C
EfErrCode ef_erase_bl(uint32_t bl_addr, size_t bl_size)
```
|参数 |描述|
|:----- |:----|
|bl_addr |Bootloader入口地址|
|bl_size |Bootloader大小|
#### 1.3.5 写数据到备份区
为下载程序到备份区定制的Flash连续写方法。
注意写之前请先确认Flash已进行擦除。
```C
EfErrCode ef_write_data_to_bak(uint8_t *data,
size_t size,
size_t *cur_size,
size_t total_size)
```
|参数 |描述|
|:----- |:----|
|data |需要写入到备份区中的数据存储地址|
|size |此次写入数据的大小(字节)|
|cur_size |之前已写入到备份区中的数据大小(字节)|
|total_size |需要写入到备份区的数据总大小(字节)|
#### 1.3.6 从备份拷贝应用程序
将备份区已下载好的应用程序拷贝至用户应用程序起始地址。
注意:
1、拷贝前必须对原有的应用程序进行擦除
2、不要在应用程序中调用该方法
```C
EfErrCode ef_copy_app_from_bak(uint32_t user_app_addr, size_t app_size)
```
|参数 |描述|
|:----- |:----|
|user_app_addr |用户应用程序入口地址|
|user_app_size |用户应用程序大小|
#### 1.3.7 通过用户指定的写操作方法来拷贝应用程序
当用户的应用程序与备份区 **不在同一个** Flash 时,则需要用户额外指定写应用程序的方法。而 `ef_copy_app_from_bak` 会使用移植文件中的 `ef_port_write` 方法进行写操作,除此之外的其余功能,两个方法均一致。
```C
EfErrCode ef_copy_spec_app_from_bak(uint32_t user_app_addr, size_t app_size,
EfErrCode (*app_write)(uint32_t addr, const uint32_t *buf, size_t size))
```
|参数 |描述|
|:----- |:----|
|user_app_addr |用户应用程序入口地址|
|user_app_size |用户应用程序大小|
|app_write |用户指定应用程序写操作方法|
#### 1.3.8 从备份拷贝Bootloader
将备份区已下载好的Bootloader拷贝至Bootloader起始地址。
注意:
1、拷贝前必须对原有的Bootloader进行擦除
2、不要在Bootloader中调用该方法
```C
EfErrCode ef_copy_bl_from_bak(uint32_t bl_addr, size_t bl_size)
```
|参数 |描述|
|:----- |:----|
|bl_addr |Bootloader入口地址|
|bl_size |Bootloader大小|
### 1.4 日志存储
#### 1.4.1 从Flash中读取已存在的日志
```C
EfErrCode ef_log_read(size_t index, uint32_t *log, size_t size);
```
|参数 |描述|
|:----- |:----|
|index |日志读取的索引顺序|
|log |存储待读取日志的缓冲区|
|size |读取日志的大小|
#### 1.4.2 往Flash中保存日志
```C
EfErrCode ef_log_write(const uint32_t *log, size_t size);
```
|参数 |描述|
|:----- |:----|
|log |存储待保存的日志|
|size |待保存日志的大小|
#### 1.4.3 清空存储在Flash中全部日志
```C
EfErrCode ef_log_clean(void);
```
#### 1.4.4 获取已存储在Flash中的日志大小
```C
size_t ef_log_get_used_size(void);
```
## 2、配置
参照EasyFlash 移植说明([`\docs\zh\port.md`](https://github.com/armink/EasyFlash/blob/master/docs/zh/port.md#5设置参数))中的 `设置参数` 章节
## 3、注意
- 写数据前务必记得先擦除
- 不要在应用程序及Bootloader中执行擦除及拷贝自身的动作
- Log功能对Flash擦除和写入要求4个字节对齐擦除的最小单位则需根据用户的平台来确定

@ -1,95 +0,0 @@
# EasyFlash V4.0 ENV 功能设计与实现
## 1、为什么要开发 V4.0
EasyFlash 是我个人开发的第二款开源软件,自 2015 年初正式开源出来至今2019.02)已经经历了 4 年多时间。期间有很多其他行业的嵌入式开发者与我取得联系,得知他们已经将 EasyFlash 应用于自己的产品上,我心里也倍感欣慰,可见 EasyFlash 的成熟性已经得到了很多行业的认可。
### 1.1 功能简洁,但性能差强人意
大家普遍的感觉是 EasyFlash 功能简洁,可以很容易的应用于产品上。但随着技术的演进,大家对于 KV 需求的多样化,对于 MCU 资源(主要是 RAM、Flash 存储资源、Flash 寿命等性能指标越来越高,旧版本的 EasyFlash 在这些方面还是有提升的空间。比如:
### 1.2 旧版本的痛点
- 每个存储在 Flash 上的 ENV 都会在 RAM 中缓存一份,这样做虽然能够简化实现,但确实会占用很多 RAM 资源;
- ENV 的值类型只支持字符串,如果想要保存其他类型的值(比如:数组、结构体)就比较麻烦了,虽然我后来为此又专门开发了 [struct2json](https://github.com/armink/struct2json) 开源软件,但还是不够便捷;
- 每次保存 ENV 都需要重新擦写整个 Flash 扇区,那么位于扇区尾部未使用的区域始终无法得到利用,降低了 Flash 的使用效率,也就降低了 Flash 的使用寿命
### 1.3 从 0 开始的 NG 版本
也就是从 2017 年初开始,我便开始准备 EasyFlash 的性能优化工作,结合大家的需求,不断的整理、迭代设计文档,也与一些社区爱好者做过非常深入的交流。最终确定下来,如果单纯的在原有基础上进行完善,那么会有太多的功能实现受到限制,所以干脆重新开发全新一代 ENV 功能组件,这个版本被命名为 NG(Next Generation) 版本。
NG 版本差不多在 2017 年底就已经设计完毕,但一直没时间去开发。后来在亲人的支持下,终于利用 2019 年猪年春节的假期,在岳父母家完成了 V4.0 NG 版本的开发(在此感谢岳父母、爱人的支持)。
## 2、V4.0 的特色有哪些
- 更小的资源占用,内存占用 **几乎为 0**
- ENV 的值类型支持 **任意类型** 、任意长度,相当于直接 memcpy 变量至 flash
- ENV 操作效率比以前的模式高,充分利用剩余空闲区域,擦除次数及操作时间显著降低;
- **原生支持** 磨损平衡、掉电保护功能 V4.0 之前需要占用额外的 Flash 扇区);
- ENV 支持 **增量升级** ,固件升级后 ENV 也支持升级;
- 支持大数据存储模式,**长度无限制**,数据可在多个 Flash 扇区上顺序存储。像脚本程序、音频等占用 Flash 超过 1 个扇区的资源也都可以存入 ENV
- 支持 **数据加密** ,提升存储的安全性,物联网时代的必备功能;
- 支持 **数据压缩** ,减低 Flash 占用;
## 3、如何实现
### 3.1 算法
假定 ENV 分区里有 4 个扇区,以下将按照操作 ENV 的方式,逐一举例讲解不同操作下,对应的 Flash 状态及数据变化。
#### 3.1.1 ENV 操作过程1常规模式
##### 3.1.1.1 首次使用
![env_op1_step1](images/env_op1_step1.png)
首次使用时EasyFlash 会检查各个扇区的 header如果不符合规定的格式将执行全部格式化操作格式化后每个扇区的顶部将被存入 header ,负责记录当前扇区的状态、魔数等信息。格式化的初始化状态为空状态。
##### 3.1.1.2 添加 KV1、KV2、KV3
![env_op1_step2](images/env_op1_step2.png)
在执行添加操作前,会先检索合适地址来存放即将添加的新 KV这里检索策略主要是
- 确定当前选择的扇区剩余容量充足
- 优选选择正在使用状态的扇区,最后使用空状态扇区
- 检查新 KV 是否有同名的 KV 存在,存在还需要额外执行删除旧值的动作
通过上图可以看出, KV1、KV2 及 KV3 已经被放入 sector1 ,添加后,扇区状态也被修改为正在使用
##### 3.1.1.3 修改 KV2 KV3删除 KV1添加 KV4
![env_op1_step3](images/env_op1_step3.png)
修改 ENV 时,旧的 ENV 将被删除,扇区的状态也将被修改为脏状态,然后再执行新增 ENV 的操作。
- 执行修改 KV2 时,已经存在的 KV2 旧值被修改为已删除sector1 状态被修改为脏状态,此后将 KV2 新值放入 sector1发现 sector1 已经没有空间了sector1 的状态还会被修改为已满状态;
- 执行修改 KV3 时,已经存在的 KV3 旧值被修改为已删除sector1 状态已经为脏状态,无需再做修改。经过查找发现 KV3 的新值只能放到 sector2放到 sector2 后将其修改为正在使用状态;
- 执行删除 KV1 时,找到 KV1 的位置将其修改为已删除状态sector1 状态已经为脏状态,无需再做修改;
- 执行添加 KV4 时,经过查找在 sector2 找到合适的存储位置将其添加后sector2 状态已经为正在使用状态,无需再做修改。
##### 3.1.1.4 添加 KV5 KV6触发 GC
![env_op1_step4](images/env_op1_step4.png)
- 执行添加 KV5 操作,由于 KV5 体积较大sector2 放不下,所以只能放在一个新扇区 sector3 上,添加后,修改 sector3 状态为正在使用
- 执行添加 KV6 操作KV6 也只能放在 sector3 下,将其放入 sector 3 后,发现 sector3 空间已满,所以将其修改已满状态。执行完成后,发现整个 ENV 的 4 个扇区只有 1 个状态为空的扇区了,这个扇区如果再继续使用就没法再执行 GC 操作了,所以此时触发了 GC 请求;
- 执行 GC 请求EasyFlash 会找到所有被标记为已满并且为脏状态的扇区,并将其内部的 ENV 搬运至其他位置。就这样 sector1 上的 KV2 被搬运至了 sector2腾空 sector1 后,又对其执行了格式化操作,这样整个 ENV 分区里又多了一个空状态的扇区。
#### 3.1.2 ENV 操作过程2开启大数据存储模式
马上就来……
### 3.2 数据结构
结合上面的算法不难发现,其实所有的操作都围绕着 **扇区状态** 及 **ENV状态** ,这些状态将被存放在扇区及 ENV 头部,并且保证在不擦除扇区数据的前提下进行单向修改,在程序代码实现上称这些状态及其他一些数据信息为 **元数据**。
除了常规功能外,还有一项重要指标是 EasyFlash 非常看重的,那就是掉电保护能力,相当于在任何操作出现掉电异常,整个 EasyFlash 的容错能力是否过硬,是否可以进行掉电恢复。像 准备写入、准备删除这些中间状态就是为了掉电保护功能而设计。
出于后期扩展性的考虑这里也预留了一些保留属性,还有一些提前规划好的状态及属性后面将用过多扇区存储、加密、压缩功能的实现。
设计完成后,整个 ENV 的数据结构如下图,该图最终也可转换为对应的结构体。
![ng_mode_data_structure](images/ng_mode_data_structure.png)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 236 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 196 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 277 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

@ -1,278 +0,0 @@
# EasyFlash 移植说明
---
## 1、下载源码
[点击此链接](https://github.com/armink/EasyFlash/archive/master.zip)即可直接下载位于Github上的最新源码。
> 建议:点击项目主页 https://github.com/armink/EasyFlash 右上角 **Watch & Star**,这样项目有更新时,会及时以邮件形式通知你。
如果Github下载太慢也可以点击项目位于的国内仓库下载的链接([OSChina](https://git.oschina.net/Armink/EasyFlash/repository/archive?ref=master)|[Coding](https://coding.net/u/armink/p/EasyFlash/git/archive/master))。
## 2、导入项目
在导入到项目前,先打开[`\demo\`](https://github.com/armink/EasyFlash/tree/master/demo)文件夹检查下有没有与项目Flash规格一致的Demo。如果有则先直接跳过2、3、4章节按照第5章的要求设置参数并运行、验证Demo。验证通过再按照下面的导入项目要求将Demo中的移植文件直接导入到项目中即可。
- 1、先解压下载好的源码包文件的目录结构大致如下
|源文件 |描述 |
|:------------------------------ |:----- |
|\easyflash\src\ef_env.c |Env常规模式相关操作接口及实现源码|
|\easyflash\src\ef_iap.c |IAP 相关操作接口及实现源码|
|\easyflash\src\ef_log.c |Log 相关操作接口及实现源码|
|\easyflash\src\ef_utils.c |EasyFlash常用小工具例如CRC32|
|\easyflash\src\easyflash.c |目前只包含EasyFlash初始化方法|
|\easyflash\port\ef_port.c |不同平台下的EasyFlash移植接口|
|\demo\env\stm32f10x\non_os |stm32f10x裸机片内Flash的Env demo|
|\demo\env\stm32f10x\non_os_spi_flash |stm32f10x裸机SPI Flash的Env demo|
|\demo\env\stm32f10x\rtt |stm32f10x基于[RT-Thread](http://www.rt-thread.org/)的片内Flash Env demo|
|\demo\env\stm32f4xx |stm32f4xx基于[RT-Thread](http://www.rt-thread.org/)的片内Flash Env demo|
|\demo\iap\ymodem+rtt.c |使用[RT-Thread](http://www.rt-thread.org/)+[Ymodem](https://github.com/RT-Thread/rt-thread/tree/master/components/utilities/ymodem)的IAP Demo|
|\demo\log\easylogger.c |基于[EasyLogger](https://github.com/armink/EasyLogger)的Log Demo|
- 2、将`\easyflash\`(里面包含`inc`、`src`及`port`的那个)文件夹拷贝到项目中;
- 3、添加`\easyflash\src\easyflash.c`、`\easyflash\src\ef_utils.c`及`\easyflash\port\ef_port.c`这些文件到项目的编译路径中;
- 4、根据项目需求选择性添加`\easyflash\src\`中的其他源码文件到项目的编译路径中;
- 5、添加`\easyflash\inc\`文件夹到编译的头文件目录列表中;
## 3、Flash规格
在移植时务必先要了解项目的Flash规格这里需要了解是规格是 **擦除粒度(擦除最小单元)** 、**写入粒度**及 **内部存储结构** 各个厂家的Flash规格都有差异同一厂家不同系列的规格也有差异。以下是一些常见 Flash 的规格
| Flash 类型 | 写入粒度 | 擦除粒度 | 内部存储结构 |
| ---------------------- | -------- | ------------ | ------------------------- |
| STM32F1 片内 Flash | 4bytes | 1K/2K | 均匀分布 |
| STM32F2/F4 片内 Flash | 1byte | 16K/64K/128K | 最大的有128K最小的有16K |
| Nor FlashSPI-Flash | 1bit | 4K | 均匀分布 |
> **注意**
> - 1、务必保证熟悉Flash规格后再继续下章节
> - 2、V4.0 新模式暂时无法使用在 STM32L4 片内 Flash 上L4 只能使用 V3.0 版本或者 V4.0 的 EF_ENV_USING_LEGACY_MODE 模式
## 4、移植接口
### 4.1 移植初始化
EasyFlash移植初始化。可以传递默认环境变量初始化EasyFlash移植所需的资源等等。
```C
EfErrCode ef_port_init(ef_env const **default_env, size_t *default_env_size)
```
|参数 |描述|
|:----- |:----|
|default_env |默认的环境变量|
|default_env_size |默认环境变量的数量|
### 4.2 读取Flash
最小单位为4个字节。
```C
EfErrCode ef_port_read(uint32_t addr, uint32_t *buf, size_t size)
```
|参数 |描述|
|:----- |:----|
|addr |读取起始地址4字节对齐|
|buf |存放读取数据的缓冲区|
|size |读取数据的大小(字节)|
### 4.3 擦除Flash
```C
EfErrCode ef_port_erase(uint32_t addr, size_t size)
```
|参数 |描述|
|:----- |:----|
|addr |擦除起始地址|
|size |擦除数据的大小(字节)|
### 4.4 写入Flash
最小单位为4个字节。
```C
EfErrCode ef_port_write(uint32_t addr, const uint32_t *buf, size_t size)
```
|参数 |描述|
|:----- |:----|
|addr |写入的起始地址4字节对齐|
|buf |源数据的缓冲区|
|size |写入数据的大小(字节)|
### 4.5 对环境变量缓冲区加锁
为了保证RAM缓冲区在并发执行的安全性所以需要对其进行加锁如果项目的使用场景不存在并发情况则可以忽略。有操作系统时可以使用获取信号量来加锁裸机时可以通过关闭全局中断来加锁。
```C
void ef_port_env_lock(void)
```
### 4.6 对环境变量缓冲区解锁
有操作系统是可以使用释放信号量来解锁,裸机时可以通过开启全局中断来解锁。
```C
void ef_port_env_unlock(void)
```
### 4.7 打印调试日志信息
在定义`PRINT_DEBUG`宏后,打印调试日志信息。
```C
void ef_log_debug(const char *file, const long line, const char *format, ...)
```
|参数 |描述|
|:----- |:----|
|file |调用该方法的文件|
|line |调用该方法的行号|
|format |打印格式|
|... |不定参|
### 4.8 打印普通日志信息
```C
void ef_log_info(const char *format, ...)
```
|参数 |描述|
|:----- |:----|
|format |打印格式|
|... |不定参|
### 4.9 无格式打印信息
该方法输出无固定格式的打印信息,为`ef_print_env`方法所用(如果不使用`ef_print_env`则可以忽略)。而`ef_log_debug`及`ef_log_info`可以输出带指定前缀及格式的打印日志信息。
```C
void ef_print(const char *format, ...)
```
|参数 |描述|
|:----- |:----|
|format |打印格式|
|... |不定参|
### 4.10 默认环境变量集合
在 ef_port.c 文件顶部定义有 `static const ef_env default_env_set[]` ,我们可以将产品上需要的默认环境变量集中定义在这里。当 flash 第一次初始化时会将默认的环境变量写入。
默认环境变量内部采用 void * 类型,所以支持任意类型,可参考如下示例:
```C
static uint32_t boot_count = 0;
static time_t boot_time[10] = {0, 1, 2, 3};
static const ef_env default_env_set[] = {
// { key , value, value_len }
{"username", "armink", 0}, //类型为字符串的环境变量可以设定值的长度为 0 ,此时会在初始化时会自动检测其长度
{"password", "123456", 0},
{"boot_count", &boot_count, sizeof(boot_count)}, //整形
{"boot_time", &boot_time, sizeof(boot_time)}, //数组类型,其他类型使用方式类似
};
```
## 5、设置参数
配置时需要修改项目中的`ef_cfg.h`文件,开启、关闭、修改对应的宏即可。
### 5.1 环境变量功能
- 默认状态:开启
- 操作方法:开启、关闭`EF_USING_ENV`宏即可
#### 5.1.1 自动更新(增量更新)
可以对 ENV 设置版本号(参照 5.1.2)。当 ENV 初始化时,如果检测到产品存储的版本号与设定版本号不一致,会自动追加默认环境变量集合中新增的环境变量。
该功能非常适用于经常升级的产品中,当产品功能变更时,有可能会新增环境变量,此时只需要增大当前设定的 ENV 版本号,下次固件升级后,新增的环境变量将会自动追加上去。
- 默认状态:关闭
- 操作方法:开启、关闭`EF_ENV_AUTO_UPDATE`宏即可
#### 5.1.2 环境变量版本号
该配置依赖于 5.1.1 配置。设置的环境变量版本号为整形数值,可以从 0 开始。如果在默认环境变量表中增加了环境变量,此时需要对该配置进行修改(通常加 1 )。
- 操作方法:修改`EF_ENV_VER_NUM`宏对应值即可
### 5.2 在线升级功能
- 默认状态:开启
- 操作方法:开启、关闭`EF_USING_IAP`宏即可
### 5.3 日志功能
- 默认状态:开启
- 操作方法:开启、关闭`EF_USING_LOG`宏即可
### 5.4 Flash 擦除粒度(最小擦除单位)
- 操作方法:修改`EF_ERASE_MIN_SIZE`宏对应值即可单位byte
### 5.5 Flash 写入粒度
- 操作方法:修改`EF_WRITE_GRAN`宏对应值即可单位bit仅支持1/8/32
### 5.5 备份区
备份区共计包含3个区域依次为环境变量区、日志区及在线升级区。分区方式如下图所示
![backup_area_partiton](images/BackupAreaPartition.jpg)
在配置时需要注意以下几点:
- 1、所有的区域必须按照`EF_ERASE_MIN_SIZE`对齐;
- 2、环境变量分区大少至少为两倍以上 `EF_ERASE_MIN_SIZE`
- 3、从 V4.0 开始 ENV 的模式命名为 NG 模式V4.0 之前的称之为 LEGACY 遗留模式;
- 遗留模式已经被废弃,不再建议继续使用;
- 如果需要继续使用遗留模式,请 EasyFlash 的 V3.X 版本。
#### 5.5.1 备份区起始地址
- 操作方法:修改`EF_START_ADDR`宏对应值即可
#### 5.5.2 环境变量区总容量
- 操作方法:修改`ENV_AREA_SIZE`宏对应值即可
> 注意:不使用环境变量功能时,可以不定义此宏。
#### 5.5.3 日志区总容量
- 操作方法:修改`LOG_AREA_SIZE`宏对应值即可
> 注意:不使用日志功能时,可以不定义此宏。
### 5.6 调试日志
开启后,将会库运行时自动输出调试日志
- 默认状态:开启
- 操作方法:开启、关闭`PRINT_DEBUG`宏即可
## 6、测试验证
如果`\demo\`文件夹下有与项目Flash规格一致的Demo则直接编译运行观察测试结果即可。无需关注下面的步骤。
每次使用前,务必先执行`easyflash_init()`方法对EasyFlash库及所使用的Flash进行初始化保证初始化没问题后再使用各功能的API方法。如果出现错误或断言需根据提示信息检查移植配置及接口。
### 6.1 环境变量
查看[`\demo\env\`](https://github.com/armink/EasyFlash/tree/master/demo/env)子文件夹中例子的`README.md`说明文档。测试时可以将`\demo\env\stm32f10x\non_os\app\src\app.c`中的`static void test_env(void)`方法体复制到项目中,然后运行测试。
### 6.2 在线升级
查看[`\demo\iap\README.md`](https://github.com/armink/EasyFlash/tree/master/demo/iap)说明文档。
### 6.3 日志
查看[`\demo\log\README.md`](https://github.com/armink/EasyFlash/tree/master/demo/log)说明文档。
> 注意:`easylogger.c`是使用[EasyLogger](https://github.com/armink/EasyLogger)与EasyFlash的无缝接口的例子EasyLogger提供针对日志的很多常用功能封装详细功能可以查看其介绍。使用这个例子时务必记得将EasyLogger一并导入到项目中。

@ -1,4 +0,0 @@
|文件名 |描述|
|:----- |:----|
|api.md |API 说明|
|port.md |移植说明|

@ -1,66 +0,0 @@
# V4.0 迁移指南
## 1、V3.0 与 V4.0 差异
### 1.1 API 接口方面
#### 1.1.1 完全兼容旧版
V4.0 在设计时,已经做到接口完全兼容旧版本,所以如果你的应用使用的是旧版本,那么无需修改任何源代码即可做到无缝迁移。
#### 1.1.2 新增接口
V4.0 底层对于 ENV 的存储使用的 blob 格式,所以增加如下 blob 操作接口,替代 V3.0 的基于字符串的接口
- `size_t ef_get_env_blob(const char *key, void *value_buf, size_t buf_len, size_t *value_len)`
- `EfErrCode ef_set_env_blob(const char *key, const void *value_buf, size_t buf_len)`
#### 1.1.3 废弃接口
以下接口在 V4.0 中仍然可用,但已经由于种种原因被废弃,可能将会在 V5.0 版本中被正式删除
- `char *ef_get_env(const char *key)`
- 注意:由于 V4.0 版本开始,在该函数内部具有环境变量的缓冲区,不允许连续多次同时使用该函数,例如如下代码:
```C
// 错误的使用方法
ssid = ef_get_env("ssid");
password = ef_get_env("password"); // 由于 buf 共用password 与 ssid 会返回相同的 buf 地址
// 建议改为下面的方式
ssid = strdup(ef_get_env("ssid")); // 克隆获取回来的环境变量
password = strdup(ef_get_env("password"));
// 使用完成后,释放资源
free(ssid); // 与 strdup 成对
free(password);
```
- `EfErrCode ef_save_env(void)`
- `EfErrCode ef_set_and_save_env(const char *key, const char *value)`
- `EfErrCode ef_del_and_save_env(const char *key)`
- `size_t ef_get_env_write_bytes(void)`
## 2、主要修改项
### 2.1 配置方面
- 删除 EF_ENV_USING_WL_MODEV4.0 原生支持磨损平衡,无需额外开启
- 删除 EF_ENV_USING_PFS_MODEV4.0 自带掉电保护功能,无需额外开启
- 删除 ENV_USER_SETTING_SIZEV4.0 无需 RAM 缓存
- 增加 EF_WRITE_GRAN :详见移植文档
### 2.2 接口改进
- 建议使用 ef_get_env_blob 接口替代 ef_get_env使用方法详见 API 文档
- V4.0 无需额外执行保存动作,所以使用这些接口的代码在 V4..0 无意义,可以移除
- ef_save_env
- ef_set_and_save_env
- ef_del_and_save_env
Loading…
Cancel
Save