Does Arduino serial use interrupts?

TLDR: Does Arduino's (Mega) Serial use an interrupt, which stops my program execution, to add a byte to its buffer?

Background:
I'm working on a program with the Arduino Mega that utilizes FreeRTOS. When each byte is received from a radio over serial it triggers an interrupt (radio at 115.2baud and receives a 25 byte message at least every 100ms). The interrupt adds the byte to a buffer then puts the message on a queue once it is validated so a scheduled task can process it accordingly. I'm getting weird behavior in the downstream tasks that process it despite verifying they're constructed OK. But, if I pause the stream of messages from the sending radio the odd behavior goes away and the receiver works as expected (executing the last task it received over radio). My suspicion is that the downstream tasks are being constantly interrupted.

Question:
If I were to switch from using my interrupt approach to polling Serial in a scheduled task, would the program still be interrupted every time a byte is received over serial? Or does Arduino handle that in the background using another method I don't know about?

Thanks, DeltaG.

I'm probably going to end up doing that since it'll make the implementation cleaner and accomplish the same thing.

Though at risk of sounding dense I'll just ask for clarification: with the interrupt that Arduino uses to handle pushing data to its buffer, that's essentially going to be the same wheel I reinvented on my own? (Firing on USART1_RX_vect and pushing UDR1 to a buffer).

Essentially I'm wondering if I can expect the same interrupt problem using the Arduino implementation instead of my own. If that's the case I'll need to reimagine how the program should work to get around that problem.

That's fair, thank you.
I appreciate your time.

The Arduino can put serial data into the built in serial transmit buffer without using interrupts. An interrupt is involved in transferring a byte from the transmit buffer to the UART hardware transmit register.

However, if the serial transmit buffer is full, the Serial.print() function will block until space becomes available. On the receiving end, it is my understanding that the oldest data in the serial input buffer is overwritten.

IMO that's a way to earn the problems of both worlds (Arduino and RTOS) due to the overhead on task switching. I'd go with polling in loop().

Thanks for that.

Is the same true for the receiving buffer? That it puts incoming serial data into the receiving buffer without using interrupts?

I'm looking at the ATmega2560 documentation and trying to find where it spells this out but haven't had any luck. I'll keep looking.

That transfer normally happens within the receive interrupt handler (UART receive data ready interrupt).

You have to study the Arduino core code relevant to your particular Arduino to be sure.

Believe me, I hear you.

I built a previous version of this application about 5 years ago and that's precisely what I did (if for no other reason than at that point I didn't even know what an RTOS was). That version worked well but suffered its own drawbacks, notably that it would occasionally miss messages if the loop took too long to get back to the polling step.

This version, which I'm building jointly with a buddy (experienced engineer in embedded systems) is an attempt to develop a more robust version of that. Moving to RTOS/interrupts instead of loop/poll (like my version) was an attempt to try and make sure we don't miss anything. But clearly it's got its own demons.

Yes.

I'm wondering if I can expect the same interrupt problem using the Arduino implementation instead of my own.

Hard to say, without a more complete description of "the problem" or seeing your code. I have not seen complaints about operation of t he Mega Serial ports, and 115200 is a very common bitrate.

Using your own ISR theoretically allows you to do the validation and message queuing in the ISR, without extra data copying, which may be valuable.

The Arduino/RTOS firmware uses interrupts for handling the embedded devices. If you want to replace these ISR by your own you have to update the entire device handler accordingly.

Just my point :frowning: