关于STM32二维码生成库的移植,以及堆栈溢出问题的解决。

本文分享了在STM32上移植二维码生成程序的经验,详细介绍了如何通过代码优化解决堆栈溢出问题,使STM32能高效处理长字符串。

1.移植二维码生成程序到项目中

  1. 从链接: https://fukuchi.org/works/qrencode/.下载源码
  2. 在工程里面添加源码主文件夹下除 qrenc.c 以外的所有 .h 和 .c 文件
  3. 创建config.h文件
    文件内容如下
#ifndef QRconfigens
#define QRconfigens

/* Define to 1 if you have the `strdup' function. */

#define HAVE_STRDUP 0

 

/* Major version number */

#define MAJOR_VERSION 3

/* Micro version number */

#define MICRO_VERSION 0

/* Minor version number */

#define MINOR_VERSION 9

/* Define to the version of this package. */

#define PACKAGE_VERSION "3.9.0"


/* Version number of package */

#define VERSION "3.9.0"

#define LIBQRENCODE_VERSION "3.9.0"

 

/* Define to empty if `const' does not conform to ANSI C. */

/* #undef const */

 

/* Define to `__inline__' or `__inline' if that's what the C compiler

calls it, or to nothing if 'inline' is not supported under any name. */

#ifndef __cplusplus

/* #undef inline */

#endif

 

/* Define to 'static' if no test programs will be compiled. */

#define __STATIC

#define WITH_TESTS 1
#endif
  1. 在项目中所有的.c文件中,添加# include “config.h”
  2. 在MAIN.C中,添加#include “qrencode.h”

2.这里就是要解决的问题:STM32堆栈大小不够?

我已经把这个问题及解决办法提交到github,在最新版中已经被改正。
如果你是下载的最新版文件,可以忽略这个问题。

以下是问题的原因以及解决办法:
参考其他人的移植经验,我发现STM32的堆栈大小至少要扩大8倍才能正常运行一些比较短的字符串。
这样做,很明显会影响其他内存空间的大小。
而且STM32运行起来速度不慢,完全不像是运算速度之类的问题。

所以我决定分析代码,检查其中到底是哪里不兼容,试着去修正它,让STM32正常运行这个程序。
经过我一周的检测,发现了这样一个函数,在split.c中。 (注释是自己加的)

static int Split_splitString(const char *string, QRinput *input,QRencodeMode hint)
{
	int length;
	QRencodeMode mode;

	if(*string == '\0') return 0;//输入字符串空则退出

	mode = Split_identifyMode(string, hint);//字符类型判断
	if(mode == QR_MODE_NUM)//数字模式移动
		length = Split_eatNum(string, input, hint);
	else if(mode == QR_MODE_AN)//字符模式移动
		length = Split_eatAn(string, input, hint);
	else if(mode == QR_MODE_KANJI && hint == QR_MODE_KANJI)//汉字模式移动
		length = Split_eatKanji(string, input, hint);
	else																				
		length = Split_eat8(string, input, hint);//8位模式移动
	
	if(length == 0) return 0;
	if(length < 0) return -1;
	return Split_splitString(&string[length], input, hint);//嵌套调用此函数
}

想必大家都能看出来这个问题,如果嵌套调用函数进行处理的话,电脑可能没什么,但是STM32的堆栈大小是不足够用的。使用长一点的字符串,重复压栈几次,就很容易导致堆栈溢出。

所以我把这个函数修改成了这样:

static int Split_splitString(const char *string, QRinput *input,QRencodeMode hint)
{
	int length;
	QRencodeMode mode;

	while(*string != '\0') //return 0;//字符串空则退出
	{
		mode = Split_identifyMode(string, hint);//字符类型判断
		if(mode == QR_MODE_NUM)
			length = Split_eatNum(string, input, hint);//数字模式移动
		else if(mode == QR_MODE_AN)
			length = Split_eatAn(string, input, hint);//数字字母混合模式移动
		else if(mode == QR_MODE_KANJI && hint == QR_MODE_KANJI)
			length = Split_eatKanji(string, input, hint);//汉字模式移动
		else																				
			length = Split_eat8(string, input, hint);//8位模式移动
		
		if(length == 0) return 0;
		if(length < 0) return -1;
	
		string = &string[length];
	}
	return 0;
}

取消了嵌套调用,而是改为循环。
经过测试,STM32在使用原来的小堆栈,也可以完美运行。

#define m_EXPAND_DOT 3

void QRcode_draw_Str(const char * QC_DATA)
{
	QRcode*qrcode; 
	u32 i=0,j=0;

	qrcode = QRcode_encodeString(QC_DATA, 3,QR_ECLEVEL_M,QR_MODE_8,1);//用输入字符串生成二维码
	
	if(qrcode != NULL)//如果成功生成二维码  
   { 
   		TFT_COLOR_18_Clear();//清屏			
        for(i = 0; i < qrcode->width; i++)//高循环  
        {  
            for(j = 0; j < qrcode->width; j++)//宽循环  
            {  
                if(qrcode->data[i*qrcode->width + j] & 0x01)  //判断目前位置颜色
					TFT_COLOR_18_draw_block(m_EXPAND_DOT*i,m_EXPAND_DOT*j,m_EXPAND_DOT,m_EXPAND_DOT,0x0000);//画黑块
                else  
                	TFT_COLOR_18_draw_block(m_EXPAND_DOT*i,m_EXPAND_DOT*j,m_EXPAND_DOT,m_EXPAND_DOT,0xffff);//画白块                         
            }  
        } 
	 QRcode_free (qrcode);//释放生成的二维码占用的内存
	}
}

例如:

QRcode_draw_Str("http://img.xz7.com/up/2017-9/2017090516331545018.jpg");

如此长的字符串可以直接生成,没有问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值