在HC32F460单片机中使用变量控制声明数组大小遇到的问题

项目场景:

MCU:HC32F460KETA
MDK:KEIL_5.28

问题描述

在开发过程中偶然遇到了读取外部储存时,读取失败报错的问题。使用的方案是在函数中申请一段缓冲Buffer数组,从外部储存中读出来后再对Buffer数组进行解析。为了防止栈空间溢出,所以在MCU配置文件中将栈空间定义了2k大小。起初程序运行没有什么问题,直到我开始尝试用变量来声明数组,如下:

@Override
	public void run() {
		uint16_t R_Size = 510/* 459+ (Properties_MXLeng + Data_vale_MXLeng + 7) * MaxSlaveCount*/;
		uint8_t R_Buffer[R_Size];
		uint8_t iic_work_statue;
		
		iic_work_statue = I2C_Mem_Read(E2_ADDRESS, DATA_TEST_ADDR, R_Buffer, R_Size, TIMEOUT);
	}

运行之后便出现了如下现象
在这里插入图片描述
参数读取居然报错了,并且缓冲Buffer指针居然是NULL!!!
为了查找问题原因,我尝试直接用数字常量声明数组,即如下所示:

@Override
	public void run() {
		uint16_t R_Size = 510/* 459+ (Properties_MXLeng + Data_vale_MXLeng + 7) * MaxSlaveCount*/;
		uint8_t R_Buffer[510];
		uint8_t iic_work_statue;
		
		iic_work_statue = I2C_Mem_Read(E2_ADDRESS, DATA_TEST_ADDR, R_Buffer, R_Size, TIMEOUT);
	}

修改后程序正常运行不报错,所以问题就出在uint8_t R_Buffer[R_Size ] 这种声明操作上。


原因分析:

在我的理解里,函数中的局部变量应该是存放于栈空间当中的,并且生命周期是以函数调用和结束为界限的,所以在当进入到I2C_Mem_Read()函数中时,R_Buffer的生命周期还存在理应不为NULL。另外在之前的个别测试里,我也用过变量声明数组的形式,只不过当时的变量范围都很小只有20~30的样子。按这个思路尝试把510改成200,重新编译运行程序,程序又正常运行不报错了。
所以问题出现的原因和uint8_t R_Buffer[R_Size ] 的大小有关,和空间大小挂钩的话,最有可能的还是空间溢出的情况。但是栈空间明明已经提前定义好了,是远大于510个字节的,并且使用uint8_t R_Buffer[510]这种方法声明也不会报错,这证实不是栈空间溢出的原因。

在查阅堆栈空间大小定义文件后,发现堆空间只有512个字节,那么有没有可能是堆空间溢出了?
在这里插入图片描述
证实疑惑的最好办法是实践,将堆空间由512字节扩大到1024个字节后,再次使用uint8_t R_Buffer[R_Size ] 这种形式声明变量,编译运行。
在这里插入图片描述

结果是程序正常运转且无任何报错!

结论:在函数中使用uint8_t R_Buffer[R_Size ] 这种形式声明变量,变量使用的是堆空间,而uint8_t R_Buffer[510] 这种声明方式使用的是栈空间


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值