我在 MicroChip/XC32 上使用 zlib 1.3.1。它是通过附带的 Harmony 导入的,并且翻译得非常完美。我的目标是通过各种方式通过串行连接接收数据。这已经适用于未压缩的数据。为了节省时间,我想压缩数据,并使用 4k、8k 和现在 16k 的未压缩二进制数据块进行了测试。我在循环内传输数据并在微控制器上对其进行 inflate() 。
为了传输数据块,我使用 Python3.6 导入 zlib( 1.2.10 ) 。
代码是:
# create compressor with user defined options
compressor = zlib.compressobj( level=zlib.Z_BEST_COMPRESSION, wbits=zlib.MAX_WBITS )
data = compressor.compress(datablock) + compressor.flush() # datablock size is 16k
send the data ...
单片机接收到rcvbuf[]中的数据后代码为:
#include "zlib.h"
uint8_t rcv_buf[LEN_RCV_BUF]; // LEN_RCV_BUF = 17000
//uint8_t decompress_buf[LEN_RCV_BUF];
uint8_t decompress_buf[40000]; // increased for testing
uint8_t my_adr[40000]; // increased for testing
/*
*
* rcv_buf is already filled, when this function is called
*
*
*/
void cmd_write_to_myadr(void) {
volatile z_stream out_stream; // zlib struct
uint16_t have;
int ret;
uint16_t dat_len = ( rcv_buf[5] << 8 ) + rcv_buf[6];
/* allocate inflate state */
out_stream.zalloc = Z_NULL;
out_stream.zfree = Z_NULL;
out_stream.opaque = Z_NULL;
out_stream.avail_in = 0;
out_stream.next_in = Z_NULL;
ret = inflateInit( &out_stream ); // HEAP-Size
if( ret != Z_OK ) {
// return ret;
// neg_response(); // AAA
return;
}
// rcv_buf[7]; => != 0 means data is compressed !
out_stream.avail_in = dat_len;
out_stream.next_in = &rcv_buf[8];
out_stream.avail_out = sizeof( decompress_buf );
out_stream.next_out = &decompress_buf[0];
// run DE-compression
ret = inflate( &out_stream, Z_NO_FLUSH );
assert(ret != Z_STREAM_ERROR); /* state not clobbered */
switch( ret ) {
case Z_NEED_DICT :
ret = Z_DATA_ERROR; /* and fall through */
case Z_DATA_ERROR :
case Z_MEM_ERROR :
inflateEnd( &out_stream );
// return ret;
// negativ_response();
return; // BreakPoint is here !!!
case Z_STREAM_END :
break;
default:
return; // BreakPoint is here !!!
}
have = sizeof( decompress_buf ) - out_stream.avail_out;
memWrite_sram_buffer( my_adr, &decompress_buf[0], have );
my_adr += have;
inflateEnd( &out_stream );
}
我正在传输二进制数据(图像和代码)。
事情是,取决于压缩数据块的内容,它是否有效。
我尝试了不同的选项和窗口大小,但在不同的调用 inflate() 后我总是遇到同样的问题。
在 inflate() 函数之后设置断点向我表明它挂在那里。
目前使用Python3仅用于测试,稍后将替换为C++代码。
是因为使用了两个不同版本的zlib进行压缩(deflate)和inflate吗?
OP似乎不愿意提供可以在问题中编译的完整代码,也不愿意提供任何运行它的测试代码和测试用例,但是在对其最新更新进行一些工作之后,我得到了这个编译(请参阅 %% 评论改变了什么):
#include <assert.h> // %% added for assert()
#include "zlib.h"
#define LEN_RCV_BUF 17000 // %% added
uint8_t rcv_buf[LEN_RCV_BUF]; // LEN_RCV_BUF = 17000
//uint8_t decompress_buf[LEN_RCV_BUF];
uint8_t decompress_buf[40000]; // increased for testing
uint8_t my_adr[40000]; // increased for testing
/*
*
* rcv_buf is already filled, when this function is called
*
*/
unsigned cmd_write_to_myadr(void) { // %% added returned length
z_stream out_stream; // zlib struct %% removed "volatile"
uint16_t have;
int ret;
uint16_t dat_len = ( rcv_buf[5] << 8 ) + rcv_buf[6];
/* allocate inflate state */
out_stream.zalloc = Z_NULL;
out_stream.zfree = Z_NULL;
out_stream.opaque = Z_NULL;
out_stream.avail_in = 0;
out_stream.next_in = Z_NULL;
ret = inflateInit( &out_stream ); // HEAP-Size
if( ret != Z_OK ) {
// return ret;
// neg_response(); // AAA
return 0;
}
// rcv_buf[7]; => != 0 means data is compressed !
out_stream.avail_in = dat_len;
out_stream.next_in = &rcv_buf[8];
out_stream.avail_out = sizeof( decompress_buf );
out_stream.next_out = &decompress_buf[0];
// run DE-compression
ret = inflate( &out_stream, Z_NO_FLUSH );
assert(ret != Z_STREAM_ERROR); /* state not clobbered */
switch( ret ) {
case Z_NEED_DICT :
ret = Z_DATA_ERROR; /* and fall through */
case Z_DATA_ERROR :
case Z_MEM_ERROR :
inflateEnd( &out_stream );
// return ret;
// negativ_response();
return 0; // BreakPoint is here !!!
case Z_STREAM_END :
break;
default:
return 0; // BreakPoint is here !!!
}
have = sizeof( decompress_buf ) - out_stream.avail_out;
// %% commenting out undefined function and illegal arithmetic on constant
// %% pointer
// %% memWrite_sram_buffer( my_adr, &decompress_buf[0], have );
// %% my_adr += have;
inflateEnd( &out_stream );
return have; // %% added
}
#include <stdio.h>
int main(void) {
size_t got = fread(rcv_buf + 8, 1, sizeof(rcv_buf) - 8, stdin);
rcv_buf[5] = got >> 8;
rcv_buf[6] = got;
unsigned have = cmd_write_to_myadr();
fwrite(decompress_buf, 1, have, stdout);
return 0;
}
我使用 zlib 压缩数据运行此程序,并且它正确解压。没有对原始代码进行实质性更改,因此问题出在其他地方。也许在数据生成中,包括两个字节长度的标头,在压缩数据的放置中(同样,OP提供了不完整的Python代码来生成测试数据),或者在数据的传输和接收中。