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

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

3天内不再提示

一种修饰符能使变量在处理器复位而不被初始化

黄工的嵌入式技术圈 来源:黄工的嵌入式技术圈 2020-03-14 15:01 次阅读

先了解一下修饰符知识

修饰符是用于限定类型以及类型成员申明的一种符号。如C语言中常见的修饰符:

1.static静态修饰符:修饰变量,函数。作用域:变量仅仅在本文件可见,函数在本文件可以被调用;

2.extern声明修饰符:修饰变量,函数。修饰变量时候,变量的声明在外面;

3.const常量修饰符:修饰变量,函数。修饰变量时候,不能被重复赋值,只能放在只读段中;

4.volatile不稳定变量修饰符:这个变量不好翻译,在c中的作用大概有两点意思:A.表示变量是易失的,易变的;B.强制访存操作,防止编译器去优化,告诉编译器每次必须去内存中取值,而不是从寄存器或者缓存。

C++ JAVA中还有更多:

public公共访问修饰符、private私有访问修饰符、protected保护访问修饰符、friendly、abstract等。

了解了修饰符之后,看见本文标题就知道本文提供的那个修饰符对于变量来说是比较重要的。

之前写过一篇文章【CM3(STM32)内核复位与系统复位区别及应用】,讲述了系统和内核复位之后存在差异,其实主要就是说内核复位之后,芯片外设资源没有进行复位的操作。

而本文说的修饰符,修饰的变量位于RAM中,在默认情况下,编译器会将其变量存放在主RAM中,并在启动时对其进行初始化。而本文说的__no_init类型修饰符使编译器把变量放在非易失RAM区中,在启动时也不对它们进行初始化,也就是说__no_init在系统启动时不初始化变量。

什么情况下使用这修饰符使系统禁止变量的初始化?

看门狗复位的现场恢复,如果初始化了就完全不可恢复了。

Keil和IAR集成开发环境下,这个修饰符有所不同;Keil中不集成这个修饰符,需要配置; 而IAR中集成这个修饰符,可直接使用。

Keil中__no_init的配置和使用

在Keil中,__no_init不是集成在开发环境中,故需要配置,配置之后就可以使用了。

1.宏定义__no_init

#define __no_init __attribute__((zero_init))

2.在工程选项中配置__no_init

Project -> Options for Targets -> Target,里面右下有个NoInit,这个就是需要我们配置的区域(可设定某一区域);

3.使用方法

__no_init uint16_t Cnt_NoInit;

提示:不能初始化这个变量。

IAR中的__no_init

IAR中的“__no_init”是一个关键字,你会发现在使用这个修饰符之后,字体都是关键字颜色。

__no_init uint16_t Cnt_NoInit;

例程源代码下载与说明

代码下载地址:

http://pan.baidu.com/s/1hskScba

两个工程名称:

1.STM32F103ZE(Keil)_复位不初始化变量NoInit

2.STM32F103ZE(IAR)_复位不初始化变量NoInit

本文提供的例程是一个Demo比较简单,但具有实际意义。Keil和IAR工程实现的功能一样。

源代码:

__no_inituint16_t Cnt_NoInit;

uint16_t Cnt_Init = 100;

intmain(void)

{

System_Initializes();

printf("Start...\n"); //复位打印

while(1)

{

printf("Cnt_NoInit = %d\n", Cnt_NoInit); //打印变量

Cnt_NoInit++;

if(Cnt_NoInit > 1000)

{

Cnt_NoInit = 0;

}

printf("Cnt_Init = %d\n", Cnt_Init);

Cnt_Init++;

if(Cnt_Init > 1000)

{

Cnt_Init = 0;

}

LED_ON;

TIMDelay_Nms(500);

LED_OFF;

TIMDelay_Nms(500);

NVIC_SystemReset(); //系统复位

}

}

不初始化变量,则会打印如下消息:

Start...

Cnt_NoInit = 0

Cnt_Init = 100

Start...

Cnt_NoInit = 1

Cnt_Init = 100

Start...

Cnt_NoInit = 2

Cnt_Init = 100

Start...

Cnt_NoInit = 3

Cnt_Init = 100

如果Cnt_NoInit不被修饰成不初始化

uint16_t Cnt_NoInit;

uint16_t Cnt_Init = 100;

则会打印出如下信息

Start...

Cnt_NoInit = 0

Cnt_Init = 100

Start...

Cnt_NoInit = 0

Cnt_Init = 100

Start...

Cnt_NoInit = 0

Cnt_Init = 100

Start...

Cnt_NoInit = 0

Cnt_Init = 100

相信聪明的你,看了上面例子会明白为什么没有初始化的变量“Cnt_NoInit”在变化,而初始化了的“Cnt_Init”一直不变。

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

    关注

    68

    文章

    19155

    浏览量

    229040
  • C语言
    +关注

    关注

    180

    文章

    7597

    浏览量

    136117
  • static
    +关注

    关注

    0

    文章

    33

    浏览量

    10356
  • 初始化
    +关注

    关注

    0

    文章

    49

    浏览量

    11831
收藏 人收藏

    评论

    相关推荐

    Keil中变量不被初始化方法

    有些时候我们的应用过程中要求变量有连续性,或者现场保留,例如Bootloader跳转,某种原因的复位过程中我们有些关键变量不能被初始化
    的头像 发表于 08-30 11:47 519次阅读
    Keil中<b class='flag-5'>变量</b><b class='flag-5'>不被</b><b class='flag-5'>初始化</b>方法

    鸿蒙原生应用元服务开发-仓颉基本概念程序结构

    决定了变量初始化后其值还能否改变,仓颉变量也由此分为不可变变量和可变变量两类。 可见性修饰符
    发表于 08-13 10:57

    DSP复位地址不在0x20b00000导致仿真时初始化失败

    在对dsp仿真时,点击systeam reset后,复位地址不在0x20b00000,出现这种现象后,使用XDS560仿真仿真程序的初始化就会出问题,初始化失败,使用XDS100的仿
    发表于 08-12 09:56

    请问STM8S207如何让编译stvd+cosmic复位后不给这个变量初始化成0?

    ,上电时开始为0V,过会充满电为VCC),上电标志0则读出EEPROM数据,为1则为看门狗热复位不读EEPROM,变量value仍保持原数据继续计数。 我没有初始化但编译
    发表于 05-09 08:01

    浅析C语言中的变量修饰符

    修饰符类型51单片机采用哈佛结构。内存空间编址有重叠。可以不同总线上定义不同的变量KEILC51中定义了data、idata、xd
    的头像 发表于 04-15 08:10 533次阅读
    浅析C语言中的<b class='flag-5'>变量</b><b class='flag-5'>修饰符</b>

    鸿蒙ArkUI开发实战:制作个【简单计数

    `@Entry` 修饰符表示个页面的入口,它需要在 `main_pages.json` 配置才可以设备上正常显示, `@Component` 修饰符表示 `Index` 是
    的头像 发表于 04-08 18:05 567次阅读
    鸿蒙ArkUI开发实战:制作<b class='flag-5'>一</b>个【简单计数<b class='flag-5'>器</b>】

    stm32如何设置ADC初始化能使能改寄存位?

    配置ADC时开启了该选项,按理来说应该可以开启eoc中断,但在debug时我发现EOC中断标志位直为零,也就是说无法开启EOC中断。请问我该如何设置ADC初始化能使能改寄存
    发表于 04-07 06:13

    字符型、指针型等变量等该如何初始化

     对于数值类型的变量往往初始化为0,但对于其他类型的变量,如字符型、指针型等变量等该如何初始化呢?
    的头像 发表于 03-18 11:02 1250次阅读

    rtc时钟如何在启动后会不被初始化为默认值?

    请教个关于rtc的问题。 1.我发现我的rtc时钟根据例子,启动后会被初始化为默认值。 但是如果我想在软件复位或者看门狗复位的情况下,不
    发表于 02-21 06:08

    使用SEGGER Embedded Studio编译发现变量无法自动初始化

    使用SEGGER Embedded Studio编译发现变量无法自动初始化, 例如声明静态变量static uint8_t i = 0;这种写法i成了静态
    发表于 01-11 14:21

    labview运行后如何初始化

    LabVIEW是款强大的图形编程软件,在运行之前通常需要进行初始化操作。本文将详细介绍LabVIEW运行前的初始化过程,并提供了
    的头像 发表于 12-28 17:24 2472次阅读

    自动初始化机制原理详解

    自动初始化机制是指初始化函数不需要被显式调用,只需要在函数定义处通过宏定义的方式进行申明,就会在系统启动过程中被执行。这篇文章就来探索下其中的奥秘, 简单理解其原理!
    的头像 发表于 12-16 09:33 961次阅读
    自动<b class='flag-5'>初始化</b>机制原理详解

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

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

    嵌入式软件开发常用的关键字和运算

    volatile是个特征修饰符,提醒编译它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,告诉编译
    的头像 发表于 12-04 12:22 561次阅读

    实战经验 | Keil、IAR、CubeIDE 中变量不被初始化方法

    关键词:不被初始化,编译环境 目录预览 1、前言 2、IAR 实现变量初始化方法 3、Keil 实现变量
    的头像 发表于 11-24 18:05 3890次阅读