STM32+LZMA的移植经历

连续一天加一个晚上,查资料,发现无解。

压缩不可能在STM32上进行的。因为代码中那个内存分配的结构体占内存太大了。解压是可以实现的。

因此这个算法在STM32上也是有一些作用:在某些场合可以在PC机进行压缩存入ARM中,然后ARM解压。比如某些代码放到flash中。不过这些场合很少遇到。

LZMA的代码生成量并不很大,LZMA920版本,要用这个版本,生成的可执行文件很小。

几个不错的文章这里列出来:

7-zip 下lzma数据解压缩方式_LG_Ting的博客-CSDN博客

linux 7z命令安装使用及其交叉编译移植到arm linux平台

LZMA SDK - How to Use

但是最重量级的文章还是LZMA源码自带的帮助文章:lzma.txt

How To compress data
--------------------


Compile files: LzmaEnc.h + LzmaEnc.c + Types.h +
LzFind.c + LzFind.h + LzFindMt.c + LzFindMt.h + LzHash.h


Memory Requirements:
  - (dictSize * 11.5 + 6 MB) + state_size

文档写的是要6M的内存。ARM没这么大内存,除非外扩。

以上就是这大周末的研究成果。全是眼泪!

原先下载了个代码,makefile一下,通过了。还把一个文件给压缩了,我还以为是程序进行压缩的呢!一看代码,才看到只有解压缩的代码。压缩式用windows工具压缩的。

于是到官网下载代码,然后移植到STM32F103,由于手里没带电路板,用软仿真,然后发现需要alloc函数,于是自己弄了一个alloc函数,然后发现压缩的返回值是2,返回值表示的是内存错误。

然后用单步调试跟踪,发现那个结构体超级大的结构体啊!

就是运行到LZMAENC.C里面的LzmaEnc_Create的这句话:

  p = alloc->Alloc(alloc, sizeof(CLzmaEnc));

结构体如下:

typedef struct
{
  IMatchFinder matchFinder;
  void *matchFinderObj;


  #ifndef _7ZIP_ST
  Bool mtMode;
  CMatchFinderMt matchFinderMt;
  #endif


  CMatchFinder matchFinderBase;


  #ifndef _7ZIP_ST
  Byte pad[128];
  #endif
  
  UInt32 optimumEndIndex;
  UInt32 optimumCurrentIndex;


  UInt32 longestMatchLength;
  UInt32 numPairs;
  UInt32 numAvail;
  COptimal opt[kNumOpts];
  
  #ifndef LZMA_LOG_BSR
  Byte g_FastPos[1 << kNumLogBits];
  #endif


  UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
  UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1];
  UInt32 numFastBytes;
  UInt32 additionalOffset;
  UInt32 reps[LZMA_NUM_REPS];
  UInt32 state;


  UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
  UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances];
  UInt32 alignPrices[kAlignTableSize];
  UInt32 alignPriceCount;


  UInt32 distTableSize;


  unsigned lc, lp, pb;
  unsigned lpMask, pbMask;


  CLzmaProb *litProbs;


  CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
  CLzmaProb isRep[kNumStates];
  CLzmaProb isRepG0[kNumStates];
  CLzmaProb isRepG1[kNumStates];
  CLzmaProb isRepG2[kNumStates];
  CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];


  CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
  CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];
  CLzmaProb posAlignEncoder[1 << kNumAlignBits];
  
  CLenPriceEnc lenEnc;
  CLenPriceEnc repLenEnc;


  unsigned lclp;


  Bool fastMode;
  
  CRangeEnc rc;


  Bool writeEndMark;
  UInt64 nowPos64;
  UInt32 matchPriceCount;
  Bool finished;
  Bool multiThread;


  SRes result;
  UInt32 dictSize;
  UInt32 matchFinderCycles;


  int needInit;


  CSaveState saveState;
} CLzmaEnc;

如果剪裁一下有小可能搞定,但是代价估计很大,还不稳定。

然后就像咋办呢?看看提供的文档吧!于是就发现了作者写的:

Memory Requirements:
  - (dictSize * 11.5 + 6 MB) + state_size

于是就彻底歇菜了!!!

看样子以后要养成先看文档再看代码的习惯!!

嗨!多好的代码啊!可惜arm里用不上了!!

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值