LPC11u67 hangs after several hours of usage

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

LPC11u67 hangs after several hours of usage

782 次查看
arty
Contributor II

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?

标签 (3)
2 回复数

615 次查看
victorjimenez
NXP TechSupport
NXP TechSupport

Hello  Arturas Jonkus,

You have to be really cautious when writing the handler of the interrupt. Mainly because carelessly written interrupts can lead to some run-time errors. There are several good practices to write a handler, for example: keep it short and simple, don't call functions inside a handler, don't call blocking functions (like memcpy)... 

I found a page (not from NXP) that explains this really good. I recommend you read the post and modify your handler following the practices that the post mention. 

Link to the post.

Hope it helps!

Victor.

-----------------------------------------------------------------------------------------------------------------------

Note: If this post answers your question, please click the Correct Answer button. Thank you!

----------------------------------------------------------------------------------------------------------------------- 

0 项奖励
回复

615 次查看
arty
Contributor II

I didn't write the code, just maintaining it, so there's not much I can do to rebuild it in more professional fashion. However, turns out that some memcpy() functions were unsafe (length was not limited) and there was an IAP call left (EEPROM write) which I finally found after extensive debugging and removed. Didn't do too much testing, but it seems everything should be okay now.