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.

C6748: Executing code from L1 RAM results in infinite loop in an if{ }else{} statement immediately following a trampoline function call.

Using L138 eXp Kit with the L138 SOM, code executing on the c6748 Core

PSP: 01_30_01    BIOS: 5_31_10_06    EDMA3_lld_01_11_03_01  CCS: 4.2.5  CGT: 6.1.20 & 7.0.5

Compiler options -mv6740 -g -O2   (everything else default settings other than include path searches)

I have decreased the L1P cache size (using the bios config tool) and created a user defined memory section (L1PROG) where I am placing several critical core algorithm functions.  Here is a snapshot of my memory map:

MEMORY CONFIGURATION

name        origin  length    used     unused attr fill
---------------------- -------- --------- -------- -------- ---- --------
IRAM       11800000 00040000 00032ba5 0000d45b RWIX
L1PROG     11e00000 00004000 00003040 00000fc0 RWIX
CACHE_L1P  11e04000 00004000 00000000 00004000 RWIX
L1DATA     11f00000 00004000 00003840 000007c0 RWIX
CACHE_L1D  11f04000 00004000 00000000 00004000 RWIX
L3_CBA_RAM 80000000 00020000 00000000 00020000 RWIX
DDR        c0000000 08000000 00064320 07f9bce0 RWIX

When the function is called, the code gets stuck in an infinite loop, repeatedly jumping back to the first instruction following a call to CLK_gethtime( ).  In looking at the assembly window, I can see the CALLP to the trampoline function, where the B3 register is set to the return address and the function call executes normally and returns.  A few assembly lines down, I see what seems to be the start of the If( ) statment, but then there is a BNOP.S2 B3,0 instruction, which puts me right back at the return location of the previous function call.  This happens indefinitely.  This happens for both the 6.1.20 and 7.0.5 tools.  Happens with -O1 optimization as well.

Below is the C code fragment and a picture of the dissassembly window associated with it.

// C code fragment.

    timeSpLNoiseEnd = CLK_gethtime();

    if (spectralLeak)
    {
       pWD = &aWeights[0];
       pWR = &bWeights[0];

Here is a snapshot of the dis-assembly window,  with the instructions in question circled in RED. 

 

Any thoughts? Ideas?  Is this the type of code you'd expect to see?  why the BNOP.S2  B3,0 back to the original return address?

Are there any other compiler settings I need to be aware of if  I am running part of my code in L1 RAM and the other in DDR?  From what I understand the newer compilers handle large jumps via the trampoline, so there is no longer a compiler option dealing with the code memory model.

thanks

-S

  • I think we need more context.  Notice the SPLOOP and SPKERNEL instructions, which the compiler generates for certain loops.  There is no loop in the C fragment you show.  Does this spot in the disassembly look the same just after loading the program, but before running it?

  • There is a for loop just after the if statement:

        if (spectralLeak)
        {
           pWD = &aWeights[0];
           pWR = &bWeights[0];
           pIC = pSpLInput;
           temp0 = 0;
           temp1 = 0;
           #pragma MUST_ITERATE(NUM_A_WEIGHTS,NUM_A_WEIGHTS,NUM_A_WEIGHTS);
           for (i = 0; i < (NUM_A_WEIGHTS); i++)
           {...

    The code looks the same just after loading (and running to main{}).  CCS is ignoring my debug option to not auto run to main{} when loading code, so this is the earliest I can look at the program space after loading.  Was your initial thought that the code space was being corrupt at run time?

    -S

  • Incidently, here is a snapshot of the disassembly window when the code is not directly placed into L1 PRAM.

     

  • You should be able to set a breakpoint at _c_int00, which will be before any instructions are executed.

    That code looks very different.  What else in the project changes when you move this code?  Did you change any compiler options?   Is a lot of other code dragged along?  The second screenshot doesn't show a trampoline.

    The first screenshot you show looks very strange, and not at all like what I would expect from the compiler, so I wanted to make sure we were looking at the compiler output.  The second screenshot looks more reasonable, but it's still such a tiny window into the problem that I'm reduced to guessing.  I can't say for sure whether the code looks reasonable without seeing both the C code and assembly code for the entire loop.

    So far, this does not look like any problem I'm familiar with, so more analysis is necessary.

  • OK,  thanks for the tip on putting the break point at _c_int00.  What I am finding now is that when hitting the break point at _c_int00 and viewing the code space, the code is correct, it looks more like snapshot of my second post, no unexpected branch instructions.

    Next, if I do a "go main", and stop at Main, the code space in that area becomes corrupt and it looks like the 1st snap shot.

    Next if I do a "reload program/go main" sequence, (even without the breakpoint at _c_int00), the code is correct.

    SO... it appears an issue with my tools/debug environment and as I think about it, it probably has something to do with the cache settings that are active when the code is 1st loaded (which are probably determined by the gel file executed after the "Connect to target" operation) compared to the cache settings that are active the 2nd time the code is loaded after running to main (which at that time would match the cache settings as set by the SW as it runs from _c_int00 to main).

    Thanks for pointing me in the right direction.  Can you move this thread over to a different forum?  Not sure if it should be the BIOS, CCS or 6748 forum, which do you suggest?

    -S

     

  • Okay, I'll move the thread. My best guess is the C67x single core DSP forum. If that's not right, someone there should know where to send you.

  • Shawn,

    Check your cache settings by reading the L1PCFG register at 0x01840020. Read it before loading your program, after loading your program when the PC is at _c_int00, and once the PC has reached main.

    If that is not the problem, then there may be something else in your linker command file or other configuration that is leading to the corruption.

    Regards,
    RandyP

  • Thanks Randy,

    Yes, it looks like I need to tweak my Gel file to set the cache register to the value that matches my intended use within my application. (looks like at power up the register is 0x0007, I need it to be 0x0003 for my particular use).   I did a test where I changed it by hand to 0x0003 after connecting to the target and then did a "load Program ->Go to Main", "run" sequence and the code is executing properly.

    Can you verify that the reset value of the L1PCFG register on the c6748 is 0x0007?

    Looking down the road, can I set the L1PCFG register via a boot record as the built in bootloader boots my application so that I know early in the boot process the entire cache is not being used or do I have to do something at runtime, as suggested by this wiki page:

    http://processors.wiki.ti.com/index.php/Putting_code_in_L1PSRAM

    thanks,

    -S

     

  • Shawn,

    For reset values, you need to trust the datasheet and not what I might tell you. Then again, I could not find the L1PCFG register reset value in the datasheet where it should be, per the Megamodule Reference Guide. So the way to find out is to get rid of all the GEL scripts and power up the board in NoBoot mode, then look at L1PCFG; try it again after pushing the reset button, and again after using the CCS reset feature. Let me know what you find out - I think it will be 0x7, but different devices could choose the 0x0 value.

    There may be a variety of ways to get code into L1P reliably. You can use the method described in the Wiki page or come up with your own. If you want to discuss alternate boot modes and secondary boot loaders and so on, it may be best to mark the best answer in this thread with Verify Answer, and then start a new thread with the new topic.

    Regards,
    RandyP

     

    If you need more help, please reply back. If this answers the question, please click  Verify Answer  , below.

  • Randy,

    Glad to know I'm not the only one who has trouble finding specific information about a specific register on a particular device among the horde of data sheets, user manuals, reference guides etc. for these DSPs.

    For now, it is not clear whether we will need to force certain code into L1PRAM in the long term.  My task at hand was to get CPU metrics on some algorithm components and I wanted to remove the variability introduced by the cache.

    If we need to pursue this further, I will open a new thread. 

    Thanks for your help.

    -S