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?