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/TMS320F28335: how the linker assign placement of several data in the same section?

Part Number: TMS320F28335

Tool/software: TI C/C++ Compiler

hi, i have some tunable parameters that i would like to place them in a separate memory for easy management. since the number of such parameters may change, i didn't create a separate section for each of them but just to place them all in one .paramData section in the flash. 

the process of adding such params is automated in script.

i would like to capture if the data structure change so that the program always matches the structure.. but for the reason of simplicity i cannot use struct, which only generates one symbol.

if i add one param, it seems the linker placements are changing.. not by any order i can predict.

is there a way to "predict" what triggers the linker to place a particular data/var in the section of memory it is allocated for?

complicated question.. hope this is clear enough to solicit some ideas.

thanks

regards

gz

  • Unfortunately, I need more detail.  Please show me, with source code, a detailed example of what you are doing, and how the linker is causing things to change order in an unexpected way.

    In the meantime, the first part of the article Linker Command File Primer should help you understand things better.

    Thanks and regards,

    -George

  • Have you had a chance to provide the example I requested?

    Thanks and regards,

    -George
  • Hi, George, 

    thanks for the reply. please see this .c code

    /*AUTOMATICALLY GENERATED FILE. DO NOT MODIFY*/ 
    
    #include "calParams.h"
    
    #pragma DATA_SECTION(twoDimTable, "caldata");
    const _iq16 twoDimTable[7][11] = {
    	_IQ16(0), _IQ16(1), _IQ16(2), _IQ16(3), _IQ16(4), _IQ16(5), _IQ16(6), _IQ16(7), _IQ16(8), _IQ16(9), _IQ16(10), 
    	_IQ16(10), _IQ16(11), _IQ16(12), _IQ16(13), _IQ16(14), _IQ16(15), _IQ16(16), _IQ16(17), _IQ16(18), _IQ16(19), _IQ16(20), 
    	_IQ16(20), _IQ16(22), _IQ16(24), _IQ16(26), _IQ16(28), _IQ16(30), _IQ16(32), _IQ16(34), _IQ16(36), _IQ16(38), _IQ16(40), 
    	_IQ16(40), _IQ16(44), _IQ16(46), _IQ16(48), _IQ16(50), _IQ16(52), _IQ16(54), _IQ16(55), _IQ16(56), _IQ16(56), _IQ16(56), 
    	_IQ16(50), _IQ16(54), _IQ16(56), _IQ16(58), _IQ16(60), _IQ16(61), _IQ16(61), _IQ16(62), _IQ16(62), _IQ16(62), _IQ16(62), 
    	_IQ16(55), _IQ16(56), _IQ16(57), _IQ16(58), _IQ16(60), _IQ16(61), _IQ16(62), _IQ16(63), _IQ16(63), _IQ16(63), _IQ16(63), 
    	_IQ16(57), _IQ16(58), _IQ16(59), _IQ16(59), _IQ16(60), _IQ16(61), _IQ16(62), _IQ16(63), _IQ16(63), _IQ16(63), _IQ16(63), 
    	};	
    
    #pragma DATA_SECTION(Areal, "caldata");
    const real_T Areal = (10.1235);	 /*test parameter, single precistion*/
    
    #pragma DATA_SECTION(Dcount, "caldata");
    const int32_T Dcount = (-50);	 /*test parameter, int32*/
    
    #pragma DATA_SECTION(Dcount2, "caldata");
    const uint16_T Dcount2 = (50);	 /*test parameter, uint16*/
    
    #pragma DATA_SECTION(Dcount3, "caldata");
    const uint16_T Dcount3 = (20);	 /*test parameter, uint16*/
    
    #pragma DATA_SECTION(Kv_corr, "caldata");
    const _iq16 Kv_corr = _IQ16(1.0123);	 /*correction gain on Vbus measurement*/
    
    #pragma DATA_SECTION(oneDimTable, "caldata");
    const _iq16 oneDimTable[11] = {
    	_IQ16(0), _IQ16(1.1), _IQ16(2.2), _IQ16(3.5), _IQ16(4.6), _IQ16(5), _IQ16(6), _IQ16(7), _IQ16(8), _IQ16(9), _IQ16(10), 
    	};	 /*correction gain on Vbus measurement*/
    
    #pragma DATA_SECTION(InitAngle, "caldata");
    const _iq16 InitAngle = _IQ16(0);	 /*init angle of resolver*/
    
    #pragma DATA_SECTION(paramVerSim, "calsig");
    const uint32_T paramVerSim = 101; 

    the symbol table after linking would give me something like this summary:

    101, varName, varDim1, varDim2, varAdd, varType, _IQN, varMin, varMax, Unit
    RW, twoDimTable, 7, 11, 0x8020, _iq16, _IQ16, -1, 100, Volts
    RW, Areal, 1, 1, 0x8006, real_T, , -20000, 20000, rpm
    RW, Dcount, 1, 1, 0x8008, int32_T, , -32767, 32767, counts
    RW, Dcount2, 1, 1, 0x8000, uint16_T, , 0, 32767, counts
    RW, Dcount3, 1, 1, 0x8001, uint16_T, , 0, 32767, counts
    RW, Kv_corr, 1, 1, 0x8004, _iq16, _IQ16, 0.9, 1.1, none
    RW, oneDimTable, 1, 11, 0x800a, _iq16, _IQ16, -1, 100, Amps
    RW, InitAngle, 1, 1, 0x8002, _iq16, _IQ16, -180, 180, deg
    RO, vdc_diag, 1, 1, 0xb202, _iq16, _IQ16, 0, 1000, V

    the data are in the right section as prescribed by the #pragma

    among all 32 bit data, the two _iq16s are placed at 8002, 8004 respectively, the real_T is placed 8006, the int32_T is placed at 8008. 

    since _iq16 is just typedef'ed to int32, so i'm not sure how the linker is deciding the sequence of arranging these variables. apparently it is not by the sequence of definition, not alphabetical or grouped by types... 

    ultimately i want to understand if i have to re-examine the map file every time even if this .c file is not changed (though other .c in the same project may change). 

    hope this help clarify my original question.

    thanks again

    gzhang

  • You want to control the placement of global variables within one file.  Unfortunately, there is no compiler feature which supports that objective.  The best solution is to define those global variables in hand-coded assembly.  Then the variables will always be in the same order as they are written in the assembly code.  Implementation details are discussed in this forum thread.

    Thanks and regards,

    -George