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.

SYS/BIOS TI-RTOS Copy Flash to RAM Example - F28335

Other Parts Discussed in Thread: TMS320F28335

Where can I find an example of how to copy functions from flash to ram on an F28335 using SYS/BIOS? SPRA958L (Running an Application from Internal Flash Memory) states that the Application  Report does NOT apply to SYS/BIOS (BIOS 6). I haven't been able to anything that is specific to the latest SYS/BIOS.

Regards,

 - Scott

  • Please refer to the following thread:

    e2e.ti.com/.../117026

    Steve
  • Ok. I believe I am doing everything as suggested but when I look at the RamfuncsLoadStart, RamfuncsLoadEnd, and RamfuncsLoad Size values they are not correct. Based on that I am assuming I am doing something wrong in my .cmd file. (???)

    Here's my code....

    #pragma CODE_SECTION(hwiDmaLongRefFxn,"ramfuncs");
    #pragma CODE_SECTION(swiAvgRefWaveFxn,"ramfuncs");
    ...
    extern Uint16 RamfuncsLoadStart;
    extern Uint16 RamfuncsRunStart;
    extern Uint16 RamfuncsLoadSize;
    extern Uint16 RamfuncsLoadEnd;

    Int main()
    {
    //memcpy( &RamfuncsRunStart, &RamfuncsLoadStart, (UInt32)&RamfuncsLoadSize );
    MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);

    RamfuncsRunStart is correct. The others are not. RamFuncsLoadSize == 4, which I believe is the CycleDelay.asm code length.

    This seems soooo simple, what am I doing wrong??

    Here's my .cmd file...

    MEMORY
    {
    PAGE 0: /* Program Memory */

    RAML0_1 : origin = 0x008000, length = 0x002000 /* use for ramfuncs */
    FLASH : origin = 0x300000, length = 0x03FF80 /* on-chip FLASH */
    CSM_RSVD : origin = 0x33FF80, length = 0x000076 /* Program with all 0x0000 when CSM is in use. */
    BEGIN : origin = 0x33FFF6, length = 0x000002 /* Used for "boot to Flash" bootloader mode. */
    CSM_PWL : origin = 0x33FFF8, length = 0x000008 /* CSM password locations in FLASH */
    OTP : origin = 0x380400, length = 0x000400 /* on-chip OTP */
    ADC_CAL : origin = 0x380080, length = 0x000009 /* ADC_cal function in Reserved memory */

    IQTABLES : origin = 0x3FE000, length = 0x000b50 /* IQ Math Tables in Boot ROM */
    IQTABLES2 : origin = 0x3FEB50, length = 0x00008c /* IQ Math Tables in Boot ROM */
    FPUTABLES : origin = 0x3FEBDC, length = 0x0006A0 /* FPU Tables in Boot ROM */
    ROM : origin = 0x3FF27C, length = 0x000D44 /* Boot ROM */
    RESET : origin = 0x3FFFC0, length = 0x000002 /* part of boot ROM */
    VECTORS : origin = 0x3FFFC2, length = 0x00003E /* part of boot ROM */

    PAGE 1 : /* Data Memory */

    RAMM0_1 : origin = 0x000000, length = 0x000800 /* on-chip RAM block M0-1 = 2K */
    PIEVECT : origin = 0xD00, length = 0x100
    RAML2_5 : origin = 0x00A000, length = 0x004000 /* combined RAML2, ... ,RAML5 */
    RAML6_7 : origin = 0x00E000, length = 0x002000
    ZONE7 : origin = 0x200000, length = 0x000400 /* XINTF zone 7 - ADC access*/
    }

    SECTIONS
    {
    /* Allocate program areas: */
    .cinit : > FLASH PAGE = 0
    .pinit : > FLASH PAGE = 0
    .text : > FLASH PAGE = 0
    codestart : > BEGIN PAGE = 0
    ramfuncs : LOAD = FLASH PAGE = 0,
    RUN = RAML0_1 PAGE = 0,
    LOAD_START(_RamfuncsLoadStart),
    LOAD_SIZE(_RamfuncsLoadSize),
    LOAD_END(_RamfuncsLoadEnd),
    RUN_START(_RamfuncsRunStart)

    csmpasswds : > CSM_PWL PAGE = 0
    csm_rsvd : > CSM_RSVD PAGE = 0

    /* Allocate uninitalized data sections: */
    .stack : > RAMM0_1 | RAML2_5 PAGE = 1
    .ebss : > RAMM0_1 | RAML2_5 PAGE = 1
    /* not using malloc (heap)
    .esysmem : > L07SARAM | M01SARAM PAGE = 1
    */
    .cio : > RAMM0_1 | RAML2_5 PAGE = 1

    /* Initalized sections go in Flash */
    /* For SDFlash to program these, they must be allocated to page 0 */
    .econst : > FLASH PAGE = 0
    .switch : > FLASH PAGE = 0
    .args : > FLASH PAGE = 0

    /* Allocate IQ math areas: */
    IQmath : > FLASH PAGE = 0 /* Math Code */
    IQmathTables : > IQTABLES PAGE = 0, TYPE = NOLOAD
    FPUmathTables : > FPUTABLES, PAGE = 0, TYPE = NOLOAD

    DMARAML6_7 : > RAML6_7, PAGE = 1 /* dma data buffers here */
    DMAZONE7SRC : > ZONE7, PAGE = 1 /* Memory mapped ADC */

    /* Allocate ADC_cal function (pre-programmed by factory into TI reserved memory) */
    .adc_cal : load = ADC_CAL, PAGE = 0, TYPE = NOLOAD
    }
  • Can you verify that the memory segments "FLASH" and "RAML0_1" are defined?

    smh123 said:
    //memcpy( &RamfuncsRunStart, &RamfuncsLoadStart, (UInt32)&RamfuncsLoadSize );
    MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);

    What is MemCopy?  Did you define your own function because memcpy() didn't seem to be working?

    Also, I noticed that the arguments in memcpy() vs. MemCopy() are different.  Was that intentional?

    smh123 said:
    .cinit : > FLASH PAGE = 0

    Just a guess, this may not matter but I noticed that there's no comma between the memory segment name and PAGE.  I.e.:

    .cinit : > FLASH, PAGE = 0

                              ^

    Can you also attach your *.map file for this app?

    Steve

  • Hi Steve,

    Thank for you looking at this.

    In answer to your questions:

    1) the FLASH and RAML0_1 segments are defined as shown in the .cmd I had attached and also in my .map file

    name origin length used unused attr fill
    ---------------------- -------- --------- -------- -------- ---- --------
    PAGE 0:
    RAML0_1        00008000   00002000 00000004  00001ffc  RWIX
    FLASH            00300000   0003ff80   00009c9c 000362e4 RWIX

    2) You are correct that Memcopy() was attempted because memcpy() didn't do the job. (It is from one of the TI example projects). The arguments are different by design.

    Your suggestion to look at the .map file has shed some light on this. I can see the "ramfuncs" section does not include the functions I want included. It only includes the CycleDelay asm function which I am able to copy to ram as expected. (Note: RamfuncsLoadStart= 0x30 9c7c, RamfuncsLoadSize = 4, RamfuncsRunStart = 0x8000 and I have verified these values with the debugger at runtime).

    ramfuncs       0 00309c7c      00000004    RUN   ADDR = 00008000
    00309c7c           00000004        CycleDelay.obj (ramfuncs)

    This is the problem. Now, how do get my functions included? 

    I have attached the entire .map file if you want to see it.

    Regards,

     -Scott

    7624.Breadboard_rtos.map.txt

  • smh123 said:
    I can see the "ramfuncs" section does not include the functions I want included

    I believe if you just use the CODE_SECTION pragma, as you did before, it should place them.  E.g.:

    #pragma CODE_SECTION(RamfuncsLoadStart, "ramfuncs");
    extern Uint16 RamfuncsLoadStart;
    
    #pragma CODE_SECTION(RamfuncsRunStart, "ramfuncs");
    extern Uint16 RamfuncsRunStart;
    
    #pragma CODE_SECTION(RamfuncsLoadSize, "ramfuncs");
    extern Uint16 RamfuncsLoadSize;
    
    #pragma CODE_SECTION(RamfuncsLoadEnd, "ramfuncs");
    extern Uint16 RamfuncsLoadEnd;

    Steve

  • It's my understanding that the CODE_SECTION pragmas are used to specify the functions that are to be placed in ram, which I have already done with the following statements in main:

    #pragma CODE_SECTION(hwiDmaLongRefFxn,"ramfuncs");

    #pragma CODE_SECTION(swiAvgRefWaveFxn,"ramfuncs");

    Placing the Ramfuncsxxxxx variables in the code section has no impact. The load size is still only accounting for the CycleDelay.asm assembly file .  Note that this  file specifies the the "ramfuncs" section:

          .def _CycleDelay

        .sect "ramfuncs"

           .global  _CycleDelay

    _CycleDelay:

           SUB    ACC,#1

          BF     _CycleDelay,GEQ    ;; Loop if ACC >= 0

           LRETR

    Steve,

    Can you find any example code for TI_RTOS that is copying code from flash to ram? I haven't been able to find any but found it but there must be some that I could look at.  Is the method for doing this different than in previous versions of DSP/BIOS or SYS/BIOS? 

    -Scott

  • I tried this in another post but haven't gotten anywhere. I will try again here.

    I have TI-RTOS and simply want to copy some of my functions from flash to ram. The problem is that the addresses of the functions that need to be copied are not getting set by the linker(?). In my application the TI supplied CycleDelay.asm function is the only function that gets accounted for in the  RamFuncxxxx variables and the CycleDelay asm function IS successfully copied to ram. My functions are not accounted for in these variables...

    extern Uint16 RamfuncsLoadStart;    // has address of CycleDelay.asm function in flash
    extern Uint16 RamfuncsLoadSize;    // size is 4
    extern Uint16 RamfuncsLoadEnd;    
    extern Uint16 RamfuncsRunStart; // this is set to the correct location as specified in my .cmd file

    so when I attempt to copy the functions to ram with "memcpy( &RamfuncsRunStart, &RamfuncsLoadStart, (UInt32)&RamfuncsLoadSize );" things don't work correctly.

    How do I get these to be set correctly?

    Here a portion of my main.c and my .cmd file that I believe "should" take care of this:
    ...
    #pragma CODE_SECTION(hwiDmaLongRefFxn,"ramfuncs");
    #pragma CODE_SECTION(swiAvgRefWaveFxn,"ramfuncs");
    
    extern Uint16 RamfuncsLoadStart;
    extern Uint16 RamfuncsRunStart;
    extern Uint16 RamfuncsLoadSize;
    extern Uint16 RamfuncsLoadEnd;
    
    Int main() {
      memcpy( &RamfuncsRunStart, &RamfuncsLoadStart, (UInt32)&RamfuncsLoadSize );
    
    The .cmd file...
    
    MEMORY
    {
    PAGE 0:    /* Program Memory */
       /* BEGIN is used for the "boot to SARAM" bootloader mode      */
        /* TODO SMH - break flash into sections for storing factory calibration, runtime stats, etc. */
        RAML0_1     : origin = 0x008000, length = 0x002000	   /* use for ramfuncs */
    
        FLASH       : origin = 0x300000, length = 0x03FF80     /* on-chip FLASH */
        CSM_RSVD    : origin = 0x33FF80, length = 0x000076     /* Program with all 0x0000 when CSM is in use. */
        BEGIN       : origin = 0x33FFF6, length = 0x000002     /* Used for "boot to Flash" bootloader mode. */
        CSM_PWL     : origin = 0x33FFF8, length = 0x000008     /* CSM password locations in FLASH */
        OTP         : origin = 0x380400, length = 0x000400     /* on-chip OTP */
        ADC_CAL     : origin = 0x380080, length = 0x000009     /* ADC_cal function in Reserved memory */
       
        IQTABLES    : origin = 0x3FE000, length = 0x000b50     /* IQ Math Tables in Boot ROM */
        IQTABLES2   : origin = 0x3FEB50, length = 0x00008c     /* IQ Math Tables in Boot ROM */  
        FPUTABLES   : origin = 0x3FEBDC, length = 0x0006A0     /* FPU Tables in Boot ROM */
        ROM         : origin = 0x3FF27C, length = 0x000D44     /* Boot ROM */        
        RESET       : origin = 0x3FFFC0, length = 0x000002     /* part of boot ROM  */
        VECTORS     : origin = 0x3FFFC2, length = 0x00003E     /* part of boot ROM  */
    
    PAGE 1 :   /* Data Memory */
       
        RAMM0_1     : origin = 0x000000, length = 0x000800     /* on-chip RAM block M0-1 = 2K */
        PIEVECT     : origin = 0xD00,    length = 0x100
        RAML2_5     : origin = 0x00A000, length = 0x004000		/* combined RAML2, ... ,RAML5 */
        RAML6_7     : origin = 0x00E000, length = 0x002000
        ZONE7       : origin = 0x200000, length = 0x000400     /* XINTF zone 7  - external ADC access*/
    }
     
    SECTIONS
    {
        /* Allocate program areas: */
        .cinit              : > FLASH,       PAGE = 0
        .pinit              : > FLASH,       PAGE = 0
        .text               : > FLASH,       PAGE = 0
        codestart           : > BEGIN,       PAGE = 0
        ramfuncs            : LOAD = FLASH   PAGE = 0,
                              RUN  = RAML0_1 PAGE = 0,
                              LOAD_START(_RamfuncsLoadStart),
                              LOAD_SIZE(_RamfuncsLoadSize),
                              LOAD_END(_RamfuncsLoadEnd),
                              RUN_START(_RamfuncsRunStart)
    ...

    Do I need another .cmd file that links earlier than my main .cmd file? I am at a loss so any help would be greatly appreciated.
    Regards,
    -Scott

  • Here's the portion of the .map file that shows the "ramfuncs" section, which looks correct for the CycleDelay.asm file. As you can see it does not account for my C-code functions.


    ramfuncs 0 00309c75 00000004 RUN ADDR = 00008000
    00309c75 00000004 CycleDelay.obj (ramfuncs)
  • Help. Can anyone out there take a stab at this. It MUST be something very simple that I am overlooking. Any assistance would be much appreciated. Thanks.

    -Scott
  • Hi Scott,

    My apologies for the delayed response.

    I was able to try this out locally on a ezDSP 28335 board and I'm seeing the same thing as you are. In particular, I'm seeing that the "load size" is also set to 4, which doesn't seem right to me.

    I also saw that my memcpy() function did not do anything to change the memory of the RAM location of my function (e.g. "run start" was all 0xFF, and after the memcpy(), it retained that value).

    I then tried, using a memory window in CCS, to manually write to the memory at "myFunction" and I could not write there using the memory window!  This indicates that the memory is read only.

    Can you try this on your side?  Are you able to manually write to your "hwiDmaLongRefFxn" or "swiAvgRefWaveFxn"?

    Steve


  • Hi Steve,

    Thanks for getting back on this. 

    I believe you are correct on why you can't write your function to the "my_RamFuncsRunStart" location. You are attempting to write to 0x380400 which is OTP memory, which I'm not sure if you can write to, but I'm not sure. If you change your .cmd file to place "my_RamFuncsRunStart" to SRAM you should be ok. 

    What is different on your Memory Browser is that "my_Function" and "my_RamFuncsRunstart" are both recognized. i.e. the linker has recognized that "my_Function" will reside at the  address 0x380400. Look at my memory browser window. It does not show that either of my functions "hwiDmaLongRefFxn" or "swiAvgRefWaveFxn"  will reside at my "RamfuncsRunStart" location RAML0_1 (0x8000). The only function that is shown to reside in SRAM is "CycleDelay", which is an assembly function from TI. So it seems to be a simple question of why does the system not recognize that I want to  place my functions in SRAM?

    Steve,  If I could see a copy of your .cmd file and your main.c (I want to see your PRAGMA statements) that may point me in the right direction.

    Regards,

      -Scott

  • Hi Steve,

    Thanks for getting back on this.

    I believe you are correct on why you can't write your function to the "my_RamFuncsRunStart" location. You are attempting to write to 0x380400 which is OTP memory, which I'm not sure if you can write to, but I'm not sure. If you change your .cmd file to place "my_RamFuncsRunStart" to SRAM you should be ok.

    What is different on your Memory Browser is that "my_Function" and "my_RamFuncsRunstart" are both recognized. i.e. the linker has recognized that "my_Function" will reside at the  address 0x380400. Look at my memory browser window. It does not show that either of my functions "hwiDmaLongRefFxn" or "swiAvgRefWaveFxn"  will reside at my "RamfuncsRunStart" location RAML0_1 (0x8000). The only function that is shown to reside in SRAM is "CycleDelay", which is an assembly function from TI. So it seems to be a simple question of why does the system not recognize that I want to  place my functions in SRAM?

    Steve,  If I could see a copy of your .cmd file and your main.c (I want to see your PRAGMA statements) that may point me in the right direction.

    Regards,

     -Scott

  • I hope this posts to the correct thread. I posted twice before and it went to a previous thread. I will try again. My apologies if it shows up as a third post. 

    Hi Steve,

    Thanks for getting back on this.

    I believe you are correct on why you can't write your function to the "my_RamFuncsRunStart" location. You are attempting to write to 0x380400 which is OTP memory, which I'm not sure if you can write to, but I'm not sure. If you change your .cmd file to place "my_RamFuncsRunStart" to SRAM you should be ok.

    What is different on your Memory Browser is that "my_Function" and "my_RamFuncsRunstart" are both recognized. i.e. the linker has recognized that "my_Function" will reside at the  address 0x380400. Look at my memory browser window. It does not show that either of my functions "hwiDmaLongRefFxn" or "swiAvgRefWaveFxn"  will reside at my "RamfuncsRunStart" location RAML0_1 (0x8000). The only function that is shown to reside in SRAM is "CycleDelay", which is an assembly function from TI. So it seems to be a simple question of why does the system not recognize that I want to  place my functions in SRAM?

    Steve,  If I could see a copy of your .cmd file and your main.c (I want to see your PRAGMA statements) that may point me in the right direction.

    Regards,

    -Scott

  • Hi Scott,


    Please find the files I used attached and let me know what happens.


    Steve

    7356.myfiles.zip

  • Hi Steve,

    Any chance you could send your entire project so I can attempt EXACTLYwhat you have done?Otherwise I am just guessing. Your files look the same as mine

    #pragma CODE_SECTION(hwiDmaFxn,"ramfuncs");  

    and 

    SECTIONS
    {
    /* Allocate program areas: */
    .cinit : > FLASH, PAGE = 0
    .pinit : > FLASH, PAGE = 0
    .text : > FLASH, PAGE = 0
    codestart : > BEGIN, PAGE = 0
    ramfuncs : LOAD = FLASH, PAGE = 0
    RUN = RAML0_1, PAGE = 0
    LOAD_START(_RamfuncsLoadStart)
    LOAD_SIZE(_RamfuncsLoadSize)
    // LOAD_END(_RamfuncsLoadEnd)
    RUN_START(_RamfuncsRunStart)

    -Scott

  • Hi Steve,

    OK. Finally some movement on this. I have found that if myFunction() is defined in main.c then everything works fine. If myFunction() is defined in an external module say myFunction.c then the linker does not account for putting myFunction() into ram.  

    The following does NOT work. RamfuncsLoadSize is always 0.

    #pragma CODE_SECTION(myFunction, "ramfuncs")
    extern void myFunction();  // defined in module myFunction.c 

    /*
    * ======== main ========
    */
    Int main()
    {
    memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (Uint32)&RamfuncsLoadSize);
    myFunction();

    Log_info0("Hello world\n");

    BIOS_start(); /* does not return */
    return(0);
    }

    I have attached my simple non-working project (TI's example project task28_TMS320F28335).

    7002.task28_TMS320F28335.zip

    Can you please try this and see if you can reproduce? Thanks.

    -Scott

  • Scott,


    I moved the #pragma to be in myFunction.c, immediately above the definition of myFunction().  I see the following in the map file now:

    abs   00000015  _RamfuncsLoadSize


    Can you give that a try?

    Steve

  • Hi Steve,

    Putting the #pragma in the module where the function is defined works. 

    This is either a bug in the linker OR it is a documentation problem. I suspect it's a bug. There may be hundreds or thousands of unsuspecting users out there that "think" their code is executing from SRAM when in actuality it is executing from flash.

    Regards,

    -Scott 

  • Scott,

    Have you seen the SET_CODE_SECTION pragma?  I think this will do what you want.  The TMS320C28x Optimizing C/C++ Compiler v6.4 guide has a good overview and an example (6-14 below) of its use for prototypes vs. actual function definitions.

    Steve