This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Compiler/CC1352P: Retain memory (SRAM) contents on reset

Part Number: CC1352P

Tool/software: TI C/C++ Compiler

Hi

I have two application images stored on internal flash, and can successfully switch between them (by updating vector table address, resetting SP and jumping to secondary ResetISR). For that to work though, it needs to happen immediately after reset, first thing in main(). Reset is done using SysCtrlSystemReset().

As a means for "communicating" between these images, I would like to set a value in RAM before reset, and then be able to read that value from RAM after reset. I have tried several things to prevent standard initialization, but none work:

  1. #pragma PERSISTENT(myvar)
  2. #pragma NOINIT(myvar)
  3. #pragma DATA_SECTION(myvar, ".resetvar") where .resetvar is a section marked as type=NOINIT or type=NOLOAD
  4. Reducing the RAM size in the MEMORY region setup and directly writing/reading a value outside the declared MEMORY region, but that too seems to be zeroed.
  5. Setting --zero_init=off in the linker script.

The first three all seem to affect the placement in memory as expected (and the section is marked as UNINITIALIZED in the map file), but the memory location is always zeroed anyway.

I tried breaking on ResetISR (which I understand calls c_int00 or equivalent) and it seems like memory is already zeroed at that point.

So at this point I am wondering if CC1352P always zeroes its entire memory before every boot? Indeed, the datasheet seems to suggest this (although it could just be referring to default behaviour): "6.5 Memory: System SRAM is always initialized to zeroes upon code execution from boot".

Is it possible to configure CC1352P to retain selected variable in RAM memory through a reset?

  • Hi,

    Yes, CC1352P do always clears the entire memory (set to zero) before every boot and it is not possible to bypass this.

    I do not know if this fits your setup but have you looked into the DMM (Dynamic Multi-protocol Manager)?

    Best Regards,

    R.M

  • Could you use NV memory?
  • Thanks for the suggestions.

    The intention was to have a seperate ota-capable bootloader and an app, and let the bootloader set a magic value in memory when it wants to attempt to run the other app-image. After reset then the bootloader will see the magic value, clear the magic value, optionally increase an attempt-counter, and then jump straight into the app. That way the bootloader won't immediately jump back into the app if the app hangs or a reset is otherwise triggered. It could instead trigger some diagnostics, re-download app firmware, revert to an older firmware, or just stay in bootloader/ota-mode to wait for a newer version of app firmware to be received by the radio.

    The key is that the magic value (or any flag really) can be cleared before jumping into the app. It seems like the jump has to happen before RTOS is started, which I think rules out erasing/clearing anything in NV memory? If it is possible to make the jump after erasing flash (or more generally after running RTOS/peripherals) then that would help. So far I haven't managed to jump successfully after starting RTOS though. Usually it just hangs. If I disable interrupts first then it gets a bit further but eventually hangs.

    Is there anything else that might be used as an alternative to RAM? All I really need is a single bit. Registers could work, but it seems like they are cleared as well. I tried using reset source to check warm reset vs system reset, but haven't been able to trigger a warm reset. I'm also worried that other things (watchdog) would trigger warm reset and therefore send the wrong signal/intention.
  • Hi,

    I do not think using RAM or registers will work for you since they are both cleared when reset.
    You could write/erase internal flash before RTOS starts (use driverlib) but the problem there is that you can't erase a single bit or byte, you need to erase a entire sector. What about having a small external EEPROM?

    Best Regards,
    R.M
  • I'll try to use driverlib directly with internal flash.

    By the way, should it be possible to jump into a different image after RTOS is running, without a system reset? Is there something extra that should be done to "reset" MCU state to defaults before making the jump?

    Here's my current "jump" routine:

    HWREG(NVIC_VTABLE) = 0x20000;
    __asm(
          " movw    r0, #0x0000  \n"
          " movt    r0, #0x0002  \n" // r0 is now 0x20000, beginning of app firmware vector table.
          " ldr     sp, [r0]     \n" // sp is now *(0x20000), pointing stack pointer at end of sram.
          " ldr     r0, [r0,#4]  \n" // r0 is now *(0x20004), address of ResetISR which prepares memory before starting main().
          " bx      r0           \n" // Jump to r0, ResetISR.
    );

    I tried disabling interrupts (CPUcpsid) before the jump and reenabling after, and that helped a bit: The app image started partially but then froze every time. I haven't had a chance to debug that yet but assume it has something to do with some preconditions not being satisfied when MCU has not been reset properly before start up.

  • Using driverlib directly before RTOS starts seems to work well, and still allows jumping into app firmware after. I cache in the existing sector data before erasing and rewriting. It is kind of heavy handed, but it works. Thanks for the suggestion :)

  • Good that you where able to resolve this.

    Best Regards,
    R.M