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.

CCS 6.1.1 debugger Step Over of a blocking function call in a TI-RTOS based AM4378 program hangs

Other Parts Discussed in Thread: AM4378

Was attempting to use the following combination to debug a TI-RTOS example for a AM4378:

- CCS 6.1.1.00022, running under Linux (CentOS 6.7 64-bit)

- The TI-RTOS based I2C_Example_idkAM437x_armExampleProject example from ti-processor-sdk-rtos-am437x-evm-02.00.00.00

- A MYD-C437X Development Board with an AM4378, using the IDK_AM437X Target Configuration (i.e. not the actual IDK_AM437X the example was written for, but the DDR3 configuration in the GEL files for the IDK_AM437X successfully initialize the DDR3 on the MYD-C437X)

- A Blackhawk USB560-M Emulator, 20-pin JTAG Cable

The issue is with debugging the following function:

void i2c_test(UArg arg0, UArg arg1)
{
    I2C_Params i2cParams;
    I2C_Handle handle = NULL;
    I2C_Transaction i2cTransaction;
    char txBuf[TX_LENGTH] = {0x00, 0x01};
    char rxBuf[RX_LENGTH] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                             0x00, 0x00};
    bool status;

    I2C_init();

    I2C_Params_init(&i2cParams);

    handle = I2C_open(I2C_EEPROM_INSTANCE, &i2cParams);

    i2cTransaction.slaveAddress = I2C_EEPROM_SLAVE_ADDR;
    i2cTransaction.writeBuf = (uint8_t *)&txBuf[0];
    i2cTransaction.writeCount = TX_LENGTH;
    i2cTransaction.readBuf = (uint8_t *)&rxBuf[0];
    i2cTransaction.readCount = RX_LENGTH;
    status = I2C_transfer(handle, &i2cTransaction);

    if(FALSE == status)
    {
        I2C_log("\n Data Transfer failed. \n");
    }

    I2C_close(handle);

    status = CompareData(&eepromData[0], &rxBuf[0], RX_LENGTH);
    if(TRUE == status)
    {
        I2C_log("\n EEPROM data matched \n");
        I2C_log("\n All tests have passed. \n");
    }
    else
    {
        I2C_log("\n Some tests have failed. \n");
    }

    while (1) {

    }
}

What happens is that if attempt to Step Over (F6) the status = I2C_transfer(handle, &i2cTransaction); line then the CCS debugger "hangs" with the Cortex-A9 status reported as "Running". The I2C_transfer invokes a blocking TI-RTOS call in which the calling task blocks on a semaphore until the I2C transaction is complete. If the Cortex-A9 is suspended once the Step Over has "hung" the debugger shows the current program counter is at the ldr r3, [r4, #4] instruction after the psid i instruction which has masked IRQs:

          ti_sysbios_knl_Task_schedule__I():
8000e320:   E92D4FF0            push       {r4, r5, r6, r7, r8, r9, r10, r11, lr}
8000e324:   E30C475C            movw       r4, #0xc75c
8000e328:   E3079D28            movw       r9, #0x7d28
8000e32c:   E3015CF8            movw       r5, #0x1cf8
8000e330:   E3072D30            movw       r2, #0x7d30
8000e334:   E3484001            movt       r4, #0x8001
8000e338:   E3489001            movt       r9, #0x8001
8000e33c:   E3485001            movt       r5, #0x8001
8000e340:   E24DD014            sub        sp, sp, #0x14
8000e344:   E3482001            movt       r2, #0x8001
8000e348:   E58D2004            str        r2, [sp, #4]
8000e34c:   E3A03000            mov        r3, #0
8000e350:   E5C43008            strb       r3, [r4, #8]
8000e354:   E5C43009            strb       r3, [r4, #9]
8000e358:   EA000002            b          #0x8000e368
8000e35c:   E12FFF33            blx        r3
8000e360:   E10F3000            mrs        r3, apsr
8000e364:   F10C0080            cpsid      i
8000e368:   E5943004            ldr        r3, [r4, #4]

Once in this state using Resume (R8) allows the program to complete the I2C_transfer call.

Some other variations in which the program executes without hanging are:

1) With the program halted prior to the execution of status = I2C_transfer(handle, &i2cTransaction), use Resume (F8) and the I2C_transfer call completes instantaneously.

2) With the program halted prior to the execution of status = I2C_transfer(handle, &i2cTransaction), use Run To Line (Ctrl-R) to run to the next statement, and the I2C_transfer call completes instantaneously.

Is the reason for the Step Over of the I2C_transfer "hanging" a bug, or a limitation of debugging TI-RTOS programs which use blocking operations?

  • Chester Gillon said:
    A Blackhawk USB560-M Emulator, 20-pin JTAG Cable

    I tried repeating the test using a Spectrum Digital XDS510 USB PLUS instead. With the change of emulator, then a Single Step over the status = I2C_transfer(handle, &i2cTransaction); statement worked without "hanging". However, not sure if this is just a timing issue, since the XDS100 USB PLUS seems noticeable slower in stepping than the USB560-M.

    [Also, when using the XDS510 USB PLUS, the download of the program fails most of the time, and the AM4378 target resets]

  • Chester Gillon said:
    What happens is that if attempt to Step Over (F6) the status = I2C_transfer(handle, &i2cTransaction); line then the CCS debugger "hangs" with the Cortex-A9 status reported as "Running". The I2C_transfer invokes a blocking TI-RTOS call in which the calling task blocks on a semaphore until the I2C transaction is complete.

    The I2C_transfer function starts a I2C transaction, and then blocks on a semaphore. An I2C interrupt is used to post a semaphore to notify the task that the I2C transaction is complete.

    The reason why the Step Over "hung" was that under the CCS Project Properties -> Debug -> Program/Memory Load Options -> Disable Interrupts "When source stepping" was enabled (the default). i.e. during the Step Over handling of interrupts was disabled.

    De-selecting the disabling of interrupts when source stepping then allowed the Step Over to work.

  • Chester,

    Thank you for posting an update and for explaining the root cause and solution for the behavior.