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
    +关注

    关注

    146

    文章

    16017

    浏览量

    343632
  • CAN
    CAN
    +关注

    关注

    56

    文章

    2467

    浏览量

    459246
  • 编程
    +关注

    关注

    88

    文章

    3440

    浏览量

    92401
  • 变量
    +关注

    关注

    0

    文章

    595

    浏览量

    28112
收藏 人收藏

    评论

    相关推荐

    局部变量超出堆栈范围,想把占用内存多的变量申请在全局如何做?

    目前局部变量超出堆栈范围,现在想把占用内存多的变量申请在全局,如何做
    发表于 03-20 08:03

    C语言中的三种形式变量

    局部变量是在一个函数、代码块内部声明的变量,只能被该函数或者代码块内部应用。局部变量在函数之外不可用。
    发表于 03-11 17:34 154次阅读
    C语言中的三种形式<b class='flag-5'>变量</b>

    TC275在内存分段预警处理之后,设置的全局变量初始值不正确怎么解决?

    大家好想问一下,tc275里,自己地图文件里定义有了新的存档段,又设置了首地位置,段内对象可写,4字节对齐。但是在内存分段预警处理之后,设置的全局变量初始值不正确,板子上电后会给出一个随机
    发表于 01-22 06:40

    LTC2943初始化的时候要如何确定Qlsb的初始值呢?

    最近公司使用一款LTC2943的库仑计,但是初始化的时候要如何确定Qlsb的初始值呢?或者可以提供一个STM32作为MCU的例程最好。
    发表于 01-04 06:47

    C语言编程时,各种类型的变量该如何初始化?

    C语言编程时,各种类型的变量该如何初始化? 在C语言中,每个变量都需要在使用之前进行初始化。初始
    的头像 发表于 12-07 13:53 583次阅读

    for循环里的变量局部变量

    对于一个普通for循环而言,循环变量局部变量。在大多数编程语言中,循环变量只在循环内部的作用域中可见。换句话说,循环变量的声明和赋值仅在循
    的头像 发表于 11-23 14:50 1000次阅读

    嵌入式全局变量初始化原理详解

    全局变量初始值,是在哪里赋值的?
    的头像 发表于 10-27 10:15 652次阅读
    嵌入式全局<b class='flag-5'>变量</b>的<b class='flag-5'>初始</b>化原理详解

    MDK的窗口调试能显示局部变量吗?

    MDK的窗口调试能显示局部变量
    发表于 10-19 07:41

    单片机程序里频繁读写的变量放在全局或静态局部变量会更好吗?

    看看我的理解对不对 1.全局变量 静态局部变量 栈 堆 全都会放在RAM中 2.函数 uint32_t fun(uint32_t arg){ static uint32_t i
    发表于 10-16 08:05

    MCU程序中怎么防止局部变量函数运行完不丢失数据?

    MCU程序中怎么防止局部变量函数运行完不丢失数据
    发表于 10-10 06:04

    MCU中局部变量的作用域是什么?

    MCU中局部变量的作用域是什么
    发表于 10-09 08:51

    局部变量超出堆栈范围,如何把占用内存多的变量申请在全局?

    目前局部变量超出堆栈范围,现在想把占用内存多的变量申请在全局,如何做
    发表于 08-08 06:29

    static的全局变量局部变量的使用,看完你就懂了

    时间效率。 2. C/C++ 中static的作用2.1 总的来说 (1)修饰变量的时候,static 修饰的静态局部变量只执行初始
    发表于 06-27 08:54

    ozone调试双核例程的hello, 无法查看局部变量如何解决?

    断点, 进入函数内, 函数内存在局部变量; 打开 local data栏, 栏目内没有任何变量, 将鼠标悬浮在变量源码上, 提示信息out of scope. 如何解决?
    发表于 05-26 06:04

    Labview如何创建波形图的X轴的局部变量

    本帖最后由 jf_94210865 于 2023-5-9 12:11 编辑 一个很简单的问题,如何创建波形图X轴的局部变量? 我正在编写一个列车模拟运行程序,用到了波形图,现在需要导入一段线路
    发表于 05-09 12:06