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.

CC1310: Placing a variable at specific address in FLASH

Part Number: CC1310
Other Parts Discussed in Thread: SIMPLICITI

Hi,

Sometime ago I created a topic asking for help to place a variable at a specific address in FLASH in the SECTIONS.

I wasn't able to do get it working.

I tried to continue the discussion in the original topic, but it seems locked. Here is the original content:

Can someone help?

  • I found other example that places a section in a specific address:
    stackoverflow.com/.../how-to-place-constant-at-specific-address-with-ld-linker-command-file

    But the syntax ".section_name address: > FLASH" doesn't works.
    I am getting the errors:
    expecting output section, GROUP, or UNION instead of ":"
  • Hi,

    every toolchain uses a different syntax for linker scripts. You haven't written it, but I assume you are using the TI toolchain. Please consult the TI CGT toolchain manual. It is surprisingly good.

    For TI CGT and IAR there is also the possibility to use pragmas. Our board files show how to do that:

    #define NVS_REGIONS_BASE 0x1B000
    #define SECTORSIZE       0x1000
    #define REGIONSIZE       (SECTORSIZE * 4)
    #define VERIFYBUFSIZE    64
    
    static uint8_t verifyBuf[VERIFYBUFSIZE];
    
    /*
     * Reserve flash sectors for NVS driver use by placing an uninitialized byte
     * array at the desired flash address.
     */
    #if defined(__TI_COMPILER_VERSION__)
    
    /*
     * Place uninitialized array at NVS_REGIONS_BASE
     */
    #pragma LOCATION(flashBuf, NVS_REGIONS_BASE);
    #pragma NOINIT(flashBuf);
    static char flashBuf[REGIONSIZE];
    
    #elif defined(__IAR_SYSTEMS_ICC__)
    
    /*
     * Place uninitialized array at NVS_REGIONS_BASE
     */
    __no_init static char flashBuf[REGIONSIZE] @ NVS_REGIONS_BASE;
    
    #elif defined(__GNUC__)
    
    /*
     * Place the flash buffers in the .nvs section created in the gcc linker file.
     * The .nvs section enforces alignment on a sector boundary but may
     * be placed anywhere in flash memory.  If desired the .nvs section can be set
     * to a fixed address by changing the following in the gcc linker file:
     *
     * .nvs (FIXED_FLASH_ADDR) (NOLOAD) : AT (FIXED_FLASH_ADDR) {
     *      *(.nvs)
     * } > REGION_TEXT
     */
    __attribute__ ((section (".nvs")))
    static char flashBuf[REGIONSIZE];
    
    #endif

    That's simpler, but not very portable across toolchains.

  • Hi Richard,

    Thank you for your quick answer.

    I am trying to reproduce the example you posted in my .cmd file.
    From:
    * .nvs (FIXED_FLASH_ADDR) (NOLOAD) : AT (FIXED_FLASH_ADDR) {
    * *(.nvs)
    * } > REGION_TEXT
    To:
    .boot_info_section (0x8000) (NOLOAD) : AT (0x8000) {
    *(.boot_info_section)
    } > FLASH

    But I am getting:
    *expecting output section, GROUP, or UNION instead of ":"
    * expecting section type (COPY, DSECT, or NOLOAD) instead of "0x8000"
  • You did not tell us which toolchain you are using, but from this question I assume that you are using the TI toolchain.

    Mad River said:
    * .nvs (FIXED_FLASH_ADDR) (NOLOAD) : AT (FIXED_FLASH_ADDR) {
    * *(.nvs)
    * } > REGION_TEXT
    To:
    .boot_info_section (0x8000) (NOLOAD) : AT (0x8000) {
    *(.boot_info_section)
    } > FLASH

    This is specific to GNU LD. It won't work with the TI linker. Are you using the GCC toolchain?

  • Where can I see what toolchain is selected?
    I only found:
    CCS General > Compiler version: TI v16.9.0.LTS
  • It's the TI compiler toolchain. I posted you an example how to place a variable at a specific address in flash using pragmas above.
  • Hi,

    I need this feature to be able to share info between the application program and the bootloader program.

    So, reproducing your example, I wrote this in the application program:
    #define BOOT_DATA_ADDR 0x8000
    #define BOOT_DATA_SIZE 10
    #pragma LOCATION(boot_data, BOOT_DATA_ADDR);
    #pragma NOINIT(boot_data);
    static char boot_data[BOOT_DATA_SIZE];

    And to access this in the bootloader program I wrote this:
    #define BOOT_DATA_ADDR 0x8000
    static char * boot_data = BOOT_DATA_ADDR;

    Is this correct?

  • Mad River said:
    And to access this in the bootloader program I wrote this:

    By "this" do you mean BOOT_INFO or BOOT_DATA? These seem to be different things in your example. But the general idea looks correct to me.

  • Sorry, It was a wrong copy/paste. I edited the previous post.

    So, in the application, can I write directly to boot_data? Like this:

        for(i=0; i<BOOT_DATA_SIZE; i++)
        {
            boot_data[i] = i;
        }

    Or do I need to make use of a flash driver?

  • The second flash page (starting from 0x1000) is reserved when you are using TI-RTOS kernel in ROM. 28 KiB sounds like a huge bootloader. Please also note that you should not update the CCFG data in the last flash page. Therefore, you might consider to split the bootloader into 2 parts and re-use the remaining part of the last flash page.

  • I was editing the previous post to change my question and you answer it before I finish editing.

    Can you please take a look in the new question?

    28 KiB sounds like a huge bootloader

    I agree. It is only a main function which uses the SPI driver.

    I think it is this big because of the TI-RTOS.

    I wish I could do it without using the TI-RTOS in the bootloader.

    Please also note that you should not update the CCFG data in the last flash page

    I am aware of that.

    Therefore, you might consider to split the bootloader into 2 parts and re-use the remaining part of the last flash page.

    I didn't understand this part.

  • Mad River said:

    So, in the application, can I write directly to boot_data? Like this:

        for(i=0; i<BOOT_DATA_SIZE; i++)

        {
            boot_data[i] = i;
        }

    Or do I need to make use of a flash driver?

    No, you need to use a flash driver. I have the feeling that you want to have a look at our OAD solution rather than reimplementing everything on your own. At least, you should study our OAD implementation carefully. Please have a look at

    Please study that carefully. This will be much more effective than asking a lot of questions on E2E.

    Mad River said:

    Therefore, you might consider to split the bootloader into 2 parts and re-use the remaining part of the last flash page

    I didn't understand this part.

    It's possible to split an application into two regions. Since the CCFG is part of the bootloader and should NOT be changed after deploying devices in the field, there is a lot of space left in the last flash page. This can be used for bootloader code as well.

  • Please have a look at

    Thank you.