调试小细节之内存溢出

调试过程中,莫名其妙的问题总是会时不时冒出来几个,但是不管问题如何怪异,只要细细分析,从每一处不起眼的改动去查找比对,查手册,查软件版本差异,查寄存器,查map文件等等所有相关文件,就一定能解决所有问题;毕竟电子产品的应用开发是二次开发,不是什么创新创造,都是基于现有的给出的规则和定义做新的排列组合。

调试对象为51内核的电机控制板

  1. 现象: 最近在调试一个新的产品过程中,将电机调速由pwm占空比控制改为串口通信控制,移植基本的串口通信功能后,验证了新版硬件的串口收发都能正常工作,且电机功能未受到任何影响。随后在确认了通信协议后,编写添加相关通信代码,结果电机却无法运行,且再讲所有通信相关代码删除屏蔽后电机仍然无法工作;在与上一版本软件进行比较发现,所有电机相关程序未改变,只是添加了串口通信文件和通信校验的crc文件,且均已经屏蔽未使用;

  2. 问题
    电机不运行,仿真时程序有正常工作,但是所有变量无法置位或任何操作;
    所有电机相关程序未动,添加的相关代码和文件均已删除屏蔽

  3. 分析解决:经过多方面查找,最后在map文件中发现xdata大小为3789(见图一),而根据数据手册xdata为2K,最大768bytes
    图1
    图2
    随后发现编译过程中xdata早就不知道什么时候超过了上限,原来是内存溢出,于是开始查找大数组,随后屏蔽了串口通信接收和发送的数据共80个字节,仍然无济于事;随后终于在添加的CRC文件中找到一堆大数组,将大数组屏蔽后问题解决;crc文件是为了与上位机保持一致校验采用了同事提供的文件,但是这份文件把所有crc的校验的计算法和查表法都汇集在一起了,当时确实没想太多就直接使用了;

上述简单的描述了问题解决的基本过程,但是实际操作过程中却没有那么顺利快速的想到这些,虽然我遵循自己一贯的解决思路顺利的找到并解决了问题,但是仍有几点心得需要牢记:

1.调试过程中如果添加大数组或者有大数组相关的文件,一定要关注当前芯片使用了多少内存和闪存,实际总共有多少内存和闪存,两者应该加强条件反射,便于提前发现问题;

2.由于我使用的MCU是51核且资源非常少,如果完全遵循常规的编程规范,减少全局变量使用,使用大量局部变量做函数封装,则会带来内存占用过多,所以在这种情况下要尽量使用全局变量完成模块之间的逻辑,可以采用结构体构建不同对象使用指针和地址访问来实现快速准确且不混乱的数据传递。

3.这次内存溢出还暴露出另一个问题,编译器为什么没有报警报错,一般我们在使用keil5创建调试工程时,默认是有设置内存大小的,如下图
图3
但是在我调试的这个keil4工程中,并没有做相关设置
图4
将芯片内存大小输入,
图5
然后将屏蔽的大数组放开,编译报错如下
图6

*** ERROR L107: ADDRESS SPACE OVERFLOW

所以在软件正确配置芯片资源后,是可以检测出这种问题的,这样就能及时发现问题,而不用白白浪费很多时间去查找。
此时问题虽然解决,但是内存却占用极大
图7
因为我使用的是crc8查表法,所查的数组都是固定不需要修改的数据,所以在数组定义是加上codeconst这两个关键字即可将数据存储在falsh上,且不可修改,这样大大减小了内存占用。
图8

  1. 思考总结虽然最终都能查到并解决了问题,但是想到一句古话:贵人不立围墙之下,同理:优秀的工程绝不仅仅是比别人更快的发现问题和解决问题,而且在项目开始的时候就会做好相对完善的准备,避免问题的发生,才是真正的高级。当然这不可能一蹴而就,离不开长期项目的积累和用心的总结。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值