Is returning from loop() mandatory?

This is just curiosity. The design could have been different. For instance, things could have been left the way they are, and instead of making the presence of setup() and loop() function mandatory, it could have been main() with a mandatory call to something like init_board().

So why the current design? Is there some extra processing the board must do from within the main loop? Is it mandatory to quickly and frequently return from loop() for the board operation? Apart from being considered a logic error, what would happen if I were to block in loop() for a long time, awaiting an input or data from an interface?

loop() is called repeatedly by a hidden main() function created by compiling in the IDE. Having a function which automatically loops is designed to help bearing in mind that the main purpose of a microcontroller is to loop reading sensors and to react to inputs.

If you block the loop() functionwhile(1){}the code will simply stop at that point.

It isn't mandatory to return from loop(), but don't expect serialEvent() to work if you don't return.

Namaan:
This is just curiosity. The design could have been different.

True.

Return from loop if you want to. Don't if you don't.

The idea of setup() and loop() was to try to teach the idea of initialisation and repeated actions.

Having a function called loop() reinforces the fact that a microcontroller doesn't ever STOP executing its program.
(unlike a desktop, where if you call exit() or return from main(), then your program's responsibilities are over...)

Exactly. When your Arduino "crashes" it hasn't really stopped working. It's just doing something different to what you want it to. :slight_smile:

Thank you all from all your quick replies :).

I understand the implications of having mandatory setup() and loop() functions instead of a mandatory init_board() in a classical main() function.

While this choice may have been made for "political" reasons (teaching, being more user-friendly, etc.) it may also have been made for practical reasons: the arduino software needs to do some stuff on a regular basis. This is what I seek to know.

Opinions on whether the program is performing extra work between calls to loop() is divided. Is there somewhere I can find the source code for the boor loader or for the actual main() function? Or somewhere I can find what actually happens when powering on the board? How does the board know at startup if it should run its software or expect to be reprogrammed?

Opinions on whether the program is performing extra work between calls to loop() is divided

It is?
It looks pretty clear to me:

#include <Arduino.h>

int main(void)
{
	init();

#if defined(USBCON)
	USBDevice.attach();
#endif
	
	setup();
    
	for (;;) {
		loop();
		if (serialEventRun) serialEventRun();
	}
        
	return 0;
}

(Arduino-1.0.5/hardware/arduino/cores/arduino/main.cpp
bootloader source is in Arduino-1.0.5/hardware/arduino/bootloaders)
The

Thank you for your reply.

By opinion are divided, I meant:

VS

AWOL:
It isn't mandatory to return from loop(), but don't expect serialEvent() to work if you don't return.

From the source, it looks like it's important to return from loop() ASAP. I thought that serial events were based on interrupts and that I could receive data "even when doing something else"?

No, serialEvent has very little to do with interrupts.
If you don't use serialEvent, you don't have the return from "loop".
If you do use serialEvent, you have to make sure that one iteration of "loop" doesn't take more than 64 times one serial character period.

Well, looks like there is something I am missing.
I thought that the serial communication through the FTDI chip was tied to an interrupt, so that the board can receive and process serial data even when it's doing something else. For instance, the documentation for the delay function states:

Certain things do go on while the delay() function is controlling the Atmega chip however, because the delay function does not disable interrupts. Serial communication that appears at the RX pin is recorded, PWM (analogWrite) values and pin states are maintained, and interrupts will work as they should.

But from the documentation of SerialEvent(), it looks like a call to SerialEvent() is required for this to work. So, if I do not return from loop() soon enough, the board won't be able to communicate with the computer? Will I loose all serial communication?

I thought that the serial communication through the FTDI chip was tied to an interrupt

It is.
The interrupt service routine buffers the incoming data in a circular buffer.

But from the documentation of SerialEvent(), it looks like a call to SerialEvent() is required for this to work

No, not at all.
You can use serialEvent or ignore it. If I'm honest, I'm not sure why it is there.

Thanks. Looking at the code, it looks like the function serialEventRun() may not be defined at runtime. First the program checks for it, then it is called.
I'll keep looking.

Looks like the function is defined in HardwareSerial.h and implemented as:

void serialEvent() __attribute__((weak));
  void serialEvent() {}
  #define serialEvent_implemented

It's doing nothing. Maybe for compatibility with legacy code?
So, I can safely ignore it, and I don't need to bother monitoring the time it takes for me to complete one loop ?

I think you're misunderstanding.
You, if you wish, provide a function called "serialEvent" that is called by "serialEventRun" in "main" if there is any serial data available to read.
Your "serialEvent" then can read and if necessary parse the incoming data, without directly involving the code in "loop"

If you don't provide a "serialEvent", that's OK.

OK! I think I get it now! It is just a convenience. I have the choice between:

void loop()
{
  // I do my stuff
  …

  // I process my serial events
  …
}

and

void loop()
{
  // I do my stuff
  …
}

void serialEvent()
{
  // I process my serial events
  ...
}

Both are the same (assuming that loop() returns of course)?

AWOL:

I thought that the serial communication through the FTDI chip was tied to an interrupt

It is.
The interrupt service routine buffers the incoming data in a circular buffer.

From this discussion, am I to understand that the serial buffer was implemented in the AVR chip itself, and not in the FTDI chip? If that's the case, did things change between then and the advent of the ATMEGA16U2? For some reason, I thought that the serial buffer was contained in the ATMEGA16U2.

From this discussion, am I to understand that the serial buffer was implemented in the AVR chip itself, and not in the FTDI chip?

The circular buffer is in RAM, so yes, in the AVR chip.

I do not have any Arduino hardware. I am new to it, started on thursday, placed an order for a few boards yesterday.

Meanwhile, I try to implement the program, since I do not need the board to write the code. So I may not be the best person to answer.

That said, I was just reading that some boards (the older ones) have an FTDI chip to handle the serial communication whereas on more recent boards, such as the leonardo, it is integrated in the AVR chip. This has some side effects, which are listed here: http://arduino.cc/en/Guide/ArduinoLeonardoMicro?from=Guide.ArduinoLeonardo

I have used the Arduino Uno and the Mega2560, and all boards I have worked with do not have the FTDI chip, but do have a separate ATMEGA16U2 that handles the USB-Serial communication. I don't know when that changed, but anything you pick up now will likely be the same (except for the Leonardo, of course).

I guess my assumption about the location of the seial buffer being the 16U2 probably came from the fact that the 16U2 handles the LEDs that signify TxData and RxData. If you fire up a board programmed to send Serial, without it being connected to anything on the USB side, the TxData LED will flicker a while, then go on solid, presumable indicating seial buffer full. That made me think that the serial buffer was in the 16U2.