Files
ESP32_COMM/main/utils/ota_compressor.h
T
小龙虾 c4d78bdfbc feat(ota): 临时版本,添加zlib压缩支持和SPI通信优化
添加了zlib压缩功能以减少固件传输时间,特别是在弱网环境下
优化了SPI通信参数和错误处理机制

BREAKING CHANGE: 固件版本从0.3.0升级到0.3.1,增加了压缩传输协议

- 在WiFi OTA中集成zlib压缩/解压缩功能
- 添加压缩选项UI界面和前端压缩逻辑
- 修复SPI引脚配置错误(MOSI/MISO接反)
- 优化SPI通信参数设置增加CS时序控制
- 改进OTA重试机制和超时处理
- 扩展ota_relay组件栈大小从8K到12K
- 添加解压缩回调函数和上下文管理
- 更新固件版本号到0.3.1
- 添加更多调试日志和错误检查
2026-05-31 19:09:11 +08:00

115 lines
3.6 KiB
C++

/*
* ota_compressor.h - OTA 流式解压模块
*
* 支持 zlib/deflate 压缩固件的流式解压,边接收边解压边写 Flash。
* 采用 tinfl 非包装模式 + 自适应缓冲:满了就 flush 到 Flash 然后重置。
* tinfl 函数在 ESP32 ROM 中始终可用,此处仅声明原型,无需 esp_rom 组件依赖。
*/
#pragma once
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include "esp_err.h"
/* ================================================================
* tinfl ROM API 声明(摘自 esp_rom/miniz.h,避免引入 esp_rom 依赖)
* ================================================================ */
typedef unsigned char mz_uint8;
typedef signed short mz_int16;
typedef unsigned int mz_uint32;
typedef unsigned int mz_uint;
#define MZ_MACRO_END while (0)
enum {
TINFL_FLAG_PARSE_ZLIB_HEADER = 1,
TINFL_FLAG_HAS_MORE_INPUT = 2,
TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF = 4,
TINFL_FLAG_COMPUTE_ADLER32 = 8
};
typedef enum {
TINFL_STATUS_BAD_PARAM = -3,
TINFL_STATUS_ADLER32_MISMATCH = -2,
TINFL_STATUS_FAILED = -1,
TINFL_STATUS_DONE = 0,
TINFL_STATUS_NEEDS_MORE_INPUT = 1,
TINFL_STATUS_HAS_MORE_OUTPUT = 2
} tinfl_status;
enum {
TINFL_MAX_HUFF_TABLES = 3,
TINFL_MAX_HUFF_SYMBOLS_0 = 288,
TINFL_MAX_HUFF_SYMBOLS_1 = 32,
TINFL_MAX_HUFF_SYMBOLS_2 = 19,
TINFL_FAST_LOOKUP_BITS = 10,
TINFL_FAST_LOOKUP_SIZE = 1 << TINFL_FAST_LOOKUP_BITS
};
typedef struct {
mz_uint8 m_code_size[TINFL_MAX_HUFF_SYMBOLS_0];
mz_int16 m_look_up[TINFL_FAST_LOOKUP_SIZE];
mz_int16 m_tree[TINFL_MAX_HUFF_SYMBOLS_0 * 2];
} tinfl_huff_table;
/* ESP32-C3: 32-bit bitbuf */
typedef mz_uint32 tinfl_bit_buf_t;
struct tinfl_decompressor_tag {
mz_uint32 m_state, m_num_bits, m_zhdr0, m_zhdr1, m_z_adler32,
m_final, m_type, m_check_adler32, m_dist, m_counter,
m_num_extra, m_table_sizes[TINFL_MAX_HUFF_TABLES];
tinfl_bit_buf_t m_bit_buf;
size_t m_dist_from_out_buf_start;
tinfl_huff_table m_tables[TINFL_MAX_HUFF_TABLES];
mz_uint8 m_raw_header[4];
mz_uint8 m_len_codes[TINFL_MAX_HUFF_SYMBOLS_0 + TINFL_MAX_HUFF_SYMBOLS_1 + 137];
};
typedef struct tinfl_decompressor_tag tinfl_decompressor;
#define tinfl_init(r) do { (r)->m_state = 0; } MZ_MACRO_END
#ifdef __cplusplus
extern "C" {
#endif
tinfl_status tinfl_decompress(tinfl_decompressor *r,
const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size,
mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next,
size_t *pOut_buf_size, const mz_uint32 decomp_flags);
#ifdef __cplusplus
}
#endif
/* ================================================================
* OTA 解压上下文
* ================================================================ */
enum class OtaCompress : uint8_t {
NONE = 0,
ZLIB = 1,
};
struct OtaDecompCtx {
OtaCompress type;
tinfl_decompressor *tinfl; // 仅 ZLIB 模式
uint8_t *out_buf;
size_t out_buf_size;
size_t out_write_pos;
size_t total_in;
size_t total_out;
bool finished;
};
typedef esp_err_t (*ota_decomp_write_fn)(const uint8_t *data, size_t len, void *arg);
esp_err_t ota_decomp_init(OtaDecompCtx *ctx, OtaCompress type, size_t out_buf_size);
esp_err_t ota_decomp_process(OtaDecompCtx *ctx,
const uint8_t *chunk, size_t chunk_len,
ota_decomp_write_fn write_cb, void *user_arg,
size_t *out_bytes);
esp_err_t ota_decomp_finish(OtaDecompCtx *ctx);
void ota_decomp_free(OtaDecompCtx *ctx);