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.

TMDSLCDK6748: Program from new CCS project hangs

Part Number: TMDSLCDK6748
Other Parts Discussed in Thread: OMAPL138

Hi

I have created a new project in CCS with the following simple program:

int main(void)
{
    int i;
    int j = 0;

    for(i = 0; i < 1000000; i++)
    {
        j++;
    }

	return 0;
}

After some time the program hangs (it seems to be at a random point) and when the debugger is suspended then it shows:

No source available for "0xc3d38e84"

But this address is DDR2, while the linker command file specifies Shared RAM. The main function has address 0x80000ee0, which is in Shared RAM, as expected. I have used an existing RTSC successfully, but I want to have a CCS project.

What is going on? Am I forgetting something?

I am using the following hardware and software:

TMDSLCKD6748

XDS100v2 JTAG 14-pins

CCS Version: 7.2.0.00013

I have attached the CCS project-files.1222.TryDspL2RAM.zip

Best regards

Ad

  • Hi,

    I've notified the sw team. Their feedback will be posted here.

    Best Regards,
    Yordan
  • I checked the map file and there is no code or data section in 0xc3d38e84. Can you setup break point at return 0 and see if the code reaches there.

    Are you sure that the error not caused because the after the main completes the control is transferred to that PC location by the exit/abort function.
    Adding printf at the end of code execution will also help indicate if the program runs to completion, which i believe it does.

    Regards,
    Rahul
  • Hi Rahul,

    Thanks for the tip. I have already tried that before, but now I have applied the changes you suggested again: I have change the program to:

    #include <stdio.h>
    
    int main(void)
    {
        int i;
        int j = 0;
    
        for(i = 0; i < 1000000; i++)
        {
            j++;
            printf("j = %d\n", j);
        }
    
        printf("End: j = %d\n", j);
    
    	return 0;
    }
    

    and this is the output:

    [C674X_0] j = 1
    j = 2
    
    ...
    
    j = 159
    j = 160
    

    I have omitted the lines in between, but "j = 160" is the last line. I have ran it 4 times and each time the last printed number j is different: 160, 99, 151 and 137.

    Then the debugger was suspended and stopped at 0xc3d38384 and this is the assembly:

    c3d38e10:   00000000            NOP           
    c3d38e14:   00000000            NOP           
    c3d38e18:   00000000            NOP           
    c3d38e1c:   00000000            NOP           
    c3d38e20:   013C62E6            LDW.D2T2      *+SP[3],B2
    c3d38e24:   023C22E4            LDW.D2T1      *+SP[1],A4
    c3d38e28:   023C42E6            LDW.D2T2      *+SP[2],B4
    c3d38e2c:   01BC92E6            LDW.D2T2      *++SP[4],B3
    c3d38e30:   00000000            NOP           
    c3d38e34:   00080362            B.S2          B2
    c3d38e38:   00008000            NOP           5
    c3d38e3c:   00000000            NOP           
    c3d38e40:   001018F3            OR.D2X        0,A4,B0
    c3d38e44:   0001C228 ||         MVK.S1        0x0384,A0
    c3d38e48:   0061EBE9            MVKH.S1       0xc3d70000,A0
    c3d38e4c:   000C0362 ||         B.S2          B3
    c3d38e50:   37800266     [!B0]  LDW.D1T2      *+A0[0],SP
    c3d38e54:   30000276     [!B0]  STW.D1T2      B0,*+A0[0]
    c3d38e58:   00004000            NOP           3
    c3d38e5c:   00000000            NOP           
    c3d38e60:   01900264            LDW.D1T1      *+A4[0],A3
    c3d38e64:   008C6362            BNOP.S2       B3,3
    c3d38e68:   018FE058            SUB.L1        A3,1,A3
    c3d38e6c:   01900274            STW.D1T1      A3,*+A4[0]
    c3d38e70:   00000000            NOP           
    c3d38e74:   00000000            NOP           
    c3d38e78:   00000000            NOP           
    c3d38e7c:   00000000            NOP           
    c3d38e80:   00000000            NOP           
    c3d38e84:   0001A120            BNOP.S1       0xC3D38E84 (PC+4 = 0xc3d38e84),5
    c3d38e88:   00000000            NOP           
    c3d38e8c:   00000000            NOP           
    c3d38e90:   00000000            NOP           
    c3d38e94:   00000000            NOP           
    c3d38e98:   00000000            NOP           
    c3d38e9c:   00000000            NOP           
    c3d38ea0:   31F7                STW.D2T2      B3,*B15--[2]
    c3d38ea2:   0627     ||         MVK.L2        0,B4
    c3d38ea4:   1FFFB813 ||         CALLP.S2      0xC3D38C60 (PC-576 = 0xc3d38c60),B3
    c3d38ea8:   0726     ||         MVK.L1        0,A6
    c3d38eaa:   71F7                LDW.D2T2      *++B15[2],B3
    c3d38eac:   0626                MVK.L1        0,A4
    c3d38eae:   4C6E                NOP           3
    c3d38eb0:   008CA362            BNOP.S2       B3,5
    c3d38eb4:   00000000            NOP           
    c3d38eb8:   00000000            NOP           
    c3d38ebc:   E1A00003            .fphead       n, l, W, BU, nobr, nosat, 0001101
    c3d38ec0:   02906059            ADD.L1        3,A4,A5
    c3d38ec4:   0FF92410 ||         B.S1          0xC3D357C0 (PC-14048 = 0xc3d357c0)
    c3d38ec8:   03140264            LDW.D1T1      *+A5[0],A6
    c3d38ecc:   0190E058            ADD.L1        7,A4,A3
    c3d38ed0:   02101FD8            OR.L1X        0,B4,A4
    c3d38ed4:   020C1FDA            OR.L2X        0,A3,B4
    c3d38ed8:   00000000            NOP           
    c3d38edc:   00000000            NOP           
    c3d38ee0:   010C1FD9            OR.L1X        0,B3,A2
    c3d38ee4:   1FED8C13 ||         CALLP.S2      0xC3D2FB40 (PC-37792 = 0xc3d2fb40),B3
    c3d38ee8:   030000A8 ||         MVK.S1        0x0001,A6
    c3d38eec:   0088B362            BNOP.S2X      A2,5
    c3d38ef0:   00000000            NOP           
    c3d38ef4:   00000000            NOP           
    c3d38ef8:   00000000            NOP           
    c3d38efc:   00000000            NOP           
    c3d38f00:   008C6363            BNOP.S2       B3,3

    The instruction at is BNOP.S1 0xC3D38E84 (PC+4 = 0xc3d38e84),5 and this is always a branche onto itself, which is confirmed by using Assembly Step Into (Ctrl-SHift-F5) that always stays at the same address.

    Now I guess that the assembly shown above in DDR2 memory is not real code, but merely the result of random bits in unitialized DDR2. Now the question is: why does the program jump to an address in DDR2? Could it be an interrupt that has been initiated in the boot entry code (i.e. the code that calls the main function)?

    Regards,

    Ad

  • I was looking at the difference in the boot entry code (i.e. the code that calls the main function) for RTSC projects and CCS projects using PSDK (RTOS 4.0, see software-dl.ti.com/.../index_FDS.html). The boot.c file for RTSC is located in:

    C:\ti\bios_6_46_05_55\packages\ti\targets\rts6000\boot.c

    and the boot.c file for CCS is located in:

    C:\ti\ti-cgt-c6000_8.1.3\lib\src\boot.c

    The code that is missing in the CCS boot.c file is:

        /*
         *  Clear CSR and IER register.  This is necessary to prohibit interrupts
         *  from being enabled and left-over interrupts from being serviced.
         */
        __asm("\t  ZERO\t\t  B0");
        __asm("\t  MVC\t\t   B0, IER");
        __asm("\t  MVC\t\t   B0, CSR");
    
    

    which explains the problem I was having. When I copied the code above to the beginning of the main function, then the problem was solved.

    So there is a bug in the CCS boot.c code: the instructions as shown above are missing. The workaround is to add these instructions to the beginning of the main function, but they should be placed in the boot.c file at the most early point in code execution.

    Rahul, can you file this as a bug for RTOS 4.0 so that it will be solved in next versions?

    Thanks in advance.

    Regards,

    Ad.

  • Thanks for posting the root cause here. It appears that this is a compiler bug so I will work with the compiler team to resolve this. We will need to check if the newer 8.x compilers alsos have this issue.

    Regards,
    Rahul
  • I apologize for the delay.

    Ad van de Voort said:

    The code that is missing in the CCS boot.c file is:

        /*
         *  Clear CSR and IER register.  This is necessary to prohibit interrupts
         *  from being enabled and left-over interrupts from being serviced.
         */
        __asm("\t  ZERO\t\t  B0");
        __asm("\t  MVC\t\t   B0, IER");
        __asm("\t  MVC\t\t   B0, CSR");

    This boot routine has been in the field for 20+ years.  It has never touched these control registers.  In fact, anything outside of the core CPU operation is not modified.  This policy has worked well over these many years.  So please understand why we are very reluctant to change it now.

    Thanks and regards,

    -George

  • Hi George,

    Thanks for looking at the problem.

    This is clearly a bug: the program hangs after a while. The fact that it has been in the field for 20+ years is never a good argument: other software parts and hardware change all the time, furthermore different usage of the code can reveal bugs that have been there from the beginning. As can be seen on the forum: other people are experiencing this problem as well. I understand that you are careful to change the code, but not fixing bugs means that you simply stopped maintaining the code and that the code is becoming obsolete.

    Since I am not the owner of this code (obviously) I can not decide whether to change this code or not, but I just wanted to let you know my opinion: as a summary: I think this bug needs to be fixed. If you think that it must be fixed in other parts of the software (or in hardware), then please let me know.

    Best regards,

    Ad

  • I am also concerned about our user base, which by this point numbers in the 1000s.  They depend on this boot routine to do exactly what it does, and no more.  Any change in behavior is likely to cause problems for at least some of them.  

    Regarding the policy to initialize only the main CPU registers the compiler explicitly depends on ... Suppose we violate this policy for the interrupt control registers.  Why stop there?  What about the external memory interface, cache control registers, other peripherals?  Keep in mind these registers work differently on different devices.  This policy separates the boot routine from all of those details.

    If you would like, I would be happy to file a request that the boot routine be changed to provide boot hook functions.  The boot routine would call one hook near the start, and one near the end.  A default implementation of these hook functions, which do nothing, would be provided.  But a user could supply their own, custom, implementation of these hook functions.  And that implementation could perform initialization specific to the device and system.

    Thanks and regards,

    -George

  • Hi George,

    I understand your concerns. In an earlier message I said that there is a bug in boot.c (because I saw that RTSC projects solved it that way), but that is not necessarily correct. So maybe the problem should not be solved in boot.c, but elsewhere. I saw that the hardware sets the registers IER and CSR to zero upon reset, so maybe it is something else that leaves these registers in an undefined state (maybe the boot loader?). I appreciate the offer to provide hook functions, but that would not be necessary, because there is a workaround to set these registers to 0 in the main function. But it would be better if this problem is solved. Can you pass this bug-fix-request to the colleague who is responsible for it? Thanks.

    Best regards,

    Ad
  • Ad van de Voort said:
    appreciate the offer to provide hook functions, but that would not be necessary, because there is a workaround to set these registers to 0 in the main function. But it would be better if this problem is solved.

    I'm confused.  The solution I propose is the hook functions.  I can file a request that they be added to the boot routine.  Note the big advantage: These hook functions could never cause problems for existing code.  Would you like me to file this request?

    Thanks and regards,

    -George

  • The current situation with the Processor SDK RTOS 4.0.0.4 is that for every new CCS project the programs hangs after some time. This can be solved with the workaround I described above, or, it can be solved with the hook functions you suggested. For myself it is no longer a problem I can use the workaround in main and I just have to remember to add the workaround to each new CCS project. But I was thinking in the interest of all new users and of TI to solve serious bugs. New users will run into problems because they are experiencing a bug and they do not know the workaround: either the main-workaround or the hook functions workaround. Now you can document the workarounds, but - in my opinion - it is much easier to solve the bug so that everyone can use new CCS projects right out of the box, without the need to implement a workaround. I hope this explanation was more clear.

    Best regards,

    Ad

  • Ad,

    Based on what you are reporting, I setup the project and the only time, I can reproduce the issue is when I do the first power on reset and setup the GEL files. 

    All subsequent load and run seem to go to the abort function after the code returns correctly. I am under the impression that this occurs because you have some code flashed on the NAND flash on the LCDK platform that boots during the first POR that is leaving the device in a unclean state. A good way to confirm this is report the Program counter the first time you connect to the device. If the PC is in 0xcXXXXXXX range or 0x8XXXXXXXX range then there is some code that loaded on the DSP from flash.

    This means that you are not loading your code in NOboot or UART boot mode in which the DSP will not load code from flash. The other way to work around this is to issue a CPU reset after the GEL file has run that puts the CPU in a clean state.

    Boot Switch setting: http://processors.wiki.ti.com/index.php/L138/C6748_Development_Kit_(LCDK)#User_Interface 

    Please try this option and let us know if the problem is resolved.

    Regards,

    Rahul

  • Rahul,

    I do not completely understand your answer, but I have done the following:

    • start CCS on the PC
    • create a new CCS project: Empty Project (with main.c)
    • add linker command file C6748.cmd
    • build
    • power on the TMDSLCDK6748
    • run the debugger and wait for it to stop at main

    At this point when I look at the view Registers the PC indicates a value of 0xC0004740 and if a press the reset button on the TMDSLCDK6748 the PC value changes to 0x00700000.

    I am using hardware: TMDSLCDK6748 (without any changes to Flash) and XDS100v2 JTAG 14-pins; and, software: CCS Version: 7.2.0.00013 and processor_sdk_rtos_omapl138_4_00_00_04.

    Regards,

    Ad

  • I forgot to mention the values of registers CSR and IER:
    after debugger start: CSR=0x14000103, IER=0x00004003
    after pressing reset button: CSR=0x14000100, IER=0x00000001
    Ad
  • Ad van de Voort,

    Let me try and provide more context. In order to fully understand my comment, you need to understand the boot flow of the DSP.

    When the DSP is reset, the ROM bootloader software on the device will read the Boot switch settings to identify if the DSP need to boot from a boot media. If the boot switch is configured to boot from flash, the device initializes the device clocks and boot media peripheral and tries to read/find a boot image on it. If it finds a image, it will load the image setup the device as required by the application and then pass control to the application that loaded from flash.

    In your case, when you are connecting to the DSP, the core is executing code in onchip memory or DDR region, this indicates that there is an application on the flash that booted when you did a power on reset. The ideal way to work around this is to set the boot switches to NO boot or emulation boot mode or to a boot mode that doesn`t have an boot image flashed on it so that the DSP core is stuck in the boot ROM when you connect the emulator and no device initialization or application configuration is running and the DSP is in a clean state.

    On the LCDK, we don`t have emulation boot mode but we have UART boot mode which can be used instead. When the device boots in UART boot mode, the device will setup PLL and UART to boot at 115.2 kbps but when it doesn`t find an image coming from UART, it will keep spinning in the BootROM. at this point if you connect and run the GEL file, the DSP should be in a clean state.

    Note that the LCDK comes with pre-programmed NAND flash, so if you have SW1 set to NAND boot as described in Quick start guide, you will see the DSP boot a TI RTOS application from NAND and the DSP PC at 0xCXXXXXXXX. Please change the SW1 setting and try this setup. When you connect the DSP, you should see it executing in L2 ROM region [0x700000 - 0x7F FFFF]

    Hope this helps clarify my earlier comments.

    Regards,
    Rahul

    PS: Bootloader app note:

    http://www.ti.com/lit/an/spraat2f/spraat2f.pdf

  • Hi Rahul,

    Thanks for you explanation, it is very clear.

    I have been looking for the Emulator boot mode for the TMDSLCDK6748 development kit, however, as I could not find one I assumed that starting the emulator would perform a hardware reset, but apparently that is not the case. So I have tried to set the board to UART2 boot mode and indeed this solves the problem: the registers CSR and IER have their reset value at start and the program no longer hangs. To use the UART2 boot mode for the emulator is the crucial information that is missing in the documentation.

    Regards,

    Ad

  • Thanks for confirming that this is not a compiler issue. I have updated the documentation here:
    processors.wiki.ti.com/.../AM1808_EVM_board_using_CCS?

    Hope this helps.

    Regards,
    Rahul