连续一天加一个晚上,查资料,发现无解。
压缩不可能在STM32上进行的。因为代码中那个内存分配的结构体占内存太大了。解压是可以实现的。
因此这个算法在STM32上也是有一些作用:在某些场合可以在PC机进行压缩存入ARM中,然后ARM解压。比如某些代码放到flash中。不过这些场合很少遇到。
LZMA的代码生成量并不很大,LZMA920版本,要用这个版本,生成的可执行文件很小。
几个不错的文章这里列出来:
7-zip 下lzma数据解压缩方式_LG_Ting的博客-优快云博客
linux 7z命令安装使用及其交叉编译移植到arm linux平台
但是最重量级的文章还是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里用不上了!!