【研发日记】Matlab/Simulink避坑指南(十)——移位溢出Bug

Mr.Cssust 2024-07-28 13:05:03 阅读 85

文章目录

前言

背景介绍

问题描述

分析排查

解决方案

总结归纳


前言

        见《研发日记,Matlab/Simulink避坑指南(五)——CAN解包 DLC Bug》

        见《研发日记,Matlab/Simulink避坑指南(六)——字节分割Bug》

        见《研发日记,Matlab/Simulink避坑指南(七)——数据溢出钳位Bug》

        见《研发日记,Matlab/Simulink避坑指南(八)——else if分支结构Bug》

        见《研发日记,Matlab/Simulink避坑指南(九)——可变数组应用Bug》

背景介绍

        最近在一个项目中,使用Simulink写一段嵌入式代码,功能是把两个8位的数据,按照Motorola格式拼接成一个16位数据。乍一看感觉挺简单,想着直接用一个MATALAB Function 函数bitshift(x,8)然后相加就能搞定了,但是就这么一个小应用让我栽了跟头,在整个工程中排查了几个小时才找到问题。下面就来分享一下这一小段个人经历。

        一开始代码调试的时候很顺利,我用一个等式直接把计算结果转换成uint16型输出。代码大概是下面这个样子:

<code>function y = fcn(u1, u2)

y = uint16(bitshift(u1,8) + u2);

 

问题描述

        按照上述示例,预想应该可以正常运行,但是实际运行时溢出部分的数据还是出现了异常,示例如下:

分析排查

        使用前两天刚刚解锁的Debug技能《【研发日记】Matlab/Simulink技能解锁(二)——在Function编辑窗口Debug》,来调试一下MatlabFunction函数,示例如下:

        打上断点,执行完这行代码之后,u1、u2和y的值都能看到,但是看不出来出错的原因。

        所以,我把这行代码拆开,继续调试,示例如下:

        上述几行代码执行完之后,发现u1移位后的结果是0,根据这个数据特种推测,可能是Matlab没有自动补位,所以数据溢出了,问题应该就出在这里。

解决方案

        根据上面的分析,调整数据处理的顺序,我把uint16类型转换放在前面,然后再进行移位和相加,代码示例如下:

<code>function y = fcn(u1, u2)

y = bitshift(uint16(u1),8) + uint16(u2);

 

        重新运行程序,问题不再出现,Bug修复完工,示例如下:

        至此,这个拼接两个8位的数据的应用就算是能用起来了。

总结归纳

        那么这个代码调试过程,发现的问题可以积累下来这么几条小经验以供自己将来使用,也给广大网友参考:

        1、函数bitshift(x,1)实现移位的算法,左移不能自动补位,而是直接把溢出的bit舍弃掉了;

        2、Simulink中实现同样移位功能的库模块Shift Arithmetic,也是同样的溢出规则;

        3、在MATALAB Function中Debug时,步进的最小粒度是行,能查看Value的最小粒度是有命名的变量。对于有连续运算的表达式,需要查看计算过程Vlaue时,可以定义一些临时变量,把计算过程付给它即可。

        以上就是本人在解决移位溢出Bug时,一些个人理解和分析的总结,首先介绍了基本的项目背景,然后描述了问题的想象,最后分析排查了Bug原因,并给出了问题解决方案。

        后续还会分享其他的,使用Matlab/Simulink进行研发时遇到的Bug,欢迎评论区留言、点赞、收藏和关注,这些鼓励和支持都将成文本人持续分享的动力。

        上述例程使用的Demo工程,可以到笔者的主页查找和下载。


        版权声明:原创文章,转载请注明出处与链接,违者必究!



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。