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.

Flash .infoB Segment allocated via CCS4.0.1 C MSP430F2274 DATA_SECTION but not initialized

Other Parts Discussed in Thread: MSP430F2274

#pragma

 

 

Correctly places the array CTL_Vars in Flash .infoB Segment, but CCS Debug Active Project does not initialize the array which includes ={a, b, c .... n} initialization parms.

While testing prior to adding the #pragma to store the array in flash .infoB, the default linker location correctly initialized the array.

Both a memory map and a RF2500 transmission of the array show the contents of the array as all 0xFF (only erased).

I only have the CCS Debug Active Target  "Load Target Function"  available for loading my MSP430 RF2500 target boards.

How can I get this Flash .infoB DATA_SECTION initialized?

DATA_SECTION(CTL_Vars, ".infoB");

  • Got split for some unknown reason. the pragma should have displayed as:

    #pragma DATA_SECTION(CTL_Vars, ".infoB");

  • Read more about initialized SECTIONs in the Assembler Guide and reasoned that I needed the following entry in lnk_msp430f2274.cmd file under the SECTIONS:

    .infoB : {main_ED.obj(.infoB)} > INFOB   /* Replaces original .infoB entry

    Compiled OK, BUT INFOB is still NOT initialized!  (Memory map still shows the CTL_Vars is declared the be loaded in INFOB but is still all 0xFF's.)

    Help would be appreciated.

     

  • You don't show the definition of CTL_vars, but I suspect that is what needs to change.  I presume you define it without the "const" keyword.  If so, you are informing the compiler that CTL_vars is in RAM, i.e. memory which can be written during execution.  I suspect, however, this INFOB memory range is flash.  If all that is correct, then you need to add the "const" keyword to the definition of CTL_vars.  The compiler will then presume CTL_vars is in flash, i.e. memory which does not change during execution.  That change alters how the compiler arranges for the initialization of CTL_vars.  Examine the assembly output to see the difference.  

    Hope this helps ...

    -George

     

  • George, thanks for your suggestion.

    Your reply shows me that I did not fully explain my intent for the #pragma.

    I am building a Data Acquisition and Control imbedded system for a Geothermal Heat Pump application. The control portion uses about 20 uint16_t variables which I want to store in an array in the F2274 Flash Segment B. Flash Segment B is ideal for this, its 64 bytes is large enough to store the array. Because these control variables must be able to be modified for each variation of heat pump configuration, and be fine tuned for each installation, I plan on using the MSP430 Flash Erase/Write capability as initiated over an RF link; this precludes storing the array in normal Flash since the Erase would wipe out the code. Erasing Flash Segment B would only erase the 64 byte array, allowing a subsequent Write to reflect any changes. Once these variables were "tweaked" in the field, they need to remain without modification even following a PUC (a HVAC technician could subsequently alter the values if need be, but again remain otherwise unchanged).

    The beauty of this design is that a simple PC program could allow a HVAC technician to access the DAQ data, analyze it, and if necessary modify the Control variables over the Internet. A good HVAC technician knows the value of periodic maintenance, in many cases it just confirms the correct operation of a customer's unit; to be able to do this over the Internet is currently only a dream. This data download could be used by the HVAC technician to build a history of the state of the customer's unit, building an early warning of impending failures and scheduling an on-site maintence call. Imagine getting a call from your HVAC technician that your unit indicates it needs maintence to restore it to its full operating state! Amazing! To prevent an uneccessary high cost on-site call, yet provide the ultimate in customer satisfaction, is the goal.

    Now for what I unsuccessfully tried for the placement and initiallization of the array in Flash Segment B (.infoB):

    Using only the pragma (using C syntax) places the array in the segment correctly (memory map shows the CTL_Vars address as starting at 0x1080) but does not initialize the array. My interpretation of this pragma is that it is only a Linker command and should not alter how the compiler compiles the code. Code snippet:

     

     

     

     

     

     

     

     

     

     

     

    #pragma

     

     

    int

     

     

    Because these variables are not truly constants, but are installation specific, a Power Up Clear must not restore these values to whatever generic version values existed at the time of the compile. Therefore I think  I can't allow the compiler to treat these as variables that the compliler should initialize (I closely read about initialization and that is my conclusion).

    The Linker command that I tried, based on the "coeffients" example in the assembler guide, is an attempt to provide a source of data at linker time that would populate these variables for the initial CCS Target Load but not be used at a PUC. This example seems to show how to do what I desire. While the example does not show the code portion, the use of the .data for the Linker in the example indicates that the .org file references the pragma SECTION name and not the variable name.    My Linker .cmd revised .infoB code snippet:

    CTL_Vars[CTL_LenCTL_Vars]= {0xFF02, 115, 34,   ...,  0xFF04};
     DATA_SECTION(CTL_Vars, ".infoB");

    .infoB : {main_ED.obj(.infoB)} > INFOB

    A compile with these two definitions was not flagged with any errors, but the addition of the Linker command still did not initialize the Flash Segment B. The result is as if the Segment was in an erased state but never written even though the linker was supplied the data to be written ( or the data supplied was all 0xFF).

    My conclusion:

    Either the Linker is not executing correctly, or the data being supplied is all 0xFF, or CCS Target Load is not writing Flash Segment B  (or some combination).

    main_ED.obj contains 4 instances of "CTL_Vars" but does not contain any instances of "infoB" (is there a program that turns this cryptic .obj file into human readable?).  Should the Linker have complained that there was no apparent section data  "main_ED.org(.infoB)" ?  This is of concern but would only have flagged a previous error if the data was truly missing.

    George, I again thank you for your response. With a better application requirement definition, and a more succinct problem analysis, I hope you can help resolve this problem. 

     

  • I obviously don't know how to copy code to this forum!   It looks good before I post it.

    What is the magic?

  • Below is an example I augmented from the MSP430F2274 code examples to target an initialized array in the INFOB section of flash.  I was able to get this to show up in the debug memory window with initialized values after downloading the program to the target via CCS v4.0

    #include "msp430x22x4.h"

    #pragma DATA_SECTION(CTL_Vars, ".infoB")
    const int CTL_Vars[5] = {0, 1, 2, 3, 4} ;

    void main(void)
    {
      WDTCTL = WDTPW + WDTHOLD ;
      P1DIR |= 0x01 ;
      TACCTL0 = CCIE ;
      TACCR0 = 50000 ;
      TACTL = TASSEL_2 + MC_2 ;

      __bis_SR_register(LPM0_bits + GIE) ;
    }

    #pragma vector=TIMERA0_VECTOR
    __interrupt void Timer_A (void)
    {
      P1OUT ^= 0x01 ;
      TACCR0 += 50000 ;
    }

     

  • Brandon,

    Thanks for your reply.

    What you show is what George suggested, the addition of the "const". And yes, I believe that this would initialize the .infiB array. And depending on the --rom_model (the default) or the --ram_model, would be initialized at run time or load time (resp). This would work for installing a set of safe generic Control coefficients for the embedded application (safe in that their use would not cause the HVAC unit to self-destruct but would not be optimal). Once initialized at either run or load time, a factory coefficient update using a CPU Flash Erase/Write subroutine to install configuration starting coefficients, and a field technician would also use the same subroutine to fine tune the coefficients.

    Because I need to modify these coefficients in the "factory/field" so that they represent the right operating conditions for each HVAC unit; once factory/field modified, the coefficients must not be re-initialized during a Power Up Clear. Power outages if not battery backed up (there may be a long period between factory build and field install), or "fail safe" Watchdog Timer actions causing a PUC would effectively "cripple" the unit.

    Section 7.17.1 of the Assembly Language Tools indicates that the bootstrap  routine at PUC will autoinitialize global variables if --rom_model via the .cinit (No distinction between RAM or Flash initialization appears in the manual). If this reinitializes Flash .infoB because of the use of the "const", then this is what I need to avoid. Specifying --ram_model,  initialization during  bootstrap  is not documented.

    If Flash .infoB is re-initialized at each PUC, isn't there a potential Flash Duration problem?

    The 7.18 Linker Example, specifically the coefficients section, appears to do exactly what I want. But my attempts to use this example as a basis have not succeeded. My above posts code copying to this forum resulted in a confusing jumble so I am repeating the Linker portion again. Using the basic same code as you have shown, less the "const" keyword in the array, and replacing the original lnk_msp430f2274.cmd SECTIONS .infoB with:

    .infoB : {main_ED.obj(.infoB)} > INFOB

    compiled and linked without any error indications; but did not initialize INFOB. My post above relates my findings when I went looking (NotePad) at main_ED.obj (essentially found no obvious .infoB entry but found 4 CTL_Vars entries). The 7.18 example used ...org(.data) which indicates that it refers to a section "(.data)" rather than a variable "(data)" so my "(.infoB)" appears appropriate.

    There appears to be a split in the constructs between the #pragma in the C++ Compiler and the Linker Sections as used in the Assembler. Is there some condition that is "falling in the cracks" as a result? The 7.18 Linker Example was successful because it probably is an Assembler only example, can you try it with C/C++?

    Should the #pragma  have resulted in the main_ED.obj file include a .infoB section containing the coefficient data?  If so, should not the Linker have balked at the absence of said section?

    Would the addition of  "const" cause the .infoB section initial data to be added to the .org file and correctly be used ONLY during linking, thus  NOT causing bootstrap autoinitialization at PUC to happen for this array?

    Again, Thanks for your attention.

    Bruce

  • Brandon,

    A followup on "const" and pragma and a red herring.

    Ran a series of compiles with the various combinations and looked at the project .map file [Both tests with the linker command file modified to point to the ... .org(.infoB)].

    While I could not find any .org(.infoB) data, the linker .map shows it to exist. Therefore I stand corrected as to it's existence. Sorry for the red herring.

    When I ran with "int" and pragma (as I originally used), the .map showed :

    .cinit as 0x128 (0x45 for main...) and .const as 0x5D and .infoB as 0x22 UNITIALIZED

    When I ran as "const int" and pragma ( as both you and George suggested), the .map showed:

    .cinit as  0x104 (0x23 for main...) and .const as 0x5D and .infoB as 0x22  no Unitialized indication.

    I believe the .cinit section difference,  0x128 vs 0x104 not equal 0x22 is due to HOLES. A .cinit reduction without .const increase is the  "tell". 

    Conclusion. When using the "const" int with a pragma and the linker .cmd section directive as shown in the example, will  initialize Flash Segment B at run/load (--rom_model/--ram_model) but not during a PUC since the .cinit section does not include the .infoB initial data. This is key to my project and I suspect to many other projects.

    I apoligize for being a skeptic, but the alternative of "User Post Initialization" exposes some expensive equipment to incorrect operation if not conducted before initial operation.

    The concern for Flash Duration for this scenerio is also not valid.

    Thanks for pointing me in the right direction.

    Bruce

  • Bruce,

    I don't understand this last post.  I think you settled on defining CTL_vars with "const" as your solution.  Is that right?

    For other readers, a general point to keep in mind ... All the talk about --rom_model/--ram_model and the .cinit section has nothing to do with variables defined "const".  A variable defined "const" gets initialized the same as a chunk of executable code.  Some code or data gets copied, perhaps by flashing it, from the .out file created by the linker into the working system.  The --rom_model etc. information pertains to variables that are not defined "const".  That information talks about  how such variables get initialized before main starts.

    Hope this helps ...

    -George

     

  • George,

    Yes I found that using a pragma DATA_SECTION(CTL_Vars, ".infoB") AND the .lnk .infoB statement (per the Example) AND "const" does what I want; which is to initialize the CTL_Vars at Target Load BUT NOT during a Power Up Clear.

    Bruce