diff --git a/docs/en/api.md b/docs/en/api.md deleted file mode 100644 index f65681d..0000000 --- a/docs/en/api.md +++ /dev/null @@ -1 +0,0 @@ -# Coming soon... \ No newline at end of file diff --git a/docs/en/images/EnvDemo.gif b/docs/en/images/EnvDemo.gif deleted file mode 100644 index ee93f11..0000000 Binary files a/docs/en/images/EnvDemo.gif and /dev/null differ diff --git a/docs/en/images/IapDemo.gif b/docs/en/images/IapDemo.gif deleted file mode 100644 index a35c686..0000000 Binary files a/docs/en/images/IapDemo.gif and /dev/null differ diff --git a/docs/en/images/LogDemo.gif b/docs/en/images/LogDemo.gif deleted file mode 100644 index b99b662..0000000 Binary files a/docs/en/images/LogDemo.gif and /dev/null differ diff --git a/docs/en/readme.md b/docs/en/readme.md deleted file mode 100644 index 916db5a..0000000 --- a/docs/en/readme.md +++ /dev/null @@ -1,3 +0,0 @@ -|File name |Description| -|:----- |:----| -|api.md |API description| \ No newline at end of file diff --git a/docs/readme.md b/docs/readme.md deleted file mode 100644 index da9229a..0000000 --- a/docs/readme.md +++ /dev/null @@ -1,4 +0,0 @@ -|File or folder name |Description| -|:----- |:----| -|en |English documents| -|zh |中文文档(简体)| \ No newline at end of file diff --git a/docs/zh/api.md b/docs/zh/api.md deleted file mode 100644 index f97dbaa..0000000 --- a/docs/zh/api.md +++ /dev/null @@ -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个字节对齐,擦除的最小单位则需根据用户的平台来确定 diff --git a/docs/zh/design.md b/docs/zh/design.md deleted file mode 100644 index 54ff0ca..0000000 --- a/docs/zh/design.md +++ /dev/null @@ -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) \ No newline at end of file diff --git a/docs/zh/images/BackupAreaPartition.jpg b/docs/zh/images/BackupAreaPartition.jpg deleted file mode 100644 index 231343d..0000000 Binary files a/docs/zh/images/BackupAreaPartition.jpg and /dev/null differ diff --git a/docs/zh/images/EnvDemo.gif b/docs/zh/images/EnvDemo.gif deleted file mode 100644 index 92cdcc8..0000000 Binary files a/docs/zh/images/EnvDemo.gif and /dev/null differ diff --git a/docs/zh/images/IapDemo.gif b/docs/zh/images/IapDemo.gif deleted file mode 100644 index a35c686..0000000 Binary files a/docs/zh/images/IapDemo.gif and /dev/null differ diff --git a/docs/zh/images/LogDemo.gif b/docs/zh/images/LogDemo.gif deleted file mode 100644 index b99b662..0000000 Binary files a/docs/zh/images/LogDemo.gif and /dev/null differ diff --git a/docs/zh/images/env_op1_step1.png b/docs/zh/images/env_op1_step1.png deleted file mode 100644 index 2b85ce8..0000000 Binary files a/docs/zh/images/env_op1_step1.png and /dev/null differ diff --git a/docs/zh/images/env_op1_step2.png b/docs/zh/images/env_op1_step2.png deleted file mode 100644 index cc9e9fb..0000000 Binary files a/docs/zh/images/env_op1_step2.png and /dev/null differ diff --git a/docs/zh/images/env_op1_step3.png b/docs/zh/images/env_op1_step3.png deleted file mode 100644 index b40799c..0000000 Binary files a/docs/zh/images/env_op1_step3.png and /dev/null differ diff --git a/docs/zh/images/env_op1_step4.png b/docs/zh/images/env_op1_step4.png deleted file mode 100644 index f5722da..0000000 Binary files a/docs/zh/images/env_op1_step4.png and /dev/null differ diff --git a/docs/zh/images/ng_mode_data_structure.png b/docs/zh/images/ng_mode_data_structure.png deleted file mode 100644 index 425e0d8..0000000 Binary files a/docs/zh/images/ng_mode_data_structure.png and /dev/null differ diff --git a/docs/zh/images/wechat_support.png b/docs/zh/images/wechat_support.png deleted file mode 100644 index 03dfe0a..0000000 Binary files a/docs/zh/images/wechat_support.png and /dev/null differ diff --git a/docs/zh/port.md b/docs/zh/port.md deleted file mode 100644 index 6bd22be..0000000 --- a/docs/zh/port.md +++ /dev/null @@ -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 Flash(SPI-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一并导入到项目中。 \ No newline at end of file diff --git a/docs/zh/readme.md b/docs/zh/readme.md deleted file mode 100644 index 167b423..0000000 --- a/docs/zh/readme.md +++ /dev/null @@ -1,4 +0,0 @@ -|文件名 |描述| -|:----- |:----| -|api.md |API 说明| -|port.md |移植说明| \ No newline at end of file diff --git a/docs/zh/v4_migrate.md b/docs/zh/v4_migrate.md deleted file mode 100644 index 7a40966..0000000 --- a/docs/zh/v4_migrate.md +++ /dev/null @@ -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_MODE:V4.0 原生支持磨损平衡,无需额外开启 -- 删除 EF_ENV_USING_PFS_MODE:V4.0 自带掉电保护功能,无需额外开启 -- 删除 ENV_USER_SETTING_SIZE:V4.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 -