• nordic __noinit__变量使用


    Noinit RAM是啥,用来做啥?

    Noinit RAM,故名思意就是未被初始化的变量,我们编程的时候也知道,如果定义了一个常规的变量,一般编译器都会将其初始化成固定数值(一般是0xFF),系统每次复位的时候都赋值为一个固定的初始值。

    但是有些场景下我们需要一些特定变量,这些变量在系统复位后也能保持复位前的值,不发生改变,Noinit RAM有用的地方就在这里。

    应用场景的一些探讨:

    • 在某些不掉电场景下代替flash存储达到变量的保持功能

    这个功能可以配合flash存储,在短期内以Noinit RAM保持数据,在关键节点再将数据写进flash,以达到减少flash擦写次数的操作次数(特别是Nordic在协议栈操作下,flash写操作容易失败的情况下)。

    • 系统的DEBUG定位

    系统出现硬件错误的时候往往会进入到harfault中断服务线程,此时可以将系统进入harfault前的PC指针和一些详细的DEBUG信息写入Noinit RAM保存起来,等到复位启动后也可以将错误的DEBUG信息拿出来分析。

    • 模拟RTC实时时钟的可记忆寄存器

    这个用法下,RTC几乎可以不受复位的影响。

    • 防止某些需要保持的数据在复位下不丢失

    如果没有任何flash存储方式,可以尝试使用Noinit RAM代替其功能,在某些场景很实用

    • 检测一个系统是否是人为复位还是意外硬件复位

    人为复位之前,Nonit RAM写入某个非0xff的特定值,如果是人为操做复位,则复位后的变量是对应的特定值。如果是意外硬件复位,则就可以通过Nonit RAM检查出来

    Noinit RAM的配置:


    注:根据MCU本身的RAM地址去设置,本文是以nRF52832为例

    RAM Start地址:0x20003AB8 RAM Stop地址:0x20010000 (协议栈已经占0x3AB8)

    Start地址+IRAM1 Size = IRAM2地址;

    IRAM2地址+IRAM2 Size = Stop地址;

    程序使用:

    //建议将Noinit RAM打包成一个结构体操作,就不需要定义多个__attribute__地址了,兼容性好
    
    //NoInit掉电保持数据
    typedef struct 
    {
    	uint32_t wake_flag;                                    
    	uint32_t circle_count;                                 
    	uint8_t  last_battery_level;                          
    	uint16_t last_battery_value;                          
    } noinit_data_t; 
    
    
    %将RAM映射到0x2000FFF0地址,也就是Noinit RAM部分
    #define __noinit__ __attribute__((at(0x2000FFF0)))   
    __noinit__ noinit_data_t noinit_data;
    
    
    int main()
    {
        if(noinit_data.wake_flag == 0xff)
        {
            //掉电复位,需要初始化一次数据
            noinit_data.circle_count = 0;
        }
        else if(noinit_data.wake_flag == 0x01)
        {
            //人为复位
        }
        while(1)
        {
           //无需初始化,直接++
            noinit_data.circle_count++;
        }
    }

    特别注意:

    对于Nordic来说,量产产品往往会有SoftDevice+BootLoader+APP三个部分,此时必须将BootLoader和APP的工程Noinit RAM设置设置一致才行,否则系统先运行BootLoader再跳转到APP,可能会发生不可控的事情

  • 相关阅读:
    C++ Primer注意事项11_运算符重载_算术/关系运算符_下标运算符
    android最新的工具DateHelper
    ssh否password登陆server
    atitit.设计模式(2) -----查询方式/ command 总结
    采用Eclipse中间Maven构建Web项目错误(一)
    dm8148 jpeg编解码器测试
    C++ 结构体和类的区别
    C++ const
    C++中的inline函数
    C++ 模板类demo
  • 原文地址:https://www.cnblogs.com/qingyunboke/p/14011990.html
Copyright © 2020-2023  润新知