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.

RTOS/CC2640: UART callback Hard Fault

Part Number: CC2640

Tool/software: TI-RTOS

CC640 4x4 custom board, ble_sdk_2_02_01_18, tirtos_cc13xx_cc26xx_2_20_01_08,

CCS 6.2, XDS 200 debugger.

The custom application uses the UART driver in read callback mode. The UART receives

bytes one at a time. It also uses the SPI and ADC drivers. UART is only used during sensor

calibration to talk to an external processor through a wired connection.

When the ble stack was upgraded to use the ADC driver, the sensor would reach a

Hard fault forced busfault PRECISERR. When the upper limit on the timeout in the

bytes received through the UART was increased, this error went away.

However, a few debug statements were in the UART callback routines processed

through the RTOS queue (pasted below underlined and highlighted in bold). When

these statements were deleted, the bus fault error would happen again. Task stack

overflow is seen in the ROV if the bus fault happens but not otherwise.

These statements debug don't impact the sensor steady state processing. The sensor is

also able to sustain UART communication through a 3 hour calibration process and

resume steady state operation.

Why is the firmware sensitive to the presence of these debug statements? Does

this indicate a task stack overflow of some kind? Or do they help wake up the

UART driver activity in the functions processed through the RTOS queue?

The UART callback stops working when messages with more than one byte are

received unless the RTOS queue functions are woken up by these debug statements.

Thanks,

Priya

static void receiveUartMsg (uint8_t value)

{

    static uint8_t i, length = 5;

 

    System_printf("\nvalue=%x clkCntDiff=%d  clkCnt=%d prevClkCnt=%d", value, clkCnt-prevClkCnt, clkCnt, prevClkCnt);

 

 

 

static void UART_enqueueMsg(uint8_t value)

{

    sbpEvt_t *pMsg;

 

    // Create dynamic pointer to message.

 

    if (pMsg = ICall_malloc(sizeof(sbpEvt_t)))

    {

        pMsg->hdr.event = UART_MSG_EVT;

        pMsg->hdr.state = value;

 

        PIN_setOutputValue(PinHandle, Board_HGM_OUT, 1);

        // Enqueue the message.

        Util_enqueueMsg(appMsgQueue, sem, (uint8*)pMsg);

    }

}

 

static void SendUartMsg(void)

{

       // Talk Mode Confirmation

       if (uart_rx_buf[0] == 0x55) {

               uint8 txbuf[] = {0x07};

               UART_write(uart, txbuf, 1);

               PIN_setOutputValue(PinHandle, Board_HGM_OUT, 0);

               processingUARTMsg = 0;

               waitForUARTMessage();

               return;

           }

 

  • Priya,

    Would you mind zipping and sharing your application so that I could get a better understanding?

    When you receive the PRECISERR bus fault, which memory location is being accessed? This is either output to the console or stored in a BusFault Address Register (BFAR), 0xE000ED38.

    Derrick
  • Can I email you the zipped application? The address of the decoded exception was 0x3200310.
    This address did not lead to anywhere in the disassembly. I don't remember looking at the BFAR,
    maybe it will have the same address.

    I tried out some of the debugging from the BLE SDG that I posted here recently.

    e2e.ti.com/.../575078

    Thanks,
    Priya
  • Priya,

    In the debug perspective,  use the Breakpoints module to add a Hardware Watchpoint. Use the Location: 0x3200310 and Memory: Any.



    Run the application. The application should break where the attempt to read/write that memory location occurred.

    Derrick

  • Derrick,

    Three screenshots attached to this post:

    1. An error message about UART write polling that displays before application is

    debugged. (this message does not show up if the debug statements are in place,

    I commented them out today).

    2. Address of decoded exception as seen on ROV:

    3. Here is where the application halts after the HW breakpoint watch is added:

    I will send you the project shortly. I appreciate any insight you may have to share.

    Thank you,

    Priya

  • Priya,

    What type of behavior do you observe when you increase the baud rate?

    What if you replace the "Debug" statements with Task_sleep(5)?

    I also notice that malloc is being called from a Swi (UART read callback).

    Could you increase the stack size of the SimpleBLEPeripheral_taskFxn and observe the task stack peak in ROV?

    Derrick
  • Derrick--

    I was able to replace PIN_setOutputValue with Task_sleep(5).

    If the System_printf inside receiveUartMsg (uint8_t value) was

    left in place, the sensor is talking as it should. Replacing this with Task_sleep

    or deleting it led to the same hard fault error.

    I also increased SBP_TASK_STACK_SIZE to 800.

    With these edits in place, the sensor is responding to the external processor

    through the UART.

    Screenshot of task ROV is attached.

    I appreciate any insight you may have.

    Thank you,

    Priya

  • Priya,

    Just something to note in your recieveUartMsg and Clock_getTicks(): the value returned will wrap back to zero after it reaches the max value that can be stored in 32 bits.

    Based on observation, I suspect that UART_read() is being called numerious times, potentially increasing the stack size. System_printf() is an intensive call which takes a long time. The reason I suggested adding the Task_sleep() was to see if the System_printf() was simply causing an inadvertent delay. With that said, Task_sleep(5) may have been too short.

    Trying replacing the System_printf() with Task_sleep() of various times.

    I also notice that the task fxn labeled as "..." is still blowing it's stack but I have no been able to identify in your application what that is? Do you have any ideas?

    Derrick

  •  Derrick,

    32 bits in terms of 10 us  ticks translates to almost 12 hours in time.

    Let me know if this time translation is incorrect-- a successful calibration

    process won't take more than 2-3 hours.

    The drop down menu in the _ASM_ task is shown in the screenshot below.

    The data logging variables are not used in this version of the application.

    When and how often a real byte comes into the UART during calibration

    is not exactly known. Yes, the uart is being read continuously, through the

    callback won't happen until there really is a byte received.

    I will scope the time taken for system_printf to find out what delay

    this statement was providing. Hopefully it won't be so large that

    communication with the external processor is broken.

    Let me know if you need any further info or think of anything else.

    Thanks,

    Priya

  • Thank you Derrick for the customized project review and support!
    Your timely help is much appreciated.

    The hard fault exception was eliminated by using a uart task in the
    place of ongoing uart monitoring. There was a lot to learn in terms
    of debugging with CCS. And, that driver initialization will be thrown off
    if the user independently opens the PIN table.

    Priya