这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » FPGA » 单片机的Flash又爆满了,快来试试这个无损压缩库heatshrink

共1条 1/1 1 跳转至

单片机的Flash又爆满了,快来试试这个无损压缩库heatshrink

菜鸟
2025-09-08 15:42:52     打赏
1 单片机数据不够存

大家好,我是麦鸽,在单片机开发中,片上Flash存储空间往往捉襟见肘。无论是传感器日志、固件升级包,还是配置参数,数据量的增长常常超出硬件资源的承载能力。

直接存储原始数据不仅占用空间,还可能影响系统响应速度。此时,无损压缩算法成为解决问题的关键——通过压缩数据再存储,可显著节省空间。

而在众多压缩方案中,基于LZSS算法的开源库heatshrink凭借其轻量化、低内存占用的特性,已经有1.4K的star了。

image项目首页

项目地址:github.com/atomicobject/heatshrink


2 什么是LZSS算法?

LZSS(Lempel-Ziv-Storer-Szymanski)是LZ77算法的改进版本,其核心思想是通过滑动窗口技术实现重复字符串的高效编码。

在LZSS算法的数据编码里面有一个重要概念,就是:数据分组。

一个字节由8位组成,因此可以用一个字节来标记后面的至少8字节是否存在压缩编码,而不用x00x00的前缀来区分是否被压缩,从而节省了大量的x00x00前缀空间开销。

数据分组标记方式:


Data Bits

由此看见,这种数据分组的方式,最坏的情况下,只会每8个字节增加一个字节的额外空间开销,比起每个字节另外需要2个字节的空间开销而言,效率大幅提升。篇幅有限,这里只做简单介绍


3 heatshrink压缩库

heatshrink是基于LZSS算法优化的开源库,专为资源受限的单片机环境设计。其核心优势体现在以下几个方面:

1. 极低的内存占用
  • 运行时内存需求:仅需50-300字节的RAM,适用于RAM仅KB级的单片机(如STM32F0系列)。
  • Flash占用:代码体积最小可压缩至1KB(AVR平台测试数据),几乎不增加固件体积。
  • 配置灵活性:通过调整窗口大小(window_sz2)和前瞻缓冲区大小(lookahead_sz2),开发者可平衡压缩率与内存消耗。例如,设置window_sz2=10(窗口1024字节)和lookahead_sz2=4(前瞻16字节)是常见配置。
2. 实时友好的处理机制
  • 流式处理:支持分块压缩/解压,无需一次性加载全部数据,适合实时数据流场景。
  • 状态机设计:通过heatshrink_encoderheatshrink_decoder状态机管理压缩流程,减少CPU占用。
3. 开源与易用性
  • 跨平台支持:纯C语言实现,兼容FreeRTOS、裸机系统及各类IDE(如Keil、IAR)。
  • 简洁API:提供初始化、数据输入(sink)、处理(poll)和结束(finish)四类函数,集成仅需数行代码。
  • 无动态内存分配:通过预编译选项HEATSHRINK_DYNAMIC_ALLOC=0,可完全避免动态内存申请,增强系统稳定性。

4 适用的场景传感器数据压缩存储

在环境监测设备中,传感器每小时产生1KB的温湿度数据。使用heatshrink压缩后,数据体积平均减少40%

OTA固件升级

通过压缩固件文件,可减少无线传输的数据量。以STM32F4为例,压缩后的固件传输时间缩短30%,且解压过程仅需数毫秒。

配置参数管理

将JSON或二进制格式的配置参数压缩存储,既节省空间,又能在读取时快速解压,避免解析延迟。


5 使用指南步骤1:获取代码可以通过git直接拉取代码,或者 公众号后台 回复【LZSS
git clone https://github.com/atomicobject/heatshrink.git
# 将heatshrink_encoder.c、heatshrink_decoder.c加入工程
步骤2:配置

heatshrink_config.h中设置:

#define HEATSHRINK_DYNAMIC_ALLOC 0  // 禁用动态内存
#define HEATSHRINK_WINDOW_BITS 10   // 窗口大小1024字节
#define HEATSHRINK_LOOKAHEAD_BITS 4 // 前瞻缓冲区16字节
步骤3:示例
// 压缩数据
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;
}
6 总结

heatshrink轻量、高效,无论是Flash空间优化,对于资源紧张但需要数据完整性的场景,都是很好的选择。通过合理配置参数,可最大化发挥其性能,为资源紧张的嵌入式系统提供更好的存储能力。





关键词: 单片机     Flash     heatshrink    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]