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

    文章

    20148

    浏览量

    247128
  • C语言
    +关注

    关注

    183

    文章

    7642

    浏览量

    144608
  • static
    +关注

    关注

    0

    文章

    34

    浏览量

    11045
  • 初始化
    +关注

    关注

    0

    文章

    51

    浏览量

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

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    什么是‍‍volatile

    volatile是个类型修饰符(type specifier)。 volatile的作用是作为指令关键字,确保本条指令不会因编译的优化省略,且要求每次直接读值。 volatil
    发表于 11-25 06:36

    串口通信基石:Air8000下Modbus RTU串口初始化详解!

    的RTU通信搭建牢固无忧。 、MODBUS 概述 Modbus 是一种广泛应用于工业自动领域的串行通信协议,由 Modicon 公司(现为施耐德电气旗下)于 1979 年推出,主要用于可编程逻辑控制
    的头像 发表于 10-28 16:33 1440次阅读
    串口通信基石:Air8000下Modbus RTU串口<b class='flag-5'>初始化</b>详解!

    NVMe高速传输之摆脱XDMA设计33:初始化功能验证与分析

    本文主要交流NVMe设计思路,本博客已给出相关博文五十多篇,希望对初学者有定作用 初始化功能主要实现 PCIe 链路设备的初始化配置和 NVMe
    发表于 10-08 08:02

    如何保持SRAM的状态,并在芯片复位时不初始化

    如何保持SRAM的状态,并在芯片复位时不初始化
    发表于 08-25 06:09

    GraniStudio:IO初始化以及IO资源配置例程

    IO资源配置.gsp文件,点击打开,完成导入。 2.功能说明 实现连接格拉尼控制IO块以及配置输入输出IO点。 2.1通过初始化IO算子连接格拉尼控制IO块,导入工程自动进行连接。 2.2 通过IO配置算子输出配置的IO表。
    的头像 发表于 08-22 17:34 746次阅读
    GraniStudio:IO<b class='flag-5'>初始化</b>以及IO资源配置例程

    GraniStudio:初始化例程

    说明 通过初始化运控板卡算子连接格拉尼总线型运控卡,导入工程自动进行连接,此算子为使用运控控制板卡的第项操作,后续运控算子需引用其输出板卡对象才可使用。 3.异常处理 当手动执行初始化
    的头像 发表于 08-22 16:45 705次阅读
    GraniStudio:<b class='flag-5'>初始化</b>例程

    如何保持SRAM的状态并在芯片复位时不初始化

    如何保持SRAM的状态,并在芯片复位时不初始化
    发表于 08-21 07:17

    定义IO初始化结构体

    由上述IOPORT相关功能的枚举类型我们可以知道,在对IOPORT模块进行初始化时需要根据情况配置它们。因此我们定义个IOPORT初始化的结构体类型IOPORT_Init_t,它的成员包括了由上述所有枚举类型所声明的
    的头像 发表于 07-16 16:26 1107次阅读

    NVMe高速传输之摆脱XDMA设计之十:NVMe初始化状态机设计

    设备控制可以正常处理指令,然后跳转到DONE状态。 DONE:NVMe配置初始化完成状态,该状态表示NVMe配置初始化过程正常完成,当复位
    发表于 07-05 22:03

    NVMe高速传输之摆脱XDMA设计之七:系统初始化

    系统复位退出后 1 秒时如果 LinkUp 信号仍为低电平, 则断言为链路训练失败, 初始化流程终止。 如果 LinkUp 为高电平, 此时用户可通过系统控制模块启动 PCIe 初始化
    发表于 07-04 09:14

    IM 系列设备过载保护机制下界面初始化中断的底层逻辑与解决方案

    、过载保护机制与界面初始化的关联基础 IM 系列设备的过载保护机制是保障设备安全运行的核心功能,其通过传感实时采集设备运行参数,如电流、电压、温度、系统资源占用率等。旦这些参数超
    的头像 发表于 06-27 09:58 366次阅读

    使用jlink连接mcu查看日志,偶发重新初始化,部分线程未退出,变量错位怎么解决?

    使用jlink连接mcu查看日志,偶发重新初始化,部分线程未退出,变量错位。 串口1的线程是main最后面。 未见初始化打印,就已经发送数据了。并且发送的数据不对。感觉是重新
    发表于 03-07 07:19

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

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

    OMAP5912多媒体处理器初始化参考指南

    电子发烧友网站提供《OMAP5912多媒体处理器初始化参考指南.pdf》资料免费下载
    发表于 12-17 16:20 0次下载
    OMAP5912多媒体<b class='flag-5'>处理器</b><b class='flag-5'>初始化</b>参考指南

    segger编译初始化问题

    的图; 2.第二张图是该变量文件中的所有操作,第行是初始化,该行代码初始化部分最后
    发表于 12-09 18:06