9 years, 5 months ago.

Conflict between UART/Serial Rx interrupt and USBSerial output on FRDM-KL25Z?

On my FRDM-KL25Z project I'm getting what seems to be a conflict between UART/Serial Rx and my TTY output to the USBSerial.

I narrowed it down to a more reliable repro by writing a constant flow of bytes to the UART (i.e. from an external source of input), and in a loop on the KL25 reading and writing to/from the UART and logging out to the USBSerial (I was logging out the received bytes, but simplified that down to just a dot each time). What happens is that after a number of bytes are read (the number differs from run-to-run, ranging from a few to fifty-odd), the TTY output stops mid-write and the chip seems to be hanging - though is in fact still running, but just never getting back to my main loop.

(Snippets, trimmed down for brevity)

USBSerial tty;
Serial uart(PTE0, PTE1);   // Not shown here, but this is attach'd to the handler below
uint8_t b;

int main()
{
    uint64_t c64 = 0;

    while (1)
    {
        uart.putc((uint8_t)c64);
        tty.puts(".");    // Also breaks using putc('.')
    }
}

void SerialRxCallback()
{
    do
    {
        int c = uart.getc();
        
        if (c != EOF)
        {
            // Do something with it...
            b = c;
        }
        
        if (c==EOF)
            break;    // If we don't break, readable keeps returning true, and getc keeps returning -1
    }
    while (uart.readable());
}

When this code runs, a number of dots comes out and then the chip seems to have locked. From the debugger, I can see the stack is something like:

  • SerialRxCallback (i.e. my handler)
  • ...
  • _irq_handler
  • uart_irq
  • uart1_irq
  • ...
  • Stream::putc
  • main

It looks like the TTY output to USB is being interrupted by the UART callback/interrupt and fails. After the apparent lock, I can breakpoint the rx callback and it hits it: I can see that getc is constantly returning -1 (i.e. EOF), and it never returns anything different on later attempts. Also, readable() always returns true, but as I say, the getc is never a valid character again.

If I breakpoint main, it never comes out of the putc function - although the UART callback/interrupt does get called as I describe above so something is running still.

Much scouring of the web hasn't got me much in understanding why the uart starts returning EOF/-1, and I can't figure how I might get out of the state or in fact not get into the state in the first place!!!

Any help greatly appreciated!

Jon

Be the first to answer this question.