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.

TMS320F28379D: ISR overruns when ran from Flash instead of RAM

Part Number: TMS320F28379D

Hello,

I have a code that is running inside ADC ISR (interrupts every 20 us). It is running without any issues when ran from RAM, whereas there is an ISR overrun when it is run from flash (The code inside the ISR seems to take more than 20 us)

I checked the wait-state configuration inside the InitFlash() function (In the SysCtrl.c file). The RWAIT bit is set to 0x3 for a CPU frequency of 200MHz, which is our operating CPU frequency. The datasheet also says that the minimum wait-states need to be 0x3 for 200MHz clock.

Are any other changes that can be made to the configuration such that it doesn't lead to an ISR overrun?

Thanks.

  • Hello,

    Due to US holiday please expect response by 20th February.

    Thanks & Regards,

    Sinchita

  • Sanjay,

    Could you share your linker(.cmd) file for the RAM and Flash use case?  I think that will help narrow down any potential issue.

    Best,
    Matthew

  • RAM linker.txt
    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    MEMORY
    {
    PAGE 0 :
    /* BEGIN is used for the "boot to SARAM" bootloader mode */
    BEGIN : origin = 0x000000, length = 0x000002
    RAMM0 : origin = 0x000122, length = 0x0002DE
    RAMD0 : origin = 0x00B000, length = 0x000800
    RAMLS0 : origin = 0x008000, length = 0x002000
    // RAMLS1 : origin = 0x008800, length = 0x000800
    // RAMLS2 : origin = 0x009000, length = 0x000800
    // RAMLS3 : origin = 0x009800, length = 0x000800
    RAMLS4 : origin = 0x00A000, length = 0x001000
    RESET : origin = 0x3FFFC0, length = 0x000002
    PAGE 1 :
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Flash linker.txt
    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    MEMORY
    {
    PAGE 0 : /* Program Memory */
    /* Memory (RAM/FLASH) blocks can be moved to PAGE1 for data allocation */
    /* BEGIN is used for the "boot to Flash" bootloader mode */
    BEGIN : origin = 0x080000, length = 0x000002
    RAMM0 : origin = 0x000122, length = 0x0002DE
    RAMD0 : origin = 0x00B000, length = 0x000800
    RAMLS0 : origin = 0x008000, length = 0x000800
    RAMLS1 : origin = 0x008800, length = 0x000800
    RAMLS2 : origin = 0x009000, length = 0x000800
    RAMLS3 : origin = 0x009800, length = 0x000800
    RAMLS4 : origin = 0x00A000, length = 0x000800
    RAMGS14 : origin = 0x01A000, length = 0x001000 /* Only Available on F28379D, F28377D, F28375D devices. Remove line on other devices. */
    RAMGS15 : origin = 0x01B000, length = 0x001000 /* Only Available on F28379D, F28377D, F28375D devices. Remove line on other devices. */
    RESET : origin = 0x3FFFC0, length = 0x000002
    /* Flash sectors */
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Matthew,

    I have attached the RAM and flash linker files with which I attempted running my code.

    While running from Flash, I have the following lines of code in my code:

    In the declarations:

    Fullscreen
    1
    2
    3
    4
    extern unsigned int RamfuncsLoadStart;
    extern unsigned int RamfuncsLoadEnd;
    extern unsigned int RamfuncsRunStart;
    extern void InitFlash(void);
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    and in void main(), after InitSysCtrl() is called, I have this:

    Fullscreen
    1
    2
    memcpy(&RamfuncsRunStart,&RamfuncsLoadStart,&RamfuncsLoadEnd-&RamfuncsLoadStart);
    InitFlash();
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    (I was unable to upload the .cmd files, so I copied them onto notepad, sorry for the messy reply!)

  • Sanjay,

    Can you look in the file where InitFlash() function is defined(for me this is in F2837xD_SysCtrl.c) and make sure you see the following line near the top

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #ifndef __cplusplus
    #ifdef __TI_COMPILER_VERSION__
    #if __TI_COMPILER_VERSION__ >= 15009000
    #pragma CODE_SECTION(InitFlash, ".TI.ramfunc");
    #pragma CODE_SECTION(FlashOff, ".TI.ramfunc");
    #else
    #pragma CODE_SECTION(InitFlash, "ramfuncs");
    #pragma CODE_SECTION(FlashOff, "ramfuncs");
    #endif
    #endif
    #endif
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    This is what tells the linker that InitFlashI() is placed in the RAM section you have made.

    Since we are also dealing with ADC ISR timing, you also need to add the ADC_ISR function(s) to the above CODE_SECTION pragmas, so those will also get loaded to flash but ran from RAM.

    Let's see if the above helps, and we can go from there,

    Best,

    Matthew

  • Matthew,

    Yes, the SysCtrl.c file has the lines that you have shared.

    Regarding adding the adc_isr function to the code_section pragmas,

    Should it be done like this?

    Fullscreen
    1
    #pragma CODE_SECTION(adc_isr, ".TI.ramfunc");
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Thanks,

    Sanjay

  • Yes, it should just be the function name.  

    Can you also send(or C/P) the contents of the .map file that gets generated for each build?  It will be in the same directory as your .out file or one dir up.  It is just a plain text file that shows where all memory is getting allocated.

    Best,

    Matthew

  • /cfs-file/__key/communityserver-discussions-components-files/171/modifiedlinker.txt

    /cfs-file/__key/communityserver-discussions-components-files/171/5584.MAP-file.txt

    Matthew,

    I added the adc_isr function to the CODE_SECTION pragma. Initially I got an error, but I was able to resolve it by making RAMLS0 as one contiguous memory where the entire code could fit, and it built without issues.

    I have attached the .map file for this build, as well the modified flash linker file that I used.

    Also, I set a GPIO at the start and cleared it at the end of the adc_isr function to see how long it takes, and it is within 20us compared to the earlier case where it quit the ISR. Thanks for the help!

    Are there any other ways to optimize this further?

  • Sanjay,

    I haven't looked at the files yet, but some ideas on decreasing the time:

    1)Optimization level; right click on your .pjt and then select "properties" at the bottom.  This will bring up a new dialogue, go to Buiild->C2000 Compiler -> Optimization.  We typically recommend opt level 2/Global Optimizations.  You can try different slider option for speed/size tradeoffs, but we usually start with 2(which should be the default).  After you change this and Apply, you'll need to re-build the project to realize the improvements.

    1a)You'll also notice that floating point mode drop down.  If you have floating point operations in your ISR(or just code) you can set this to "relaxed" which will use the some optimized HW/SW routines to speed that up.  The difference is that "relaxed" mode does not strictly adhere to the ANSI C requirements for floating point operations.  You can read more about this here https://www.ti.com/lit/spry288 

    2)Code debug checks.  There is by default, many checks in the drivers for correct arguments and error handlers if there is some invalid options passed.  If your code is running correctly you can remove these(usually done before release).  In that same dialogue window we had open, go to "predefined symbols" still under C2000 Compiler.  Remove the DEBUG predefine from this list, and re-compile.  You should notice some improved performance here as well.

    I'll take a look at your maps, sometimes there are memory conflicts between program execution and data storage that can slow things down as well.

    Best,

    Matthew

  • Matthew,

    Thanks for the suggestions. I have incorporated them in my code. Did you find any issues with the maps?

  • Sanjay,

    I believe things look good now, there doesn't appear to be any memory conflicts that would slow things down due to arbitration.  One last thing, I see that RAMGS0 and RAMGS1 are defined twice

    SHARERAMGS0 : > RAMGS0, PAGE = 1
    SHARERAMGS1 : > RAMGS1, PAGE = 1
    ramgs0 : > RAMGS0, PAGE = 1
    ramgs1 : > RAMGS1, PAGE = 1

    You can check your main code, to see if these are referenced for run time use(like a buffer), just wanted to make sure we are not using twice with different names.  I think this would show up in the map, and I didn't see anything in those ranges at first pass, but thought I'd mention it.

    Best,

    Matthew

  • Matthew,

    Thanks for all the help!