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.

Custom Memory Sections (Tiva Processors)

Hey guys, as part of a project I'm working on, I need to be able to store some custom data at the start of a Tiva processor's internal Flash memory, isolated from regular variables and program data. After doing a bit of research, it seems like memory sections are the best way to accomplish this. I gave it a crack, but it doesn't seem to be working. Here's what I did:


In the .cmd file that my program is using, I modified the SECTIONS block to the following:

SECTIONS
{
    .intvecs              :   > 0x00000000
    .mySection            :   > FLASH
    .text                 :   > FLASH
    .const                :   > FLASH
    .cinit                :   > FLASH
    .pinit                :   > FLASH
    .init_array           :   > FLASH

    .vtable :   > 0x20000000
    .data   :   > SRAM
    .bss    :   > SRAM
    .sysmem :   > SRAM
    .stack  :   > SRAM
}

All I really did was add a section labeled .mySection to the flash. From my understanding of sections, this should cause variables mapped to .mySection to be located between the end of the interrupt vectors and the start of the .text section. I'm not confident that this is how sections are defined, and I can't find any documentation for modifying these .cmd files, so any help with this would be appreciated.


To test if my section works, I added a C file to my project's root with the following contents:

typedef struct exampleStruct {
	int a;
	int b;
} exampleStruct;
#pragma DATA_SECTION(myExample, ".mySection")
exampleStruct myExample;

From my understanding, this should define a structure, and then place the instance of the structure with the symbol myExample in the .mySection section of memory. Also, I added the following as a simpler test in case I messed up the way that structures should work for this:

#pragma DATA_SECTION(arrayA, ".mySection")
int arrayA[20];

After doing this, my project builds without any problems. To see if my test worked, I used some of the cg_xml tools to analyze the .out file generated by my build. Specifically, I ran "ofd6x -x app.out | sectti", which printed out the memory breakdown of the binary. All of the regular sections from the SECTION block are there, but it jumps right from .intvecs to .text without showing anything for .mySection.

I looked at the generated linkInfo.xml file as well, and it contained the following:

      <logical_group id="lg-4" display="no" color="cyan">
         <name>.mySection</name>
         <run_address>0x0</run_address>
         <size>0x0</size>
         <contents>
         </contents>
      </logical_group>

From the looks of it, the linker knows that the section was added, but it thinks that it's empty. I'm guessing that the C file I added with the structure and the array is at fault here, but I'm not really sure why. My test with the array is more or less copied and pasted from Example 5-4 from section 5.9.6 in the "ARM Optimizing C/C++ Compiler v5.1" documentation, so I don't know what I need to change to get this to work.


If anyone has any ideas or input it would be very appreciated. Thanks.

  • Matthew Kipper said:
    From the looks of it, the linker knows that the section was added, but it thinks that it's empty. I'm guessing that the C file I added with the structure and the array is at fault here, but I'm not really sure why.

    If the variables aren't referenced in the program the the linker may remove them. To make the linker keep the variables you need to either:

    a) Reference the variable in the program.

    b) Use a RETAIN pragma. e.g.:

    #pragma RETAIN (myExample)
    #pragma RETAIN (arrayA)

    Matthew Kipper said:
    I'm not confident that this is how sections are defined, and I can't find any documentation for modifying these .cmd files, so any help with this would be appreciated.

    Have you seen ARM Assembly Language Tools User's Guide, which documents the linker?

  • Matthew Kipper said:
    I need to be able to store some custom data at the start of a Tiva processor's internal Flash memory,

    Really - at the "start" - is that well designed/considered?  Is not the "start" of flash memory a "hubbub" of MCU activity?

    Suggest location of such custom data to the less active, "end" section of flash memory - to avoid unnecessary & unwanted complications.

    Chester's code comments are (as usual) most excellent...

  • cb1_mobile said:

    Really - at the "start" - is that well designed/considered?  Is not the "start" of flash memory a "hubbub" of MCU activity?

     

    Agreed and I go a bit further.  What is the justification for fixing the location at all?  The only case that I could justify is if the application binary needed to be manipulated outside of the micro.  Even in that case there are ways around the necessity although it may be more convienient not to use them.

    On another note.  This question is tool chain specific.  You have not mentioned the tool chain you are using.

    Robert

  • In addition to the excellent comments already provided I also noticed that you have attempted place a non-constant structure in a read only area of memory.  I don't know how or if the linker will rectify this inconsistency.  I would also declare the struct as const just to be sure.

  • Thanks for the replies guys.

    Chester, I feel pretty dumb for not realizing that the linker was probably optimizing out my code. For some reason I felt like defining a memory section would somehow cause an exception to this but that doesn't make any sense in retrospect. Thanks for the answer.

    cb1_mobile said:

    I need to be able to store some custom data at the start of a Tiva processor's internal Flash memory,

    Really - at the "start" - is that well designed/considered?  Is not the "start" of flash memory a "hubbub" of MCU activity?

    Suggest location of such custom data to the less active, "end" section of flash memory - to avoid unnecessary & unwanted complications.

    Chester's code comments are (as usual) most excellent...

    [/quote]

    I understand that it's a little strange to insert something before everything else in flash, but are there any technical problems that could stem from this? From my understanding, one of the purposes of memory sections is to abstract absolute memory locations from the structure of the microcontroller's memory where possible. If I choose to insert a fixed-length section between the interrupt vectors and the rest of the flash, shouldn't the compiler/linker be able to take care of this transparently? I agree that this doesn't necessarily make the most sense and I'm still thinking about changing this structure, but I'm just curious if there are any specific problems that this may cause.

    Robert Adsett said:

    Really - at the "start" - is that well designed/considered?  Is not the "start" of flash memory a "hubbub" of MCU activity?

     

    Agreed and I go a bit further.  What is the justification for fixing the location at all?  The only case that I could justify is if the application binary needed to be manipulated outside of the micro.  Even in that case there are ways around the necessity although it may be more convienient not to use them.

    On another note.  This question is tool chain specific.  You have not mentioned the tool chain you are using.

    Robert

    [/quote]

    That's more or less the reasoning. For certification purposes, each firmware release needs release information and a form of corruption detection (e.g. CRC or hash) which is accessible from outside the micro. My background is in networking, so my natural inclination was to insert a header (including the size of the firmare release) at the start of the memory, then place the "payload" (the program) in the middle and the error-detection code at the end. If the release information was placed at the end of the flash, it would need to be RIGHT at the end (which is a fine option) since the firmware releases will change in size. To me, it felt more natural to put the header first, but as I mentioned, I'm not locked into this or anything.

    I'm using the standard TI toolchain for the Tiva processor. I'm not really sure if there are any differences between first-party toolchain options for the Tiva processors, but I'm just using the tools bundled with CCSv6.

    INTEGRIS Dexter said:

    In addition to the excellent comments already provided I also noticed that you have attempted place a non-constant structure in a read only area of memory.  I don't know how or if the linker will rectify this inconsistency.  I would also declare the struct as const just to be sure.

    Yeah, this will be constant when implemented, I just didn't think about this discrepancy when coming up with my simple test.

    Thanks again for the replies everybody.

  • Matthew Kipper said:
    That's more or less the reasoning. For certification purposes, each firmware release needs release information and a form of corruption detection (e.g. CRC or hash) which is accessible from outside the micro

    A few notes:

    • Accessible from outside the micro is a little vague.  If you do not need to read the binary file but rather read this via a communications channel there is still no reason to use a fixed location.
    • Application CRC can cover the whole memory area so size becomes moot.
    • You have a number of unused interrupt vectors available.  They can either contain the information or point to it.

    Robert