嵌入式目标板程序的压缩(1)--学习使用LZMA SDK

来源:互联网 发布:抵御网络黑客攻击 编辑:程序博客网 时间:2024/06/05 12:01

 

之前完成了串口升级到功能之后,觉得700多K一分多钟的传输时间应该还有优化空间。波特率最大就115200bps,而且有些特殊时候还要降到19200用,所以减少程序大小是个途径。一般要显著减少代码量比较困难,除非程序里面“废话”太多;而且做编译器优化实验观察,差异还不到10%。压缩自然是个好方法,某次打rar包仔细看了下,500多K的程序压到不到200k,看来效果比较明显。于是有了以下想法:

一。找一个公开的压缩算法,最好有良好的C接口

二。测试该算法的压缩性能,压缩比大概跟Winrar差不多,不多于1倍就好

三。移植解压部分到目标板程序,实现[上位机压缩程序]->[串口传输]->[目标板解压升级程序]的串口升级流程

 

首先是找一个公开的压缩算法:

LZW

http://zh.wikipedia.org/zh/LZW

LZMA

http://zh.wikipedia.org/wiki/LZMA

.....

然后不停地搜源码下源码,下了一堆。浏览了一下”战利品“,最后发现有个LZMA SDK的C实现比较合我胃口。用vs写了个console工程,就调用LzmaLib里面的LzmaCompress和LzmaUncompress接口,参数全部默认,实现了一个简单的命令行压缩工具。

 

这里小结下Lzma SDK的使用:

最顶层的接口是LzmaCompress和LzmaUncompress,位于LzmaLib.c中,声明如下:

//--------------------------------------------//

MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen,

  const unsigned char *src, size_t srcLen,
  unsigned char *outProps, size_t *outPropsSize, /* *outPropsSize must be = 5 */
  int level,      /* 0 <= level <= 9, default = 5 */
  unsigned dictSize,  /* default = (1 << 24) */
  int lc,        /* 0 <= lc <= 8, default = 3  */
  int lp,        /* 0 <= lp <= 4, default = 0  */
  int pb,        /* 0 <= pb <= 4, default = 2  */
  int fb,        /* 5 <= fb <= 273, default = 32 */
  int numThreads /* 1 or 2, default = 2 */
  );

//--------------------------------------------//

MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen,

  const unsigned char *src, SizeT *srcLen,
  const unsigned char *props, size_t propsSize);

//--------------------------------------------//

调用很简单,压缩接口只要填入进出缓冲区和默认参数就行了,注意到是outProps参数是输出参数,这个数组值在相应解压的时候用;解压接口参数更少,注意要填好对应的outProps参数,还有提供足够大destLen的缓冲区。看代码可以发现,outProps数组其实就是压缩参数lc,lp,bp和dictSize算出来的。

 

写好便开始测试,首先看看压缩的效果:把目标板的程序试着压缩,576K压缩到153K。不错!满足了我的预期。

其次试试压缩后解压是否正确,是否生成的与原来文件一模一样;换几组参数再测,没问题。

然后分别找来几个不同类型不同大小的文件,例如txt exe pdf doc bmp rar zip,压缩结果和winRAR相当。还查到程序的一些bug,不过对于上百兆的文件解压结果有误,一时没查出原因,只好先搁置。

最后换了几组参数测,打算把从level到pb五个参数所有排列的参数都测一遍。不想改程序,很自然就求助于批处理/脚本了。(待续)

 

附LZMA C SDK精简包(csdn下载,需注册,不需积分)

 

原创粉丝点击