About NRF52832 used the noinit section but encountered the problem of RAM reset

I'm using SDK17.0.2

I need to keep a noinit variable in memory so that I have the correct flag when I execute the DFU. So I use the following method, but it doesn't seem to work

I defined a noinit area for the end of memory in the .sct file

LR_IROM1 0x00026000 0x0005A000  {    ; load region size_region
  ER_IROM1 0x00026000 0x0005A000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  RW_IRAM1 0x20002C00 0x0000D3FC  {  ; RW data
   .ANY (+RW +ZI)
  }
  NOINIT 0x2000FFFC UNINIT 0x00000004  {
   .ANY (NOINIT)
  }
}

At the same time, the variables are mapped to the address in the main program

uint32_t OTA_mode 
    __attribute__((section("NOINIT")))
    __attribute__((used));

Then I can see the variable location in the .map file

    HEAP                                     0x2000bfa8   Section     8192  arm_startup_nrf52.o(HEAP)
    Heap_Mem                                 0x2000bfa8   Data        8192  arm_startup_nrf52.o(HEAP)
    STACK                                    0x2000dfa8   Section     8192  arm_startup_nrf52.o(STACK)
    Stack_Mem                                0x2000dfa8   Data        8192  arm_startup_nrf52.o(STACK)
    __initial_sp                             0x2000ffa8   Data           0  arm_startup_nrf52.o(STACK)
    NOINIT                                   0x2000fffc   Section        4  main.o(NOINIT)
    __tagsym$$used                           0x2000fffc   Number         0  main.o(NOINIT)

In the .map file, the address belongs to the Noinit zone

    Execution Region NOINIT (Exec base: 0x2000fffc, Load base: 0x00052730, Size: 0x00000004, Max: 0x00000004, ABSOLUTE, UNINIT)

    Exec Addr    Load Addr    Size         Type   Attr      Idx    E Section Name        Object

    0x2000fffc   0x00052730   0x00000004   Data   RW            6    NOINIT              main.o

After that,I automatically increment the variables and print the values in the main program, with a 500ms delay, and do a soft reset

uint32_t OTA_mode 
    __attribute__((section("NOINIT")))
    __attribute__((used));
void main()
{
    log_init();
    OTA_mode += 1;
    NRF_LOG_INFO("ota_mode:0x%X", OTA_mode);
    NRF_LOG_INFO("REG32:0x%X", REG32(0x2000FFFC));
    NRF_LOG_PROCESS();
    NRF_LOG_PROCESS();
    nrf_delay_ms(500);
    NVIC_SystemReset();
}

Under normal circumstances, this variable should be self-incrementing. But the logs I actually got look like this

00> <info> app: ota_mode:0x1
00> 
00> <info> app: REG32:0x1
00> 
00> <info> app: ota_mode:0x1
00> 
00> <info> app: REG32:0x1
00> 
00> <info> app: ota_mode:0x1
00> 
00> <info> app: REG32:0x1
00> 
00> <info> app: ota_mode:0x1
00> 
00> <info> app: REG32:0x1
00> 
00> <info> app: ota_mode:0x1
00> 
00> <info> app: REG32:0x1
00> 
00> <info> app: ota_mode:0x1
00> 
00> <info> app: REG32:0x1

I'm guessing this piece of RAM is actually reset.  I hope I can get some revelations

Parents Reply Children
Related