news 2026/6/17 22:59:52

FlashDB / Easyflash触发GC导致系统卡死的解决方法分享

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
FlashDB / Easyflash触发GC导致系统卡死的解决方法分享

FlashDB / Easyflash触发GC导致系统卡死的解决方法分享

遇到的问题:启动后单片机打印这样的log

Bootthismcu....[SFUD]Find a Winbond W25Q32BV flash chip.Size is4194304bytes.[SFUD]norflash0 flash device is initialize success.flashDB_myDataSet_construct.OK[D/FAL](fal_flash_init:49)Flash device|norflash0|addr:0x00000000|len:0x00400000|blk_size:0x00001000|initialized finish.[I/FAL]====================FAL partition table====================[I/FAL]|name|flash_dev|offset|length|[I/FAL]-------------------------------------------------------------[I/FAL]|fdb_kvdb1|norflash0|0x00000000|0x00002000|[I/FAL]|fdb_tsdb0|norflash0|0x00002000|0x00040000|[I/FAL]|fdb_tsdb1|norflash0|0x00042000|0x00040000|[I/FAL]=============================================================[I/FAL]Flash AbstractionLayer(V0.5.99)initialize success.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1801)The oldest addr is @0x00000000[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1817)KVDB size is8192bytes.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1161)**The remain empty sector is0,GC threshold is1.**[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(sch)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(chipID_crc32)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(user_brightness)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(bootCount)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(mode_auto)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(bootCount)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(bootCount)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(bootCount)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(bootCount)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(mode_auto)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(mode_auto)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(mode_auto)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(bootCount)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(bootCount)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(mode_auto)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(bootCount)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(bootCount)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(mode_auto)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(bootCount)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(bootCount)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(mode_auto)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(mode_auto)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(bootCount)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(mode_auto)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(mode_auto)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(mode_auto)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(mode_auto)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(mode_auto)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(mode_auto)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(mode_auto)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(mode_auto)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(mode_auto)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(mode_auto)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(mode_auto)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(mode_auto)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(mode_auto)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(mode_auto)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(mode_auto)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(mode_auto)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(mode_auto)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(mode_auto)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(mode_auto)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(mode_auto)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(mode_auto)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(mode_auto)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(mode_auto)is garbage NOT need move,collect it.[FlashDB][kv][env][fdb_kvdb1](../Core/FlashDB-master/src/fdb_kvdb.c:1130)KV(mode_auto)is garbage NOT

把KVDB分区从2个sector更改为4个sector后,问题暂时可以解决,但是不知道是否会再次发生
别人的解决方法:

芯片:SMT32F429
操作系统:RTT 5.0.0
文件系统:littlefs + romfs
flashdb:kvdb + 文件模式 使用
使用场景
分配5个扇区情况
创建一个线程,1秒写入一次当前时间戳至kvdb数据库中
发现如果分配五个扇区,前四个扇区都可以正常读写。
当五个扇区都写满的时候,需要搬运数据到第0扇区去。
日志如下,没有空扇区了。
The remain empty sector is 1, GC threshold is 1.
这个日志已出现,系统就会卡死,看门狗复位
尝试debug调试,总是调到没有使用的函数里面,函数地址
0x00000xx开头。
解决方法
经过不断尝试,ps打印当前线程状态时,发现时间戳保存线程的最大使用率高达81%.一般来说都要控制在75%左右合适。
分析是不是应该堆栈不够导致系统卡死
将该线程从2048改为4096后,不会出现卡死问题了。线程的最大使用率变为51%

分析
flshdb在扇区都满的情况下,会进行Collect操作。这个操作是在当前线程完成的,会增加占用率。
然而这个运行操作并不是会频繁出现的,所以很难判断到是堆栈不够导致的问题。
建议
能否增加一个异步模式来专门执行gc与Collect操作?
就像ulog的异步线程的方式那样。
写入数据库并不要求实时性,只需要确保数据的准确就好了。
异步方式需要一个缓冲区,缓冲区满了才能传入数据,可能导致缓冲区未满时掉电,导致数据缺失了一部分。
但是这个情况,可以添加一个函数,立刻刷新缓冲区。然后给用户使用。 用户自己实现掉电保存与硬件。
所以可以增加一个异步线程的选项,提供用户使用。看用户是选择实时,还是效率。
原作者:用户名由3_15位

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/15 15:28:30

GSE高级宏编译器:魔兽世界自动化战斗的技术实现方案

GSE高级宏编译器:魔兽世界自动化战斗的技术实现方案 【免费下载链接】GSE-Advanced-Macro-Compiler GSE is an alternative advanced macro editor and engine for World of Warcraft. It uses Travis for UnitTests, Coveralls to report on test coverage and the…

作者头像 李华
网站建设 2026/6/13 21:40:09

人体姿态检测与动作搜索:从入门到精通的完整指南

人体姿态检测与动作搜索:从入门到精通的完整指南 【免费下载链接】pose-search x6ud.github.io/pose-search 项目地址: https://gitcode.com/gh_mirrors/po/pose-search 在当今人工智能蓬勃发展的时代,实时人体姿态检测和智能动作搜索技术正在彻底…

作者头像 李华
网站建设 2026/6/15 20:32:19

EmotiVoice能否替代真人配音?实测结果告诉你

EmotiVoice能否替代真人配音?实测结果告诉你 在某短视频平台上,一个名为“AI小夏”的虚拟主播正用温柔又略带俏皮的语气讲述今日天气。她的声音自然流畅,情绪起伏恰到好处——说到晴天时轻快上扬,提到降温则微微低沉。观众几乎无法…

作者头像 李华
网站建设 2026/6/15 19:13:33

如何快速解决Edge-TTS语音合成地区访问限制问题

Edge-TTS是一个强大的Python语音合成库,让开发者能够免费使用微软Edge的在线文本转语音服务。然而,近期部分地区的用户在使用Edge-TTS时频繁遇到访问限制问题,严重影响了语音合成功能的正常使用。 【免费下载链接】edge-tts Use Microsoft Ed…

作者头像 李华
网站建设 2026/6/16 8:58:33

ChatTTS-ui语音合成实战:打造个性化语音包完整指南

ChatTTS-ui语音合成实战:打造个性化语音包完整指南 【免费下载链接】ChatTTS-ui 匹配ChatTTS的web界面和api接口 项目地址: https://gitcode.com/GitHub_Trending/ch/ChatTTS-ui 还在为语音合成应用缺乏特色而烦恼吗?ChatTTS-ui作为当前热门的开源…

作者头像 李华
网站建设 2026/6/17 1:46:34

watermark.js完整教程:前端水印技术的终极解决方案

在数字化内容日益丰富的今天,图片版权保护已成为每个网站开发者必须掌握的技能。watermark.js作为纯前端水印处理库,彻底改变了传统依赖服务器的水印添加方式,让图片保护变得简单高效。 【免费下载链接】watermarkjs :rice_scene: Watermarki…

作者头像 李华