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.

Ti TMS470 Linker/c_int00 in ram_model for C++ failure!

Other Parts Discussed in Thread: OMAPL138

I use code segments like this:

class MyClass
{
public:
  MyClass();
private:
  int m_value;
};

MyClass::MyClass():
 m_value(1)
{
}

void main()
{
   static MyClass s_instance;  //constructor call is random depending on the memory content in ram_model!!!
}

When I check the assembler code, the compiler generates a flag bit which is checked to guaranty that the constructor of the static
instance is just called once.
Unfortunately this flag bit is not initialized by the "C runtime environment" (c_int00) at startup in ram_model. Therefore if
this flag bit is already set (randomly or after a device reset) the constructor is not called anymore.

In linker rom_model everything works fine (bit is initialized in "C runtime environment").

Is this a known problem?
Are there any other workarounds beside not using of this kind of construct or using rom_model?

  • In RAM model, the loader (e.g. CCS) is responsible for initializing global data, including the guard bit controlling object construction.  If you run the program and then restart, you must re-load the program or the global data is in an unknown, unreliable state.  So, if you use RAM model, you must re-load before every run (some programs can get away without a re-load, but not this one).  Does this match what you are observing?

  • When you execute the code built with the RAM model of initialization, how are you loading the code into the system?  If you are not using CCS, then that is probably the problem.  When using RAM model, it is the responsibility of the loader to initialize variables according to the content of the .cinit section.  Because such processing is non-trivial, few production systems running in the field use RAM model.

    Thanks and regards,

    -George

  • Actually I tried two methods of loaders.


    First, the CCS loader with an XDS560 debugger/emullator. I observed the "guard" bit in the memory. After power up this bit is set to 0 (like all external memory addresses). Therefore the constructor of the static local class is called. After a reload of the application (break point at the beginning of main) the guard bit is still set. Hence the constructor is not called this time. A manual reset of the guard bit in the debug envirnoment helps.

    Second, I flashed the application into a SPI flash and booted from there. Added a wait loop at the beginning of the application to connect to the board with the debugger (just symbol load). I got the same problem.

    Best regards

    Thomas

  • In the first case, are you re-loading the program from disk after the first run, or just setting the PC back to main?

  • I stop the debugger. Start again and therefore reload the application from disk.

  • Could you send me the executable file for your small test case so I can make sure it properly encodes the initialization?  Use the "Conversations" button above.  You'll probably need to wrap it in a ZIP file.

  • Here my test project.
    Problem does not appear with simulator. It seams like the simulator initializes the memory and therefore the guard bit to 0 at connection/startup.

    I get the problem on a real hardware CPU with ram that keeps state from previous debug sessions/program runs (unless the variables are reinitialized by the loader/application).

    7870.problem2.zip

  • That ZIP does not contain the executable.  I need to see whether the compiler and linker did what they should.

  • Here the built binary output. The mentioned "guard" bit is at address 0xC3001710 (bit0).

    3377.problem2_bin.zip

  • This appears to be a bug in the CCS loader.  I've submitted SDSCM00042973 for this issue.  This problem only happens for EABI RAM model.

    The linker correctly creates a PT_LOAD segment containing both .bss and .data with "file size" smaller than the "memory size" (use ofd470 to see this).  This is a signal to the loader that it is responsible for zero-initializing the leftover portion of the PT_LOAD segment that doesn't have data in the object file.  This is a requirement of the ELF standard.  (See System V Application Binary Interface - DRAFT - 19 October 2010, Chapter 5, section "Program Header", the description of PT_LOAD.)

    Please note that RAM model is not well-suited for placing .bss in FLASH memory.  Something must be responsible for zero-initializing .bss at "boot" time, which is pretty much what ROM model does.

  • Unfortunately the ROM bootloader of OMAPL138 seems to have a similar problem.
    According your description of the RAM model for FLASH, for what else is the RAM model suitable?

    Then there is another problem with static constructs in relation with templates and libraries (see my other post:
    http://e2e.ti.com/support/development_tools/compiler/f/343/t/160822.aspx#584744

    Regards
    Thomas

  • RAM model is suitable when there is a loader which runs every time the program might be run.  For example, in an operating system context, the operating system might act as the loader.  To run a program, it would copy it into memory from something like a disk drive.  In this case, the loader might just as well perform the zero-initialization once at load-time, rather than as part of program startup.  In a system that does not have an operating system with a program loader, you should typically use ROM model.

  • My understanding is, that the OMAPL138 should be a boot-loader too. Else this way it's a kind of waste of memory since the "variable" is twice in ram. Once as the initialization value and once as the variable used at runtime.

  • I don't know anything about that bootloader, so I can't comment on it, but it's not strictly necessary for a boot loader to load all sections to RAM; why not leave the .cinit record in ROM/FLASH and read it from there?

    For RAM model EABI, a loader of any kind, boot or otherwise, is responsible for zero-initializing .bss (and other uninitialized sections).  If the boot loader format is not capable of representing a list of sections it must zero-initialize, the zeros must be encoded directly in the load image by whatever created the bootloader.