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.

CC2642R: Want to allocate a variable in the flash after the flash usage by the firmware

Part Number: CC2642R


Hi,

I have a requirement to add a specific variable in my firmware and it should be located after the flash usage of my firmware in the flash. I am trying to add that up in the linker file and see if the memory is allocated for the same in the flash by looking into map file. However, the variable is not appearing after the end of the flash usage but before TI specific links.

In linker .cmd file

SECTIONS
{
  .intvecs        :   >  FLASH_START
  
  .text           :   >> FLASH
  .const          :   >> FLASH
  .constdata      :   >> FLASH
  .rodata         :   >> FLASH
  .cinit          :   >  FLASH
  .pinit          :   >> FLASH
  .init_array     :   >  FLASH
  .emb_text       :   >> FLASH
  //for ccfg memory allocation refer to BIM linker file
  .ccfg           :   >  FLASH_LAST_PAGE (HIGH)

  // Below section must be last
  .flash_usage_end  :   > FLASH


........................

In source code:

#pragma DATA_SECTION(test_array, ".flash_usage_end")  
#define TEST_ARRAY_SIZE (size_t)(64)  // bytes
const uint8_t test_array[TEST_ARRAY_SIZE] = {1, 2, 3};

After the code links and HEX file is created, the MAP file shows following:

0001c466  cryptoMode                                                      
0001c467  ecdhMode                                                        
0001c468  test_array  // test_array appears before _ccfg to __TI_CINIT_Limit                                                    
0001c4a8  __ccfg                                                          
0001c500  __TI_static_base__                                              
0001c974  __TI_Handler_Table_Base                                         
0001c980  __TI_Handler_Table_Limit                                        
0001c9e0  __TI_CINIT_Base                                                 
0001ca48  __TI_CINIT_Limit    
// test_array should appear here
00058000  __UNUSED_FLASH_end__                                            
10007000  __checksum_begin                                                
10007001  ROM_BASE_ADDR                                                   
10007005  llProcessSlaveControlPacket       

Can you suggest what change needed in the linker file to get the test_array located after the end of the flash being used in the firmware i.e after __TI_CINIT_Base?

  • I would also like to know how in the application firmware like simple_peripheral, I can access the last byte memory address from where the application firmware is ended?

  • Hi Mehul,

    Actually the linker does not place the sections by following the sequence provided in the .cmd file. The linker rather uses the placement constraints you provide.

    Here, you are asking the linker to:

    - store the section "flash_usage_end" in FLASH (i.e. between the flash start and the flash end).

    - store the section "ccfg" at Flash end

    Here are the definition of "FLASH" and FLASH_LAST_PAGE for your reference:

    #define FLASH_LAST_PAGE_START      (FLASH_SIZE - PAGE_SIZE)
    
      /* Application stored in and executes from internal flash */
      FLASH (RX) : origin = FLASH_START, length = (FLASH_END - FLASH_START + 1)
    
      /* CCFG Page, contains .ccfg code section and some application code. */
      FLASH_LAST_PAGE (RX) :  origin = FLASH_LAST_PAGE_START, length = PAGE_SIZE

    So we cannot really blame the linker on this one :)

    With that said, the CCFG section should ALWAYS be placed at the last flash page. This means you won't manage to store some code after the CCFG - and if you manage to do this then you do not follow our guidelines and will use the device in a non-tested way.

    I can provide a solution to get the table placed just before the CCFG.

    /*******************************************************************************
     * Section Allocation in Memory
     ******************************************************************************/
    SECTIONS
    {
      .intvecs        :   >  FLASH_START
      .text           :   >> FLASH | FLASH_LAST_PAGE
      .const          :   >> FLASH | FLASH_LAST_PAGE
      .constdata      :   >> FLASH | FLASH_LAST_PAGE
      .rodata         :   >> FLASH | FLASH_LAST_PAGE
      .cinit          :   >  FLASH | FLASH_LAST_PAGE
      .pinit          :   >> FLASH | FLASH_LAST_PAGE
      .init_array     :   >  FLASH | FLASH_LAST_PAGE
      .emb_text       :   >> FLASH | FLASH_LAST_PAGE
      .ccfg           :   >  FLASH_LAST_PAGE (HIGH)
      
      // Below section will be right before CCFG
      .flash_usage_end:   >  FLASH_LAST_PAGE (HIGH)

    This will provide the following map file:

    00022bce  cryptoMode                                                      
    00022bcf  ecdhMode                                                        
    00022bd0  __TI_static_base__                                              
    00022fe4  __TI_Handler_Table_Base                                         
    00022ff0  __TI_Handler_Table_Limit                                        
    00023010  __TI_CINIT_Base                                                 
    00023038  __TI_CINIT_Limit                                                
    00057f68  test_array                                                      
    00057fa8  __ccfg                                                          
    00058000  __UNUSED_FLASH_end__

    I hope this will help,

    Regards,

  • Hi again,

    (Sorry I missed your second message)

    I would also like to know how in the application firmware like simple_peripheral, I can access the last byte memory address from where the application firmware is ended?

    It will depend what you want to do...

    As I said before, the last Flash page contains the CCFG. You have ways to read the CCFG but I am not sure this is the sense of your question.

    In a more generic way, you could declare a table and place it right before the CCFG (exactly like we discussed in our previous messages). That way you can access this table using its symbol.

    Best regards,

  • Hi Clement,

    Sorry for not clear enough. But we really do not have CCFG area defined in our application. Instead, the BIM defines it. It is similar to OAD project.

    So, application linker file looks like this:

    SECTIONS
    {
      .intvecs        :   >  FLASH_START
      //FLASH_LAST_PAGE memory section is now use by the BIM Firmware and ccfg area
      //as FLASH_BIM_START and FLASH_CCFG_START (refer to the BIM linker file)
      //So, we can not use this memory for our Aplication Firmware code memory allocation
      .text           :   >> FLASH
      .const          :   >> FLASH
      .constdata      :   >> FLASH
      .rodata         :   >> FLASH
      .cinit          :   >  FLASH
      .pinit          :   >> FLASH
      .init_array     :   >  FLASH
      .emb_text       :   >> FLASH
      //for ccfg memory allocation refer to BIM linker file
      //.ccfg           :   >  FLASH_LAST_PAGE (HIGH)
    
      // Create a section for locating functions in RAM.
      // For example, the internal flash erase function (RamExecuteFlashSectorErase())
      .TI.ramfunc : {} load=FLASH, run=SRAM, table(BINIT)
      // Below section must be last
      .flash_usage_end  :   > FLASH

    See the CCFG is not really defined in the application linker file. So, how I can get the end address of the flash application usage and place my variable there? Essentially, that variable is going to hold security specific data which must be at the end of the application firmware memory usage.

  • Clement, one more thing, Using memory before FLASH_LAST_PAGE is not an option as that will make the application firmware OAD image larger than the actual. As an example, let's say the application is of only 200KB but this variable will make application will make the application size near to 344 KB. That is not an option.

  • Hi,

    Thank you for the details provided.

    Given your requirements, I would suggest to force the linker to link the symbol at a specific address. That way you will be able to place the symbol exactly where you want. 

    Here is a way to do this - you could of course use a define:

    .flash_usage_end:   > 0x00023078

    This leads to the following map file:

    00022bce  cryptoMode                                                      
    00022bcf  ecdhMode                                                        
    00022bd0  __TI_static_base__                                              
    00022fe8  __TI_Handler_Table_Base                                         
    00022ff4  __TI_Handler_Table_Limit                                        
    00023018  __TI_CINIT_Base                                                 
    00023040  __TI_CINIT_Limit                                                
    00023078  test_array                                                      
    00057fa8  __ccfg                                                          
    00058000  __UNUSED_FLASH_end__    

    You can refer to this document for more information.

    Best regards,

  • Hi Clement,

    Having absolute value is not a correct solution. The application can expand its usage and we really cannot go every time and work on linker file to find the absolute value for the variable. There must be a way to get the variable to end without making change every single time (at least for other compiler like GHS, IAR have worked for).

  • Hi Clement,

    Gentle reminder. Can you suggest?

    Mehul

  • Hi Mehul,

    I have asked linker experts to provide their inputs.

    Please bear with me.

    Regards,

  • Thanks for the update!

  • Hi,

    If I understood this correctly, I think that you want to place the test_vector at the end of all the allocated code. In this case, can you check the e2e thread below that contains a good discussion about this?

    https://e2e.ti.com/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/491556/how-to-explicitly-place-input-section-at-the-end-of-output-section-without-generating-warning

    Hope this helps,

    Rafael

  • I will take a look into this thread. However, by going through it quickly, this is not what I wanted. I do want to get the location of my application flash usage and have that address known to my application. I do not know what do you mean by test_vector (its not a vector table, it is just a variable I want to have after the allocated usage).

    As I said, is there anyway in my application, I can know the end address of the application flash usage? That will work for me as well.

  • Hi Rafael, I have looked into the thread in detail and I believe that it is not explaining the resolution as what I wanted.

  • HI Clement, can I get a way to get the used flash in the application at runtime? That will also suffice my work. I have posted new e2e thread on this:

    https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/1007279/cc2642r-how-to-get-application-flash-usage-in-the-application-fimrware

    Kindly let know the solution.

    Mehul

  • Hi Mehul,

    I will answer on you other thread soon.

    Here an option for the initial question you may want to consider. You could use a "group" and force the linker to output the sections in the order you want.

    Here is the linker command file:

    /*******************************************************************************
     * Section Allocation in Memory
     ******************************************************************************/
    SECTIONS
    {
      .intvecs        :   >  FLASH_START
    //  .text           :   >> FLASH | FLASH_LAST_PAGE
    //  .const          :   >> FLASH | FLASH_LAST_PAGE
    //  .constdata      :   >> FLASH | FLASH_LAST_PAGE
    //  .rodata         :   >> FLASH | FLASH_LAST_PAGE
    //  .cinit          :   >  FLASH | FLASH_LAST_PAGE
    //  .pinit          :   >> FLASH | FLASH_LAST_PAGE
    //  .init_array     :   >  FLASH | FLASH_LAST_PAGE
    //  .emb_text       :   >> FLASH | FLASH_LAST_PAGE
    
      GROUP : > FLASH
      {
     	.text
     	.const
     	.constdata
     	.rodata
     	.cinit
     	.pinit
     	.init_array
     	.emb_text
      	.flash_usage_end
      }
    
      .ccfg           :   >  FLASH_LAST_PAGE (HIGH)
    

    Here is the map file:

    00022bd2  cryptoMode                                                      
    00022bd3  ecdhMode                                                        
    00024184  __TI_Handler_Table_Base                                         
    00024190  __TI_Handler_Table_Limit                                        
    000241a0  __TI_CINIT_Base                                                 
    000241c8  __TI_CINIT_Limit                                                
    000241c8  test_array                                                      
    00057fa8  __ccfg                                                          
    00058000  __UNUSED_FLASH_end__         

    Best regards,

  • It worked! Thanks.