点击上方,选择“置顶/星标公众号”
大家好,我是麦鸽,在单片机开发中,片上Flash存储空间往往捉襟见肘。无论是传感器日志、固件升级包,还是配置参数,数据量的增长常常超出硬件资源的承载能力。
直接存储原始数据不仅占用空间,还可能影响系统响应速度。此时,无损压缩算法成为解决问题的关键——通过压缩数据再存储,可显著节省空间。
而在众多压缩方案中,基于LZSS算法的开源库heatshrink凭借其轻量化、低内存占用的特性,已经有1.4K的star了。
项目地址:github.com/atomicobject/heatshrink
LZSS(Lempel-Ziv-Storer-Szymanski)是LZ77算法的改进版本,其核心思想是通过滑动窗口技术实现重复字符串的高效编码。
在LZSS算法的数据编码里面有一个重要概念,就是:数据分组。
一个字节由8位组成,因此可以用一个字节来标记后面的至少8字节是否存在压缩编码,而不用\0x00\0x00
的前缀来区分是否被压缩,从而节省了大量的\0x00\0x00
前缀空间开销。
数据分组标记方式:
由此看见,这种数据分组的方式,最坏的情况下,只会每8个字节增加一个字节的额外空间开销,比起每个字节另外需要2个字节的空间开销而言,效率大幅提升。篇幅有限,这里只做简单介绍
heatshrink是基于LZSS算法优化的开源库,专为资源受限的单片机环境设计。其核心优势体现在以下几个方面:
window_sz2
)和前瞻缓冲区大小(lookahead_sz2
),开发者可平衡压缩率与内存消耗。例如,设置window_sz2=10
(窗口1024字节)和lookahead_sz2=4
(前瞻16字节)是常见配置。heatshrink_encoder
和heatshrink_decoder
状态机管理压缩流程,减少CPU占用。sink
)、处理(poll
)和结束(finish
)四类函数,集成仅需数行代码。HEATSHRINK_DYNAMIC_ALLOC=0
,可完全避免动态内存申请,增强系统稳定性。在环境监测设备中,传感器每小时产生1KB的温湿度数据。使用heatshrink压缩后,数据体积平均减少40%
通过压缩固件文件,可减少无线传输的数据量。以STM32F4为例,压缩后的固件传输时间缩短30%,且解压过程仅需数毫秒。
将JSON或二进制格式的配置参数压缩存储,既节省空间,又能在读取时快速解压,避免解析延迟。
git clone https://github.com/atomicobject/heatshrink.git
# 将heatshrink_encoder.c、heatshrink_decoder.c加入工程
在heatshrink_config.h
中设置:
#define HEATSHRINK_DYNAMIC_ALLOC 0 // 禁用动态内存
#define HEATSHRINK_WINDOW_BITS 10 // 窗口大小1024字节
#define HEATSHRINK_LOOKAHEAD_BITS 4 // 前瞻缓冲区16字节
// 压缩数据
heatshrink_encoder *enc = heatshrink_encoder_alloc();
uint8_t input[] = "原始数据";
uint8_t output[128];
size_t input_size = sizeof(input);
size_t output_size = 0;
// 分块处理
while (input_size > 0) {
heatshrink_encoder_sink(enc, input, input_size, &input_consumed);
heatshrink_encoder_poll(enc, output, sizeof(output), &output_byte_count);
// 写入Flash或发送数据
input += input_consumed;
input_size -= input_consumed;
}
heatshrink轻量、高效,无论是Flash空间优化,对于资源紧张但需要数据完整性的场景,都是很好的选择。通过合理配置参数,可最大化发挥其性能,为资源紧张的嵌入式系统提供更好的存储能力。
🫵兄弟们!一个人单打独斗确实能冲得挺快,但要想走得更远、更稳,还得靠一群志同道合的伙伴啊!
👊 麦鸽的知识星球现在已经聚集了一波人,大家都在这里互相学习、共同进步。
如果你也想找个靠谱的学习圈子
赶紧 戳链接 🔗 加入我们吧!
在这里,你能读到星球专栏的干货,优质教程,练手项目,随时向麦鸽提问,还能帮你定制学习计划。别犹豫了,兄弟,一起冲!💪
往期推荐