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/MSP432E401Y: Unable to write variables to flash memory after allocation

Part Number: MSP432E401Y

Tool/software: TI C/C++ Compiler

I am attempting to create an object in the flash memory which records information about the reset history of the microcontroller. I want this object, of class ResetInfoContainer (a simple class which has integer and boolean members), to persist in memory through the resets so that it can be accessed on startup to aid in diagnosing any system problems. While I am able to allocate memory to store my ResetInfoContainer object in the flash memory, I am unable to assign any values to it without my program crashing. 

I'll outline below the steps I have taken in order to try and implement this feature, in the hope that it's useful in identifying the problem in my code or my understanding. 

In the `linker.cmd` file, I added an instruction to create a RESETINFO section in the memory (at address 0x000F0000 with length 0x00010000, though these values are arbitrary). In my code I then attempted to instruct the compiler to store my ResetInfoContainer object in the RESETINFO section using the instruction: `#pragma DATA_SECTION(".resetinfo") \n ResetInfoContainer reset_info_container`. This works to some extent. The memory browser indicates that some memory has been allocated at 0x000f000 for the reset_container_object, however when I run the debugger, I am taken immediately to the `abort()` function in `exit.c`. (Confusingly I also get a warning that my #pragma instruction is unrecognised, but I can't make sense of this given that the memory allocation seems to have worked.)

With the above unsuccessful, I tried instead using the the location pragma; I used the instruction: `#pragma LOCATION(0xf0000) \n ResetInfoContainer reset_info_container;` to attempt to initialise this object in the RESETINFO section (though through inelegant hard-coding of the memory address). Very similar to above, the memory for the object seems to have been allocated, but no values can be stored in it without the program crashing. 

In both cases when the program fails, the decoded exception in the Hwi module (in the RTOS Object View) reads: "Hard Fault: FORCED: BUSFAULT: PRECISERR.Data Access Error. Address = 0xf0000." I thought that this could be a problem with the write access of the flash memory, but when I retrieve the flash protection status of the section at 0x000f0000 it returns `FlashReadWrite`.

I'm unsure how to continue to look for solutions to this problem, so any help would be much appreciated! 

I based my code off the solution given in this forum thread - - with some syntactic alterations for the C++ compiler, described here - .

Here are the files involved in the problem: 

TIForumFiles.zip

  • Hello Hugo,

    Based on your description, I would expect the linker script to look like below:

    Memory
    {
       FLASH (RX) : origin = 0x00000000, length = 0x000F0000
       RESETINFO (RX): origin = 0x000F0000 , length = 0x00001000
       SRAM (RWX) : origin = 0x20000000, length = 0x00040000
    }
    
    SECTIONS
    {
       .intvecs:   > 0x00000000
       .text   :   > FLASH
       .const  :   > FLASH
       .cinit  :   > FLASH
       .pinit  :   > FLASH
       .init_array : > FLASH
    
       .resetinfo : > RESETINFO
    
       .vtable :   > 0x20000000
       .data   :   > SRAM
       .bss    :   > SRAM
       .sysmem :   > SRAM
       .stack  :   > SRAM
    }

    and your application code to look like:

    #pragma DATA_SECTION(reset_info_container, ".resetinfo")
    const unsigned int reset_info_container;

    Is this what you did? Is it not working?

    Thanks,

    Sai

  • Hello Sai,

    That matches pretty closely what I've got, with just a few differences.

    1. I've included a 'write' (W) attribute in my memory range assignment. I assumed that this would be necessary to allow me to update variables located there.
      RESETINFO (RWX): origin = 0x000F000, length = 0x00001000

    2. I've used the C++ syntax for the #pragma, so it looks like this instead.
      #pragma DATA_SECTION(".resetinfo")
      ResetInfoContainer reset_info_container;

      Apparently the C++ compiler then allocates the space for the next-declared variable.

    3. I'm storing my own data type, ResetInfoContainer, which is a class containing some integers and booleans. (I don't think that this should be a problem, but I thought it worth noting that it's not a simple primitive.

    4. I haven't made my object `const`, because I need to be able to modify its values during program execution. 

    I'm hoping that my problem is lurking somewhere in these points! 

    Thanks.

  • Hello Hugo,

    Just to calrify, since this is a Flash location, you cannot update this location like how you would update a RAM location. You will need specific APIs (driverlib APIs to write to Flash) to write to Flash. I would suggest to keep the (RX) option in linker script.

    Also I am not sure how the syntax of the Pragma works in C++ . Can you try the C pragma (as there are examples in the SDK) and once it works, equivalent C++ pragma can be employed.

    Thanks,
    Sai
  • Hi Sai,

    Apologies for the delayed response. 

    Okay, I think I was misunderstanding exactly what the #pragma DATA_SECTION was doing. Am I correct in saying that all it is doing is allocating a space in a specified memory section for a variable (but giving that allocated space no special treatment)? 

    I'm comfortable using the flash API but, I'm still confused about how to store a non-primitive data-type in the flash memory. FlashProgram() requires a uint32_t pointer as an argument - does this mean that only uint32_t integer arrays can be stored in the flash (and that I have to create my own functions to convert back and forth between my ResetInfoContainer class and the array to be stored in flash memory)? If this is the case, I don't understand why I would bother allocating space for my ResetInfoContainer in the first place, when what I really need to be allocating for is the converted uint32_t array.

    Thanks,

    Hugo

  • Hello Hugo,

    Hugo Umbers said:
    Am I correct in saying that all it is doing is allocating a space in a specified memory section for a variable (but giving that allocated space no special treatment)?

    Yes! That's my understanding too.

    Hugo Umbers said:
    If this is the case, I don't understand why I would bother allocating space for my ResetInfoContainer in the first place, when what I really need to be allocating for is the converted uint32_t array.

    What you say makes sense. Allocate a space the size of ResetInfoContainer to store data using Driverlib Flash APIs. Create your own mechanism to convert this data to the Structure you need.

    Thanks,

    Sai

**Attention** This is a public forum