Software Serial Research and Questions

oqibidipo:
Never say "never" :wink: :

Jeez ... what a can of worms.

I will amend my earlier comment

...R

Is the following summary adequately describing the sequence of events on the serialEvent() issue?
1. The MCU is waiting in the loop() function.
2. Character arrives at the receiver of UART. (USART)
3. The MCU is interrupted and it goes to ISR due to USART_RX_vect. Here, the character is saved in the 64-byte wide FIFO.

4. From the ISR of Step-3, the MCU calls upon the serialEvent() SUR.
5. After finishing the serialEvent() SUR, the MCU goes back to ISR.
6. After finishing the ISR, the control goes back to loop() function.

//--------------------------------------------------------------------------
There are two places for data/string processing : void serialEvent(){} SUR or the loop() function.

A: If using void serialEvent() SUR

void serialEvent()
}
   byte x = Serial.read();
   if (x == end-of-string marker)
   {
       //do string processing
   }
       //making return to ISR
}

B: If using loop() function

void loop()
{
    if(Serial.avialable()>0)
    {
        byte x = Serial.read();
        if (x == end-of-string marker)
        {
            //data string processing
        }

    }
}

Question: Assume that the user is not doing any data processing in the serialEvent() SUR, that means that the user has not explicitly declared the serialEvent() SUR by the statement void serialEvent(){ //codes }; does the MCU still make a jump from ISR to the empty serialEvent() SUR?

You have the first three steps correct, but lose it for step 4-6.

GolamMostafa:
1. The MCU is waiting in the loop() function.
2. Character arrives at the receiver of UART. (USART)
3. The MCU is interrupted and it goes to ISR due to USART_RX_vect. Here, the character is saved in the 64-byte wide FIFO.
4. From the ISR of Step-3, the MCU calls upon the serialEvent() SUR.
5. After finishing the serialEvent() SUR, the MCU goes back to ISR.
6. After finishing the ISR, the control goes back to loop() function.

I'm not sure what loop() contains for programming so the response may be a little incomplete.

Yes Step 3, interrupts the MCU to process ISR USART_RX_vect.
No Step 4, ISR USART does not call serialEvent() (see post #36)
Which makes step 5 irrelevent.
Step 6, OK.

If loop() contains an infinite loop (ie., while (1) {}) then serialEvent() is never called. because it is not called from ISR USART_RX_vect but from serialEventRun() which is executed after completing loop() which never completes due to the infinite loop.

If loop() contains normal programming that ends then serialEvent() is called from serialEventRun() after the executing statements in loop().

In neither case is serialEvent() executed from SR USART_RX_vect. The the programming listed in post #4 for HardwareSerial.cpp is very old, circa 2011 and does not represent how the Arduino and HardwareSerial is programmed today. If you compare the code from post #34 to the files on your computer or to the snippets in post #36, you will notice substantial differences. We must ignore post #34 as it is so far out of date (apologies to @oqibidipo).

GolamMostafa:
Question: Assume that the user is not doing any data processing in the serialEvent() SUR, that means that the user has not explicitly declared the serialEvent() SUR by the statement void serialEvent(){ //codes }; does the MCU still make a jump from ISR to the empty serialEvent() SUR?

No on many counts.

If the user does not define serialEvent(), then there is not serialEvent() subroutine, therefore nothing to jump to from serialEventRun().

Secondly, the ISR does not call/jump to serialEvent(). serialEvent() is called from serialEventRun() see post #36.

GolamMostafa:
4. From the ISR of Step-3, the MCU calls upon the serialEvent() SUR.
5. After finishing the serialEvent() SUR, the MCU goes back to ISR.

No, you have this wrong. serialEvent() is not called from the ISR in recent versions of Arduino AVR Boards. Years ago it was but it is not now done that way. I haven't looked at how things are implemented in hardware packages other than Arduino AVR Boards.

This code reproduces what happens in a slightly simplified manner. Part of the simplification I've made is to only deal with Serial rather than Serial1-3 as actually happens but the other Serial interfaces are handled exactly the same.

int main(void)
{
  init();

#if defined(USBCON)
  USBDevice.attach();
#endif

  setup();

  for (;;) {
    loop();
    if (Serial.available()) {
      serialEvent();
    }
  }
  return 0;
}

GolamMostafa:
Question: Assume that the user is not doing any data processing in the serialEvent() SUR, that means that the user has not explicitly declared the serialEvent() SUR by the statement void serialEvent(){ //codes }; does the MCU still make a jump from ISR to the empty serialEvent() SUR?

Well, as I said, there is no call of serialEvent() from an ISR.

However, it is interesting to consider what happens when serialEvent() is not in use. This is not entirely clear to me because we have this strange construct:

if (serialEventRun) serialEventRun();

and:

if (Serial0_available && serialEvent && Serial0_available()) serialEvent();

serialEventRun() and serialEvent() are given the weak attribute in HardwareSerial.h/HardwareSerial.cpp. serialEventRun() is defined in HardwareSerial.cpp but serialEvent() is not defined anywhere in the core.
What I do know is that if you compile this sketch for Uno with Arduino IDE 1.8.5/Arduino AVR Boards 1.6.21:

void setup() {}
void loop() {}

The size is:

Sketch uses 444 bytes (1%) of program storage space. Maximum is 32256 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving 2039 bytes for local variables. Maximum is 2048 bytes.

If you compile this sketch:

void setup() {}
void loop() {}
void serialEventRun() {}

The size is:

Sketch uses 434 bytes (1%) of program storage space. Maximum is 32256 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving 2039 bytes for local variables. Maximum is 2048 bytes.

If you do a loop speed test you will also find the latter is something like 0.5 us faster. So there is overhead for this serialEventRun() call even when, as with 99.99% of Arduino users, you never use the serialEvent() feature. It's not a lot of overhead but I take any code that runs on every single loop seriously. Well at least there is a simple way to avoid the overhead.