GithubHelp home page GithubHelp logo

armink / easyflash Goto Github PK

View Code? Open in Web Editor NEW
1.9K 216.0 751.0 6.74 MB

Lightweight IoT device information storage solution: KV/IAP/LOG. | 轻量级物联网设备信息存储方案:参数存储、在线升级及日志存储 ,全新一代版本请移步至 https://github.com/armink/FlashDB

License: MIT License

C 100.00%
flash embedded key-value iap log iot kv

easyflash's Introduction

EasyFlash

GitHub release GitHub commits MIT licensed

1、介绍(English

提示 :从 EasyFlash V4.1 后,基于 EasyFlash 全新设计开发的 FlashDB 开源项目正式上线,新集成了时序数据库、多分区管理,多数据库实例等功能,也从一定程度上提升了整体性能,欢迎关注:https://github.com/armink/FlashDB 。同时,现有的 EasyFlash 也会继续维护。

EasyFlash是一款开源的轻量级嵌入式Flash存储器库,方便开发者更加轻松的实现基于Flash存储器的常见应用开发。非常适合智能家居、可穿戴、工控、医疗、物联网等需要断电存储功能的产品,资源占用极低,支持各种 MCU 片上存储器。该库主要包括 三大实用功能

  • ENV 快速保存产品参数,支持 写平衡(磨损平衡)掉电保护 功能

EasyFlash不仅能够实现对产品的 设定参数运行日志 等信息的掉电保存功能,还封装了简洁的 增加、删除、修改及查询 方法, 降低了开发者对产品参数的处理难度,也保证了产品在后期升级时拥有更好的扩展性。让Flash变为NoSQL(非关系型数据库)模型的小型键值(Key-Value)存储数据库。

  • IAP 在线升级再也不是难事儿

该库封装了IAP(In-Application Programming)功能常用的接口,支持CRC32校验,同时支持Bootloader及Application的升级。

  • Log 无需文件系统,日志可直接存储在Flash上

非常适合应用在小型的不带文件系统的产品中,方便开发人员快速定位、查找系统发生崩溃或死机的原因。同时配合EasyLogger(我开源的超轻量级、高性能C日志库,它提供与EasyFlash的无缝接口)一起使用,轻松实现C日志的Flash存储功能。

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) 模式,这是一个完全重构的新版本,具有以下新特性:

  • 更小的资源占用,内存占用 几乎为 0 ;(V4.0 以前版本会使用额外的 RAM 空间进行缓存)
  • ENV 的值类型支持 任意类型 、任意长度,相当于直接 memcpy 变量至 flash ;(V4.0 之前只支持存储字符串)
  • ENV 操作效率比以前的模式高,充分利用剩余空闲区域,擦除次数及操作时间显著降低;
  • 原生支持 磨损平衡、掉电保护功能 (V4.0 之前需要占用额外的 Flash 扇区);
  • ENV 支持 增量升级 ,固件升级后 ENV 也支持升级;
  • 支持大数据存储模式,长度无限制,数据可在多个 Flash 扇区上顺序存储。像脚本程序、音频等占用 Flash 超过 1 个扇区的资源也都可以存入 ENV(即将在 V4.2 支持);
  • 支持 数据加密 ,提升存储的安全性,物联网时代的必备功能(即将在 V4.3 支持);
  • 支持 数据压缩 ,减低 Flash 占用(即将在 V4.4 支持);

V4.0 设计及内部原理,V4.0 迁移指南等更多内容请继续阅读下面的 文档章节

注意 :个别 Flash 存在无法逆序写入的问题,例如 STM32L4 片内 Flash,所以无法使用 NG 模式,这种情况下建议使用 V3.0 的 legacy 模式

1.1.2、延续 V3.0 的 legacy 模式

对应源码文件为: ef_env_legacy.cef_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、资源占用

最低要求: ROM: 6K bytes     RAM: 0.1K bytes

1.3、支持平台

目前已移植硬件平台有 stm32f10xstm32f4xx 系列的片内Flash,片外的 SPI Flash(基于 SFUD),这些也是笔者产品使用的平台。其余平台的移植难度不大,在项目的设计之初就有考虑针对所有平台的适配性问题(64位除外),所以对所有移植接口都有做预留。移植只需修改 \easyflash\port\ef_port.c 一个文件,实现里面的擦、写、读及打印功能即可。

欢迎大家 fork and pull request(Github|OSChina|Coding) 。如果觉得这个开源项目很赞,可以点击项目主页 右上角的 Star,同时把它推荐给更多有需要的朋友。

2、流程

2.1、ENV:环境变量(KV数据库)

下图为通过控制台(终端)来调用环境变量的常用接口,演示了以下过程,这些接口都支持被应用层直接调用。

  • 1、创建“温度”的环境变量,名为 temp,并且赋值为 123
  • 2、保存“温度”到Flash中并重启(V4.0 版本的每个操作完自动保存,无需额外保存);
  • 3、检查“温度”是否被成功保存;
  • 4、修改“温度”值为 456 并保存、重启;
  • 5、检查“温度”是否被成功修改;
  • 6、删除“温度”的环境变量。

easy_flash_env

2.2、IAP:在线升级

下图演示了通过控制台来进行IAP升级软件的过程,使用的是库中自带的IAP功能接口,演示采用的是串口+Ymodem协议的方式。你还也可以实现通过CAN、485、以太网等总线,来实现远程网络更新。

easy_flash_iap

2.3、Log:日志存储

下图过程为通过控制台输出日志,并将输出的日志存储到Flash中。重启再读取上次保存的日志,最后清空Flash日志。

easy_flash_log

3、文档

务必保证在 阅读文档 后再移植使用。

4、支持

support

如果 EasyFlash 解决了你的问题,不妨扫描上面二维码请我 喝杯咖啡~

5、许可

采用 MIT 开源协议,细节请阅读项目中的 LICENSE 文件内容。


1 Introduction

EasyFlash is an open source lightweight embedded flash memory library. It provides convenient application interface for MCU (Micro Control Unit). The developers can achieve more efficient and common application development based on Flash memory. The library currently provides three useful features

  • Env(environment variables) Fast Saves product parameters. Support write balance mode(wear leveling) and power fail safeguard.

EasyFlash can store setting parameters or running logs and other information which you want to keep after power down. It contains add, delete, modify and query methods. It helps developer to process the product parameters, and makes sure the product has better scalability after upgrade. Turns the Flash into a small NoSQL (non-relational databases) model and Key-Value stores database.

  • IAP : online upgrade is no longer a difficult thing.

The library encapsulates the IAP (In-Application Programming) feature common interface. Support CRC32 checksum. While supporting the bootloader and application upgrade.

  • Log : The logs can store to product's flash which has no file-system.

It's very suitable for small without a file system products. The developer can easy to locate and query problem when system crashes or freezes. You can use EasyLogger( A super-lightweight, high-performance C log library which open source by me. It provides a seamless interface with EasyFlash) at the same time. So, it's so easy to store the logs to flash.

1.1 Resource consumption

Minimum : ROM: 6K bytes     RAM: 0.2K bytes

1.2 Supported platforms

Hardware platform has been ported SPI Flash, stm32f10x and stm32f4xx series of on-chip Flash. These are my product platforms. Remaining platform porting difficulty is little. To port it just modify \easyflash\port\ef_port.c file. Implement erase, write, read, print feature.

Welcome everyone to fork and pull request(Github|OSChina|Coding). If you think this open source project is awesome. You can press the Star on the top right corner of project home page, and recommend it to more friends.

2 Flow

2.1 Env(KV database)

The figure below shows an ENV's common interface be called by the console (terminal). These interfaces are supported by the application layer called.

  • 1.Create temperature environment variable. It's name is temp and value is 123;
  • 2.Save temperature to flash and reboot;
  • 3.Check the temperature has saved successfully;
  • 4.Change the temperature value to 456 and save, reboot;
  • 5.Check the temperature has changed successfully;
  • 6.Delete temperature environment variable.

easy_flash_env

2.2 IAP

The figure below shows the process of upgrading software through the console by IAP. It use this library comes with IAP function interface. It uses a serial port + Ymodem protocol mode. You can also be achieved through CAN, 485, Ethernet bus to online upgrade.

easy_flash_iap

2.3 Log

The following figure is the output of the log process through the console. The logs are saved to flash at real time. Then the board is rebooted and the logs back are read back from flash. At last logs will be erased.

easy_flash_log

3 Documents

All documents are in the \docs\en\ folder. Please read the documents before porting it and using it.

4 License

Using MIT open source license, please read the project LICENSE file.

easyflash's People

Contributors

armink avatar crespum avatar i-jaffer avatar iysheng avatar kaidegit avatar liquanqing avatar mculover666 avatar murphyzhao avatar outely avatar redoccheng avatar shiyj avatar smartmx avatar wu1045718093 avatar wudicgi avatar xixijay1988 avatar xtaens avatar xxxxzzzz000 avatar ylzbotian avatar yuht avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

easyflash's Issues

关于特征字env的字长选择

作者(armink)你好:
看了下env的好多标志,比如存储状态,脏状态,都是32位的,
为什么要放这么多字节呢?记录的状态只有3,4个这样的
要知道eeprom的读写字节数越多,速度越慢呀。
还请教这里是否有什么原因呢。
谢谢~

GC出现问题,未掉电,中等强度持续跑12小时

env区:24K;log区:24K;ARM平台,FreeRTOS,移植,使用master最新版本的EasyFlash。

在测试时wifi_ssidwifi_pwd__ver_num__均保持初始值。只有l_unup_i保持定期写入新值。

距离错误最近一次GC搬移(以下日志均发生在写入l_unup_i新值时):

[Flash](ef_env.c:1000) Trigger a GC check after created ENV.
[Flash](ef_env.c:906) The remain empty sector is 1, GC threshold is 1.
[Flash](ef_env.c:821) Moved the ENV (wifi_ssid) from 0x080F0014 to 0x080F5014.
[Flash](ef_env.c:821) Moved the ENV (wifi_pwd) from 0x080F0039 to 0x080F5039.
[Flash](ef_env.c:821) Moved the ENV (__ver_num__) from 0x080F0061 to 0x080F5061.
[Flash](ef_env.c:886) Collect a sector @0x080F0000
[Flash](ef_env.c:886) Collect a sector @0x080F1000
[Flash](ef_env.c:886) Collect a sector @0x080F2000
[Flash](ef_env.c:886) Collect a sector @0x080F3000
[Flash](ef_env.c:821) Moved the ENV (l_unup_i) from 0x080F4FC0 to 0x080F5088.
[Flash](ef_env.c:886) Collect a sector @0x080F4000

出错时:

  1. 看上去是写入l_unup_i时长度出错,但是l_unup_i值的长度是sizeof计算出来的常量。
[Flash](ef_env.c:336) Error: The ENV @0x080F004E length has an error.
  1. GC搬移出错,不知为何会校验失败
[Flash](ef_env.c:726) Trigger a GC check after alloc ENV failed.
[Flash](ef_env.c:837) Warning: Alloc an ENV (size 34) failed when new ENV. Now will GC then retry.
[Flash](ef_env.c:906) The remain empty sector is 1, GC threshold is 1.
[Flash](ef_env.c:886) Collect a sector @0x080F0000
[Flash](ef_env.c:821) Moved the ENV (wifi_ssid) from 0x080F5014 to 0x080F0014.
[Flash]Error: The ENV (@0x080F0039) CRC32 check failed!
[Flash](ef_env.c:336) Error: The ENV @0x080F0088 length has an error.
[Flash](ef_env.c:821) Moved the ENV (wifi_pwd) from 0x080F5039 to 0x080F4014.
[Flash]Error: The ENV (@0x080F0039) CRC32 check failed!
[Flash](ef_env.c:336) Error: The ENV @0x080F406C length has an error.
[Flash](ef_env.c:336) Error: The ENV @0x080F4084 length has an error.
[Flash](ef_env.c:881) Error: Moved the ENV (__ver_num__) for GC failed.
[Flash](ef_env.c:886) Collect a sector @0x080F5000
[Flash]Error: The ENV (@0x080F0039) CRC32 check failed!
[Flash](ef_env.c:726) Trigger a GC check after alloc ENV failed.
[Flash]Error: The ENV (@0x080F0039) CRC32 check failed!
[Flash](ef_env.c:336) Error: The ENV @0x080F504E length has an error.

之后每次写入env都会报:

[Flash]Error: The ENV (@0x080F0039) CRC32 check failed!

程序从未重新设置wifi_pwd过,运行中也从未掉电,供电也是独立供电,sem信号锁已设置,系统内部还有专门的flash锁。这种问题会是什么问题?

均衡磨损问题

上面提到了均衡磨损的问题,是否可以改成和掉电保护一样,在不同的page上面进行切换。
现在掉电保护是在2个page上进行切换。如果开启均衡磨损,那就在多个page上进行切换,page数量可配置。

关于EasyFlash的存储性能指标

你好,关于EasyFlash的系统性能,比如有效存储空间:总存储空间大小,最多支持变量个数等等,是否有示例数据评估?
我建议这方面进行一些说明,有助于大家使用的时候知道正在使用的东西,极限在哪里,也能有助于安全可靠地使用它。
不管怎样,谢谢作者的共享和公开。
看来作者也在魔都,有机会可以一起交流啊。

移植说明 port.md

5.1.1 磨损平衡/常规 模式

磨损平衡:由于flash在写操作之前需要擦除且使用寿命有限,所以需要设计合理的磨损平衡(写平衡)机制,来保证数据被安全的保存在未到擦写寿命的Flash区中。

默认状态:常规模式
常规模式:关闭 FLASH_ENV_USING_WL_MODE
磨损平衡模式:打开EF_ENV_USING_WL_MODE

上面的“常规模式”应该是关闭EF_ENV_USING_WL_MODE 而不是 FLASH_ENV_USING_WL_MODE

请问这样的应用,EasyFlash适合吗

请问easyflash,适合用于这样的场合吗:

从串口接入256 Byte/包 的数据,然后存到SPI flash中。

数据是图片数据,会有很多包数据,连续传输。

后续会从SPI flash 取出数据,刷到TFT LCD上。

请问EasyFlash 用哪个API函数,适合这样的应用

请问ef_log 写满了会如何

我的log区,配置了80K
#define LOG_AREA_SIZE (20 * EF_ERASE_MIN_SIZE) /* 80K */

然后,如下的代码,测试 写满 log
while(1)
{

			ret  = ef_log_write((const uint32_t *)logTest, 76) ; //每次写76字
		
			EF_INFO("ef_log_get_used_size[%ld]\n\r",ef_log_get_used_size());
	}

运行意思写log后,ef_log_get_used_size的尺寸从0~80K,然后一直在 70+K ~80+K 之间循环。以下是截取一段打印输出:
Flash]ef_log_get_used_size[79420]
[Flash]ef_log_get_used_size[79496]
[Flash]ef_log_get_used_size[79572]
[Flash]ef_log_get_used_size[79648]
[Flash]ef_log_get_used_size[79724]
[Flash]ef_log_get_used_size[79800]
[Flash]ef_log_get_used_size[79876]
[Flash]ef_log_get_used_size[79952]
[Flash]ef_log_get_used_size[80028]
[Flash]ef_log_get_used_size[80104]
[Flash]ef_log_get_used_size[80180]
[Flash]ef_log_get_used_size[80256]
[Flash]ef_log_get_used_size[80332]
[Flash]ef_log_get_used_size[80408]
[Flash]ef_log_get_used_size[80484]
[Flash]ef_log_get_used_size[80560]
[Flash]ef_log_get_used_size[80636]
[Flash]ef_log_get_used_size[80712]
[Flash]ef_log_get_used_size[80788]
[Flash]ef_log_get_used_size[80864]
[Flash]ef_log_get_used_size[80940]
[Flash]ef_log_get_used_size[81016]
[Flash]ef_log_get_used_size[81092]
[Flash]ef_log_get_used_size[81168]
[Flash]ef_log_get_used_size[81244]
[Flash]ef_log_get_used_size[81320]
[Flash]ef_log_get_used_size[81396]
[Flash]ef_log_get_used_size[81472]
[Flash]ef_log_get_used_size[81548]
[Flash]ef_log_get_used_size[81624]
[Flash]ef_log_get_used_size[81700]
[Flash]ef_log_get_used_size[81776]
[Flash]ef_log_get_used_size[77760]
[Flash]ef_log_get_used_size[77836]
[Flash]ef_log_get_used_size[77912]
[Flash]ef_log_get_used_size[77988]
[Flash]ef_log_get_used_size[78064]

请问ef_log_get_used_size() 的尺寸一直在70~80K之间循环的情况,正常吗?

read_env 问题

static EfErrCode read_env(env_meta_data_t env) { ... crc_data_len = env->len - ENV_NAME_LEN_OFFSET; ... }

读取数据错误时,crc_data_len 出现数据长度超长

Updating flash when new variables are created

I've idefntified an scenario that is quite common in my opinion but it's not supported by the library (and I'm not sure if it should).

Imagine you are using this set of variables:

/* ef_ports.c default environment variables set for user */
static const ef_env default_env_set[] = {
    {"var1", "foo"},
};

But in the next release of your code you want to add a new one (or even remove one of the existing ones). For instance you might need this:

/* ef_ports.c default environment variables set for user */
static const ef_env default_env_set[] = {
    {"var1", "foo"},
    {"var2", "6"}
};

Since you already have some variables saved in memory, your code will not be able to find "var3" unless you call manually call ef_env_set_default() (the library will not do it). To call it only when a new variable is added I've done this:

/* ef_ports.c default environment variables set for user */
static const ef_env default_env_set[] = {
    {"__ENV_VER", "1"}, // Increase this number whenever a new variable is added 
    {"var1", "foo"},
    {"var2", "6"}
};
/* main.c */
easyflash_init();

char *var;
var = ef_get_env("__ENV_VER");
if (var == NULL || memcmp(var, EF_ENV_ID, sizeof(EF_ENV_ID))) {
    ef_env_set_default();
}

My question is, should this be implemented by the library somehow or should it be part of the application layer? Is there any other way around?

询问保存耗时过长解决问题

一直想找SPI FLASH的磨损均衡方案,直到发现此项目,感觉很符合自己的需求,非常感谢开源。在使用中遇到问题请教一下:
1,在测试保存数据时,当扇区使用差不多的时候,在此时保存数据,程序会释放其它扇区数据,导致保存数据耗时过长,而对无操作系统来说,可能会导致看门狗复位,建议后续增加喂狗接口;
2,另外有10个扇区,比如从1-10,当用到5时(1-5都dirty),当此时把1-4都清理,那当5用完时,会从1开始用还是从6开始到10,而从1再开始?
3、若是从6开始,能否开放清理扇区的接口,在程序空闲时调用,这样在1的时候,保存数据,会耗时降低一些。期待你的回答,再次感谢开源,谢谢。

另外请问有 关于 plugins/types/ 的范例吗。

另外请问有 关于 plugins/types/ 的范例吗。
我使用起来,提示

0> [Flash]Memory full!
0> [Flash]Memory full!

代码:
static void test_env(void) {
uint32_t i_boot_times = NULL;
char *c_old_boot_times, c_new_boot_times[11] = {0};
char test_flash[20] = {"1234asdasdasd"} ;
char test_flash1[20] = {"1234asdasdasd"} ;

	ef_get_char_array("test_flash",test_flash1);
	SEGGER_RTT_printf(0,"test_flash = %d \n\r", test_flash1[0]);

	for(u16 i = 0;i<20;i++)
	{
		   test_flash[i] = i;
	}
	EfErrCode ERR = ef_set_char_array("test_flash", test_flash, 20);
	ef_save_env();
	SEGGER_RTT_printf(0,"ERR = %d \n\r", ERR);

	ef_print_env();

}

log显示:
0> SFUD Flash device supports 64KB block erase. Command is 0xD8.
0> [SFUD]Find a GigaDevice flash chip. Size is 2097152 bytes.
0> SFUD Flash device reset success.
0> [SFUD]SST25VF016B flash device is initialize success.
0> Flash ENV start address is 0x00000000, size is 4096 bytes.
0> Flash Calculate ENV CRC32 number is 0xFCEEFD14.
0> Flash Verify ENV CRC32 result is OK.
0> Flash EasyFlash V3.0.0 is initialize success.
0> Flash You can get the latest version on https://github.com/armink/EasyFlash .
0> [Flash]Couldn't find this ENV(test_flash)!
0> test_flash = 49
0> [Flash]Memory full!
0> [Flash]Memory full!
0> ERR = 5
0> iap_need_copy_app=0
0> iap_copy_app_size=0
0> stop_in_bootloader=0
0> device_id=1
0> boot_times=24
0>
0> ENV size: 100/2048 bytes.

The WL mode in EFV3.3.0 is not working?

Hey,dude:
I still using the version of 3.3.0 that you have already released.
I am trying to use WL mode,and I have defined EF_ENV_USING_WL_MODE in ef_cfg.h.But it seems does't work.
I checked the memory address,it still write the same address every time when I call ef_save_env().It just erase the section then write the new kv in it.
Am I missing something?

存储空字符串问题

使用EfErrCode ef_set_env(const char *key, const char *value)存储空value时是删除对应的Map。
但又可以通过ef_env_set_default()将默认环境变量列表中的值为空的Map存入flash。如
static const ef_env default_env_set[] = { {"password",""} };
因为在某些应用场景下可能会存储有意义的空串值,如空密码。
是否能够通过加入一个删除Map的API 取代ef_set_env()中value为空时删除Map的功能。

Types 插件 范例中有一处:

Student *student;
ef_get_struct("张三学生", student, stu_get_cb);

好像应该是:
student = ef_get_struct("张三学生", stu_get_cb);

有2个关于存储的问题

目前环境变量都是键值对的方式存储,存储都是字符串形式

1、如果要存储一个结构体,怎么办?只能将结构体每个成员分别存储?这样貌似太麻烦..
2、如果要存储的是一个数组,怎么办?因为这个数组有可能中间某个元素为0x00,0x00是字符串结束符号,直接存储肯定不行,存储时候会将0x00后面的元素都丢掉了。我的想法是只能将每个元素都分别拆开,比如0x00拆分成0和0,再转化成字符串成了0x30和0x30进行存储。不知道是否有更好的办法?

移植出现的部分问题

  • flash_enveasyflash\port\ef_port.c Line32 出现,但是源码中并没有flash_env的定义,参考demo得知应该为ef_env
  • easyflash\port\ef_port.c中应该增加#include <stdarg.h>防止开了PRINT_DEBUG 编译出错。

自动更新问题

在开启EF_ENV_AUTO_UPDATE后,每次重新开机都会擦写Flash。
是否是缺少在ef_env_init()-->result = ef_load_env()中加载Flash中的EF_ENV_VER_NUMenv_cache[ENV_PARAM_INDEX_VER_NUM]
还是我配置或使用方式不对:smiley:

关于gc机制

版本: 4.0.0的版本

情景: easyflash的分区比较大1MB, 当空闲扇区剩下最后一个时触发gc后, 会擦出全部脏的区域耗时比较长1秒以上.

建议: 有没有可能用懒擦除, 需要几个扇区就擦除几个.

平衡磨损配置疑问

根据easyflash文档说明有以下一段话
例如:EF_ERASE_MIN_SIZE是128K,ENV_USER_SETTING_SIZE是2K, 那么你可以这样定义不同模式下的环境变量总容量:
擦写平衡模式:3*EF_ERASE_MIN_SIZE(它将会有3个Flash扇区去存储环境变量, 1个系统区,2个数据区,按照每个Flash扇区可被擦写10W次计算,那么当前配置至少可擦写20W次);

那么假如 EF_ERASE_MIN_SIZE是4K,ENV_USER_SETTING_SIZE是2K,flash扇区寿命为10k次, 擦写平衡模式下我要如何配置才能支持可擦写1000k次呢?

见到demo平衡模式下,ENV_AREA_SIZE都是配置为3EF_ERASE_MIN_SIZE大小,该模式下我如果设置ENV_AREA_SIZE为30EF_ERASE_MIN_SIZE会有什么后果呢,对flash的使用寿命会有什么影响呢?

增加int数组消耗的env size大小问题

我存储int数组,每一次增加2 int的数据,但是消耗的size提示增加176bytes,为什么这么大?
下面是日志

main---in---
[Flash](easyflash/ef_env.c:1421) ENV start address is 0x08019000, size is 20480 bytes.

[Flash]EasyFlash V4.0.0 is initialize success.

[Flash]You can get the latest version on https://github.com/armink/EasyFlash .

EF_NO_ERR
iap_need_copy_app=0
iap_copy_app_size=0
stop_in_bootloader=0
device_id=1
boot_times=0
user_password_format_list=blob @0x080197C8 22bytes

mode: next generation
size: 2016/10240 bytes.
main---in---
[Flash](easyflash/ef_env.c:1421) ENV start address is 0x08019000, size is 20480 bytes.

[Flash]EasyFlash V4.0.0 is initialize success.

[Flash]You can get the latest version on https://github.com/armink/EasyFlash .

EF_NO_ERR
iap_need_copy_app=0
iap_copy_app_size=0
stop_in_bootloader=0
device_id=1
boot_times=0
user_password_format_list=blob @0x08019878 24bytes

mode: next generation
size: 2192/10240 bytes.

注释有bug

/* ENV area total bytes size in wear leveling and power fail safeguard mode. /
#define ENV_AREA_SIZE (6 * EF_ERASE_MIN_SIZE) /
20K */

这个地方是不是注释写错了?EF_ERASE_MIN_SIZE是4K,那(6 * EF_ERASE_MIN_SIZE)不就是24K吗?你的注释是/* 20K */?

关于写入速度

无论写入多大的数据,延时都大于2s,尝试修改retry_delay_100us 有所减少,但还是很慢?是否有对应的数据呢》
MCU:STM32F105RCT6
FREQUENCE:72MHZ
FLASH CHIP:W25Q128

移植的读写接口如下:
static sfud_err spi_write_read(const sfud_spi *spi, const uint8_t *write_buf, size_t write_size, uint8_t *read_buf,
size_t read_size) {
sfud_err result = SFUD_SUCCESS;
uint8_t send_data, read_data;
int i = 0;
spi_user_data_t spi_dev = (spi_user_data_t) spi->user_data;

if (write_size) {
    SFUD_ASSERT(write_buf);
}
if (read_size) {
    SFUD_ASSERT(read_buf);
}


	FLASH_SPI_CS_ENABLE();
if (write_size && read_size)
{
    /* read data */
		
		uint8_t dummy_byte = 0xff;
  //  qspi_send_then_recv(write_buf, write_size, read_buf, read_size);
		for( i = 0; i < write_size; i++)
		{
			//HAL_SPI_TransmitReceive(&hspi2, (uint8_t*)write_buf+i, &dummy_byte, 1,0xFFFFFF);
			SPI_FLASH_SendByte(write_buf[i]);
		}
		for(i = 0; i < read_size; i++)
		{
				//HAL_SPI_TransmitReceive(&hspi2, &dummy_byte, read_buf, 1,0xFFFFFF);
			read_buf[i]=SPI_FLASH_SendByte(dummy_byte);
		}
}
else if (write_size)
{
    /* send data */
   // qspi_send_then_recv(write_buf, write_size, NULL, NULL);
		HAL_SPI_Transmit(&hspi2,(uint8_t *) write_buf, write_size,0xFFFFFF);

}

	FLASH_SPI_CS_DISABLE();
return result;

}

移植Easyflash 中update更新固件方法

  • 平台STM32F407ZGT6
  • 情况描述
    • 之前移植好是可以用update串口更新程序方法
    • 后面可能工程中加了一些文件,到时使用update方法时出现图片中无法更新的情况。
    • 请问这样一般是什么导致的?

image

STM32 Flash擦写操作导致USART接收丢数据

基本情况:
平台:stm32f103vct6 裸机
串口接收方式:DMA接收中断
FLASH擦除时间:Page/Mass Erase time: 20 ms (文档号-AN2594 Application note
FLASH擦除期间的描述:写/擦除操作进行期间不能从 Flash 中执行代码,这句话一般地方没有,取自STM32F7x参考手册

问题简要描述:
根据上述,stm32 FLASH擦除时无法响应中断,若此时有数据进来,会直接导致丢包。自己测试每次丢数据flash刚好擦除了一次。

目前的解决方式:
1、采用外部FLASH,
2、控制下发时间间隔,

请问还有么有更好的方式?

ef_log.c 的 log_seq_read方法 似乎会读取失败

`static EfErrCode log_seq_read(uint32_t addr, uint32_t log, size_t size) {
EfErrCode result = EF_NO_ERR;
size_t read_size = 0, read_size_temp = 0;
while (size) {
/
move to sector data address /
if ((addr + read_size) % EF_ERASE_MIN_SIZE == 0) {
addr += LOG_SECTOR_HEADER_SIZE;
}
/此处,假如需要读取扇区末位的log,而这一条log数据 恰好跨越2个扇区。 这扇区的log前部分数据恰好又不能整除4的时候,会在方法ef_port_read中断言 %4不等于0./
/
calculate current sector last data size */
read_size_temp = EF_ERASE_MIN_SIZE - (addr % EF_ERASE_MIN_SIZE);
if (size < read_size_temp) {
read_size_temp = size;
}
result = ef_port_read(addr + read_size, log + read_size / 4, read_size_temp);
if (result != EF_NO_ERR) {
return result;
}
read_size += read_size_temp;
size -= read_size_temp;
}

return result;

}`

[SFUD]Error: Flash address is out of bound.

[SFUD]Error: Check SFDP signature error. It's must be 50444653h('S' 'F' 'D' 'P').
[SFUD]Warning: Read SFDP parameter header information failed. The SST25VF016B is not support JEDEC SFDP.
[SFUD]Warning: This flash device is not found or not support.
[SFUD]Error: SST25VF016B flash device is initialize fail.
Flash ENV start address is 0x00000000, size is 819200 bytes.
[SFUD]Error: Flash address is out of bound.
[Flash]Warning: Sector header check failed. Set it to default.
[SFUD]Error: Flash address is out of bound.
[SFUD]Error: Flash address is out of bound.
[Flash]EasyFlash V4.0.0 is initialize success.

测试环境
STM32F207 外挂flash。
2块板,A板跑同样程序,没有异常。 B板,提示上述错误。
可以排除B板的SPI flash硬件有问题。因为另外一套程序(没有使用EasyFlash),在B板上运行,可以正常读写SPI flash。

移植到spi flash使用中遇到问题

移植到spi flash 用了一段时间发现,如果flash是旧的本身有存过其他数据时,在使用easyflash会出现异常,
会进入到这一步,ef_port_erase ---> EF_ASSERT(addr % EF_ERASE_MIN_SIZE == 0); 这里卡住

仿真发现ef_load_env里ef_port_read(get_env_start_addr(), &area0_cur_using_addr, 4);得到的area0_cur_using_addr值会有问题,导致上面的卡住情况

是不是使用easyflash前必须要对flash做一次整片擦除呢?

ef_types中的问题

在ef_types.c中

double ef_get_double(const char *key) {
    char *value = ef_get_env(key);
    if(value) {
        return atof(value);
    } else {
        EF_INFO("Couldn't find this ENV(%s)!\n", key);
        return NULL;
    }
}

此处返回了NULL,是否将其更改为
int ef_get_double(const char *key,double * out_value)
返回值指示是否成功,参数输出,会更好呢?
因为我在移植的过程中此处发生了报错.

日志存储功能最多只能存储一页大小的内容

经过测试,日志存储功能最多只能存储flash一页大小的内容,超过一页大小就写不进去了。
测试环境:
easyflash v4.0.0
mcu stm32f107VC 256K的flash,2K/页
EF_ERASE_MIN_SIZE 2048
EF_WRITE_GRAN 32

找不着原因,烦请指教,谢谢~

编译问题

编译环境:

toolchain: gcc-arm-none-eabi-5_4-2016q3
board: stm32f103zet6
bsp: stm32f10x-hal
使用到的package: ulog,easyflash,ulog_easyflash(版本均为最新)

错误内容:

  1. 类型错误
    位置:packages/EasyFlash-latest/src/ef_env_wl.c:619:19
char c;//变量c定义
if (c == NULL) {//错误
        ...
}

均衡擦写问题

看了一下均衡擦写的实现,我的理解是通过擦除失败,或者写入失败时进行page的切换。
在STM32内部Flash上测试,发现实际不会进行page切换,一直对一个page进行擦写。

这样就达不到均衡擦写的目的了。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.