5 years, 10 months ago.

How to clear the Serial::RxIrq without calling getc()

Ah, I was a little confused thinking the readable() was spin locking but it doesn't. So yes, I understand this solution. Thanks

1 Answer

5 years, 10 months ago.

Hello Kevin, So the Mbed OS required you to do a getc() so that you can clear the Rx buffer. Otherwise, if you do resolve the interrupt and letting the EventQueue handle the buffer clearing, incoming data will eventually overflow the Rx buffer and be lost before the EventQueue will be able to handle reading from serial. Therefore, if you want to have the EventQueue handle the word processing, then you can write an interrupt handler that does the getc() from serial and move the data to another buffer that the EventQueue will eventually handle and process at a later time. This can be done by calling the attach function in the Serial class and passed the interrupt handler function that you want to call when Rx is trigger. Example:

Serial Interrupt Example

#include "mbed.h"
.......
int main() {
.......
// Setup a serial interrupt function to receive data
    device.attach(&Rx_interrupt, Serial::RxIrq);
// Setup a serial interrupt function to transmit data
    device.attach(&Tx_interrupt, Serial::TxIrq);
.........}

.......
.......
.......
// Interupt Routine to read in data from serial port
void Rx_interrupt() {
    led1=1;
// Loop just in case more than one character is in UART's receive FIFO buffer
// Stop if buffer full
    while ((device.readable()) || (((rx_in + 1) % buffer_size) == rx_out)) {
        rx_buffer[rx_in] = device.getc();
// Uncomment to Echo to USB serial to watch data flow
//        monitor_device.putc(rx_buffer[rx_in]);
        rx_in = (rx_in + 1) % buffer_size;
    }
    led1=0;
    return;
}

// Interupt Routine to write out data to serial port
void Tx_interrupt() {
    led2=1;
// Loop to fill more than one character in UART's transmit FIFO buffer
// Stop if buffer empty
    while ((device.writeable()) && (tx_in != tx_out)) {
        device.putc(tx_buffer[tx_out]);
        tx_out = (tx_out + 1) % buffer_size;
    }
    led2=0;
    return;
}
.....

here is the link to the example above that you can use as a reference: https://os.mbed.com/users/4180_1/code/Serial_interrupts/

Thank you,

Peter, Mbed Team

Accepted Answer

So, I'm curious about this solution. My experience is that if I have a thread in a loop always checking device.readable(), readable actually spins and uses thread time until something comes in. So if there is nothing to read, device.readable() will not return. Won't this lock up the ISR?

posted by Kevin McQuown 13 Jun 2018

So there is two way that you can check to see if there is data in the buffer or not. The first one (the one that you are using) is call busy-wait polling. This is where you have a while loop that constantly checking for data input. This technique is usually use for single thread application or you need to block other thread from working until you have an input. The other way is to do interrupt where you allowed other threads to run while you wait for incoming data.

posted by Peter Nguyen 13 Jun 2018