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.

TMS320F28335 RTS Library Initialization Issue

Other Parts Discussed in Thread: CONTROLSUITE

Hi there,

I experienced a couple of strange crashes in the simulator (CCS 3.3) trying to use malloc(). Then I realized various pointers had not been initialized. The debugger was at the entry into main() after loading / restart. I am using the large memory model library with exception handling.

I finally stumbled across c_int00() in the documentation. I noticed that this wasn't linked or called. I never did anything explicitly to circumvent this code from linking or executing, however, I do have to use a linker command file fairly closely based on the one used in this project, which I will attach below for inspection.

Out of curiosity I put the following code into my main.cpp source just before main():

extern "C" {
    void c_int00(void);
    void (*dummy)() = c_int00;
}

Low and behold, the function is now linked and the debugger starts at at the entry to c_int00() after a reset. Also, SP and other initializations now seem to be as expected. My program (a unit test, written in a mixture of C and C++ and based on CppUTest) still does not run without problems, but the apparent problems caused by uninitialized code at least are gone.

My questions are this:

  1. Why did c_int00() not get linked? Of course there was no reference to it in the code, since it is supposed to be linked and executed "behind the scenes". Surely one should not have to resort to weird tricks like the above?
  2. Now that it does get linked and executed, is it normal for the Debugger to start at c_int00(), so that I first need to issue a "Go Main" command?
  3. Is there any way of using a simple, no-frills memory map for simulator runs? What would be the simplest possible memory map to use on the actual device?
  4. Currently, the stack has a size of 0x0800. This should be plenty, unless things go wrong. Where in the memory map could I allocate a larger space for the stack, should this be necessary?
  5. What is the point of the -farheap0x10000 -heap0x1000 -stack0x800 linker options when I need to specify in the linker command file exactly where and how large each of these sections should be? My idea would be to use these options and leave it to the linker where exactly it wants to place each. Conversely, when I do have to use .cmd files, what are the options for?  Must I use both?

I built this same unit test (identical code except for the deviation mentioned above) for ARM using the IAR Embedded Workbench. On that platform, I could simply compile and link, using pretty much the default options, then load the binary in the simulator and execute it without a hitch, so it's not like there is anything inherently wrong with CppUTest or my code.

http://e2e.ti.com/cfs-file.ashx/__key/communityserver-discussions-components-files/171/0624.Example.7z

 

 

  • Arnd Strube said:
    1. Why did c_int00() not get linked? Of course there was no reference to it in the code, since it is supposed to be linked and executed "behind the scenes". Surely one should not have to resort to weird tricks like the above?

    I found the answer to this part of my question myself. For c_int00() to be linked and put in the Reset vector, one has to specify the -c linker option (or choose " Autoinit Model: Run-Time Autoinitialization (-c)" under the "Basic" category on the "Linker" tab of Build Options.

  • Hi!

    Maybe I didn't understand you very well but first I would recommend you refer to 3438.TI_Running_from_Flash_spra958l.pdf (especially to pages 6 and 32).

    Regards,

    Igor

  • Hi Igor,

    Obviously, I am a beginner with this MCU.

    I didn't find the abovementioned documentation very helpful, as I have the outlandish(?) notion that it should be possible to compile / link / run an ordinary C/C++ program without resorting to software-archaeology, within the confines of a given system, of course.

    As such, I expect not to have to resort to writing assembler code so the C initialization will take place (although, generally, I don't mind assembler. But I'm not working on that level here).

    My expectation is that the linker should make use of available memory / flash in a sensible way, without me having to specify every little bit. Obviously, this is not the case...

    Thanks you anyway, your help is appreciated.

    Arnd

  • Hi!

    Sorry! It is a pity that I could not help you. But I would like to make a couple of recent banal comments:

    1 CCS-linker works via the command linker file (*.cmd). I do not mean that you have to be implemented in software-archaeology very deeply. But it is necessary by himself to take care of the location of data in memory in each case (certainly "without you having to specify every little bit").

    2 To organize the correct operation of F28335 it is not necessary to apply programming on assembler. To start the program from the flash, you can use the ready file 6888.DSP2833x_CodeStartBranch.asm (from device-library) by connecting it to the project. In that case this  excess:

    extern "C" {
        void c_int00(void);
        void (*dummy)() = c_int00;
    }

    Good luck,

    Igor

  • Hi Igor,

    Thank you again for your kind reply. I was on vacation for a week, that's why I got to look at it only now. Actually, the linker .cmd file (and the related .gel file) are part of my problem.

    My .cmd file (which is based on the one normally used in this project) seems extremely fragmented to me. The software we need to run for unit testing is pure software, with no hardware interaction (ports, CAN, etc.). We might write the results into RAM (current approach) or we might use the facility to have printf() write results into a file on the host (haven't looked into that yet).

    Looking at the .cmd file, there are many very small areas of memory allocated to various registers, and for me, not being an expert with this platform, it is hard to tell which ones are essential for correct operation, and which ones are not. For example, all of the first .cmd file (DSP2833x_Headers_nonBIOS.cmd) is tiny areas for various registers, some of which I will most certainly not use (ECANA..., ECANB...) and some the processor probably will use (XINTF) since I plan to use XINTF memory.

    Also, the file F28335_RAM_lnk_4_UT.cmd contains a lot of detailed information, some of which may not be relevant.

    I adjusted both files to the best of my very skimpy knowledge, just to get enough RAM / big enough segments for stack and heap anywhere I could (the .cmd files are attached to my first post above).

    I wish I could simplify the memory map, so that only the essentials are left, and as much contiguous RAM for stack, static variables and heap as possible.

    I would appreciate if you could point me the right direction to achieve that.

    Thanks,

    Arnd

  • Hello Arnd!

    It is difficult to give useful advice in specific cases. I'm beginner at C2000. But my opinion your .CMD looks rather strange (I still did not see something like that). At least it has a lot of memory partitons and then these partitions are aggregated for using by different data type (for example, FLASH for program memory). I think if you want to get simple MAP you should aggregate memory areas primarily. Ultimately what do you want? If I uderstood you right, you need big stack, big pogram memory, big data memory. Thus try to aggregate memory partitons for your needs. For example:

    RAML0123

    insted:

    RAML0

    RAML1

    RAML2

    RAML3

    etc.

    Also I would recommend you refer to .CMD-files for F28335 from controlSUITE.

    Regards,

    Igor 

  • Hi Igor,

    Yes, it is strange. But then, I do find the adress space of the f28 series somewhat strange to begin with...

    Following your suggestions, and pulling information from spru513e.pdf I came up with the following:

    /************************************************************/
    /* Linker command file for simulator only                   */
    /************************************************************/

    /* Contains only the bare necessities for running a unit test
     * in the TI CCS 3.3 Simulator
     */

    MEMORY
    {
    PAGE 0 : /* Program Memory */

        /* Flash as one big segment */
        FLASH    : origin = 0x300000, length = 0x040000

    PAGE 1 : /* Data Memory */

        /* Internal SARAM */
        RAM_0    : origin = 0x000000, length = 0x002000 
        /* 0x2000 to 0x3FFF: Not defined */
        STACK    : origin = 0x004000, length = 0x004000
        RAM_1    : origin = 0x008000, length = 0x008000

        /* External memory */
        EMEM     : origin = 0x100000, length = 0x030000
    }

    SECTIONS
    {  
        /* segment allocation */
        .cinit   : >  FLASH, PAGE = 0 /* initialized RAM */
        .pinit   : >  FLASH, PAGE = 0 /* initialized constructors */
        .stack   : >  STACK, PAGE = 1
        .text    : >  FLASH, PAGE = 0
        .bss     : >  RAM_0, PAGE = 1
        .ebss    : >  RAM_1, PAGE = 1 /* uninitialized */
        .econst  : >  FLASH, PAGE = 0
        .esysmem : >  EMEM,  PAGE = 1 /* malloc calls */
        .cio     : >  RAM_0, PAGE = 1 
     
        /* keep the linker from complaining */
        .reset   : >  FLASH, PAGE = 0, TYPE = DSECT /* not used */
    }

    This is the simplest I could come up with while still staying reasonably close to the actual silicone.

    Thanks again for your kind help!

    Arnd R.

     

  • Hello!

    Ok! Brevity is the soul of wit.

    Regards,

    Igor