AnsweredAssumed Answered

LPC11u67 hangs after several hours of usage

Question asked by Arturas Jonkus on Sep 4, 2018
Latest reply on Sep 7, 2018 by Arturas Jonkus

Hi there!

 

I'm building a device that is communicating to a master device via USART0. However, it breaks after some hours of usage (this can differ from several hours to several days). I cannot connect USB which usually works at beginning of code execution. Reseting device works, but only for some time.

 

I attached a debug probe to see what makes it hang expecting to get a HardFault or at least some useful information. What I found out is that HardFault is never generated, yet debugging session breaks directing me to some addresses in RAM, information not very useful to me. Adding watchdog didn't seem to reset a device therefore I turn to you to get more insights about what could have gone wrong.

 

A team meeting got to conclusion that it's probably something in USART handler therefore I am going to show this handler:

 

void USART0_IRQHandler(void)
{
    WDTReset();
    /* Handle receive interrupt */
    Chip_UART0_RXIntHandlerRB(LPC_USART0, (RINGBUFF_T*)&board_uart_rx);
    char ch;
    int waiting = 0;
    if ((!RingBuffer_IsEmpty((RINGBUFF_T*)&board_uart_rx))
            && (RingBuffer_GetCount((RINGBUFF_T*)&board_uart_rx)) != 14)
    //TODO: !=14 is workaround for UART FIFO. if received 14, need to wait some time, and accept it
    //eventually
    {
        IEC_103_Handle((RINGBUFF_T*)&board_uart_rx, (RINGBUFF_T*)&board_uart_tx);
        if (!RingBuffer_IsEmpty((RINGBUFF_T*)&board_uart_tx))
        {
            RingBuffer_Flush((RINGBUFF_T*)&last_telegram);
            Chip_UART0_IntEnable(LPC_USART0, (UART0_IER_RLSINT | UART0_IER_THREINT));
        }
    }

 

    switch (RingBuffer_GetCount((RINGBUFF_T*)&board_uart_tx))
    {
        case 0:
            SetRSMode(0);
            Chip_UART0_IntDisable(LPC_USART0,( UART0_IER_RLSINT | UART0_IER_THREINT));
            break;

 

        case 1:
            SetRSMode(1);

 

            __disable_irq(); // do it atomically

 

            RingBuffer_Pop((RINGBUFF_T*)&board_uart_tx, &ch);
            RingBuffer_Insert((RINGBUFF_T*)&last_telegram, &ch);

 

            __enable_irq();
            Chip_UART0_SendByte(LPC_USART0, ch);
            break;

 

        default:
            SetRSMode(1);
            // Fill FIFO until full or until TX ring buffer is empty
            __disable_irq(); // do it atomically

 

            while ((waiting = RingBuffer_GetCount((RINGBUFF_T*)&board_uart_tx) > 1)
                && ((Chip_UART0_ReadLineStatus(LPC_USART0) & UART0_LSR_THRE)!= 0 )
                && RingBuffer_Pop((RINGBUFF_T*)&board_uart_tx, &ch))
            {
                RingBuffer_Insert((RINGBUFF_T*)&last_telegram, &ch);
                Chip_UART0_SendByte(LPC_USART0, ch);
            }
            __enable_irq(); // do it atomically

 

        break;
    }
}

 

What can break LPC without a hardfault? Can a memcpy function do it?

Outcomes