0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

在MCU编程中局部变量赋初始值的重要性

jf_pJlTbmA9 来源:瑞萨MCU小百科 作者:瑞萨MCU小百科 2023-10-16 18:29 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

C语言编程过程中,由于计算需要,会使用各种各样的变量,用于给需要访问的地址取个名称,方便编程中使用,代码维护者也容易理解。

这里先给大家分享一个案例,让大家意识到变量赋初始值的重要性。

某用户在基于瑞萨MCU:RA6T2做开发时,发现一个问题,MCU发出的CAN数据帧总是莫名其妙的出错,比如应用中明明只使用了CAN的扩展帧,但是使用捕捉工具总是能捕捉到远程帧,出现远程帧的情况毫无规律可言,有时添加一个定时器中断,该现象就不会出现了,有时修改了代码里某处跟CAN没有任何关系的代码,该问题又会出现,过了两周时间调试无果。在介入Debug时发现,他使用的是CAN扩展帧,扩展帧使用29位ID标识符,而且对ID区数据定义了一个如下结构体:

wKgaomUD5XKAKA7FAAAHACC9mOU044.png

他在需要发送CAN帧时,申请一个如上结构体的临时变量can_id,在把can_id.id赋值后,再把该变量的地址传递给CAN的发送函数,在发送函数里使用如下语句把id的数据写入CAN的发送消息缓冲寄存器

wKgaomUD5XOAApX2AAAHaPYEckQ954.png

如下图,其中第30位的0表示数据帧,并不是远程帧,31位的1表示扩展帧。

wKgZomUD5XWAca2cAADiCZqaiwY457.png

用户是把can_id的所有数据赋值给了CFDTMID0寄存器,假如can_id.dummy中第二个位是1,会有什么后果呢?CFDTMID0.TMRTR=1,即CAN会发送远程帧。

用户又问:我没有给dummy赋值啊,为什么dummy的第二个位会变成1呢?这就是问题所在了,就是因为他没有给can_id.dummy赋值,所以can_id.dummy有可能为任意的值。下面详细分析一下,为什么这个局部变量的值会随意变化。

大家知道,变量根据存储类型和用途,一般可以分成:全局变量和局部变量。全局变量,就是指分配了固定地址的变量,全局变量可以在整个代码范围内使用。我们在申请全局变量时,有时对它赋一个初始值,也时也不会赋初始值,在代码上可能看不出有什么区别,但是编译器在编译程序时,是区别对待他们的。对于有初始化的变量,编译器还需要在Code Flash里(代码存储区)分配一段空间,把变量的初始值全部存储在该区域里,并且在MCU的启动代码里插入一段程序,把这些Code Flash区的初始值拷贝到变量对应的RAM地址中。假如上面的can_id是全局变量,并且申明变量的同时并按下图赋初始值:

wKgaomUD5XeAaBPmAAAqgT5kmag262.jpg

这时can_id.dummy=0,如果代码中用户没有再赋值,它的值也不会变化,这样就不会发生用户的那个远程帧的问题了。对于没有赋初始值的全局变量,编译器只是分配RAM的地址,并不会修改RAM地址里的数据,那么这个变量的值就会依赖于MCU启动时RAM里的值了。为了避免未赋值的全局变量出现上述的问题,我们一般会在MCU启动代码里插入未赋初始值全局变量的清零操作,相当于做了一个未赋初始值的全局变量的初始化赋值操作。

像上面的案例,can_id申请的是局部变量,这又是什么情况呢?

因为MCU的RAM资源有限,为了最大限度的利用RAM,MCU会提前分配一块RAM区域,叫堆栈区,这块区域大家共用,对于只需要在某个函数内使用的变量,引入了局部变量概念。在开始执行该函数时,才从堆栈里分配地址给局部变量使用,函数执行结束后,该变量占用的RAM区域被堆栈回收,当下次再调用该函数,再重新分配RAM。因此对于局部变量,每次申请到的地址是不同的,该地址很可能是其它函数使用过并改写数据了的,因此每次函数调用时can_id.dummy的数据是不确定的。因为堆栈区里的数据是被反复利用的,即使MCU的初始化代码对堆栈区域做清零处理,也是没有意义的。

由此看来,局部变量在申请的时候赋一个初始值,是非常有必要的。虽然有时候赋初始值没有用,但是出现问题时常常是致命的,而且也是非常难以定位的,你可能觉得我的代码里后面肯定会赋值的,但是后面维护该项目的其他工程师并不一定意识到这一点。像类似上面的案例,我在其他用户当中也是经常见到的。因此软件工程师在编程的时候,一定要养成局部变量赋初始值的习惯。

来源:瑞萨MCU小百科
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • mcu
    mcu
    +关注

    关注

    147

    文章

    18605

    浏览量

    387026
  • CAN
    CAN
    +关注

    关注

    58

    文章

    3010

    浏览量

    471467
  • 编程
    +关注

    关注

    90

    文章

    3707

    浏览量

    96764
  • 变量
    +关注

    关注

    0

    文章

    615

    浏览量

    29370
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    智能显示模块怎么显示工程中给寄存器设置初始值?我想给变量一个上电的默认该如何设置?

    智能显示模块怎么显示工程中给寄存器设置初始值?我想给变量一个上电的默认该如何设置?
    发表于 12-06 10:20

    常用变量的介绍

    extern:用在全局变量上表示该变量在其他文件中已经定义;用在函数上作用同全局变量; static:用在全局变量上,和非静态全局变量相比,
    发表于 11-21 07:05

    C语言开发单片机为什么大多数都采用全局变量的形式?

    单片机的芯片资源从来都是 “精打细算” 的级别,CPU 主频普遍不高,RAM 总容量本就紧张,分给栈空间的更是少得可怜。要是像普通软件那样,依赖函数返回传递数据、频繁用局部变量周转,一来二去占用
    的头像 发表于 11-12 14:29 227次阅读
    C语言开发单片机为什么大多数都采用全局<b class='flag-5'>变量</b>的形式?

    按照芯来文档设置可以通过segger IDE debug了,但是没法看全局或者局部变量值,怎么解决?

    如题,按照芯来文档设置可以通过segger IDE debug了,但是没法看全局或者局部变量值,很麻烦。有遇到过解决了的吗?
    发表于 10-20 09:20

    120Ω的秘密:CAN总线终端电阻的重要性

    CAN总线作为一种广泛应用的工业通信协议,其终端电阻的作用不容忽视。本文将详细探讨CAN总线终端电阻的重要性及其通信中的关键作用。CAN总线终端电阻的重要性CAN总线终端电阻顾名思义就是夹在总线
    的头像 发表于 08-08 11:35 787次阅读
    120Ω的秘密:CAN总线终端电阻的<b class='flag-5'>重要性</b>

    PCBA加工必看!BOM表的重要性大揭秘

    一站式PCBA加工厂家今天为大家讲讲PCBA加工中BOM表的内容和格式有什么要求?BOM表PCBA加工中的重要性PCBA加工中,BOM表(物料清单)扮演着至关重要的角色,是连接设
    的头像 发表于 06-18 10:15 811次阅读

    分享原子钟科研领域的重要性

    ,以其无与伦比的精度和稳定性,成为了科研领域的核心设备之一。本文将深入探讨原子钟科研领域的重要性,揭示其如何推动科学技术的进步。1.天文学与宇宙研究天文学领域,
    的头像 发表于 05-15 15:55 497次阅读
    分享原子钟<b class='flag-5'>在</b>科研领域的<b class='flag-5'>重要性</b>

    连接器气密检测的重要性

    连接器气密是电气系统稳定运行的基石,尤其严苛环境下至关重要。精诚工科作为气密检测领域深耕多年的专家,为您提供专业、高效的连接器气密
    的头像 发表于 03-17 11:01 600次阅读
    连接器气密<b class='flag-5'>性</b>检测的<b class='flag-5'>重要性</b>

    PCB拼板设计全解析:重要性、优势与应用实践

    一站式PCBA智造厂家今天为大家讲讲PCB拼板设计的重要性表现哪些方面?PCB拼板设计的基本概念及其重要性电子制造行业,SMT贴片工艺中,PCB拼板设计是一项极为关键的步骤。通过优化PCB拼板
    的头像 发表于 03-13 09:35 1073次阅读
    PCB拼板设计全解析:<b class='flag-5'>重要性</b>、优势与应用实践

    ADS1298 CONFIG2读取初始值不正常是什么原因引起的?

    你好,我从贵公司申请了几片ADS1298的芯片,使用后发现以下问题:1。芯片ID,CONFIG2读取初始值不正常2。前四个通道控制寄存器读写正常,后四个通道寄存器无法读写,请问是否出现过类似情况,望尽快回复,谢谢
    发表于 02-13 08:02

    构建综合指挥调度系统的重要性

    构建综合指挥调度系统的重要性不言而喻,它对于提升应急响应速度、优化资源配置、加强跨部门协作、提高决策效率和确保公共安全等方面都具有至关重要的作用。以下是古河云科技构建综合指挥调度系统重要性的几个关键方面:
    的头像 发表于 02-06 16:56 880次阅读

    TLC5615芯片输出的初始值是不是为0?

    TLC5615芯片输出的初始值是不是为0,还有为什么我的5615芯片我给了数据进入要么就是输出的0V要么就是输出的4.8或者5V
    发表于 01-20 09:25

    EE-88:使用21xx编译器C中初始变量

    电子发烧友网站提供《EE-88:使用21xx编译器C中初始变量.pdf》资料免费下载
    发表于 01-13 15:54 0次下载
    EE-88:使用21xx编译器<b class='flag-5'>在</b>C中<b class='flag-5'>初始</b>化<b class='flag-5'>变量</b>

    电桥电子测试中的重要性

    电桥电子测试中的重要性体现在多个方面,以下是详细的分析: 一、精确测量电参数 电桥作为一种精密的测量工具,能够精确测量电阻、电容、电感等电参数。
    的头像 发表于 01-09 10:03 1437次阅读

    PCB板元器件点胶加固的重要性

    PCB板元器件点胶加固的重要性PCB板元器件点胶加固电子制造过程中起到了至关重要的作用,其重要性主要体现在以下几个方面:一、提高机械强度点胶加固可以显著降低电子元件的翘曲和变形现象,
    的头像 发表于 12-20 10:18 2418次阅读
    PCB板元器件点胶加固的<b class='flag-5'>重要性</b>