My setup() and loop() routines are never called after the constructors of global objects have completed. As far as I understand the environment (main.cpp) the only thing that should happen before entering setup() are calls into init() and initVariant().
Is there any way to see what these routines actually do when running on a Nano?
C++ constructors happen before main() is called.
On an embedded system like Arduino, this means that you have to be careful not to touch chip peripherals that aren't yet initialized. (This is why so many Arduino libraries have a "begin" method separate from their constructor.) (for example, if you call delay() in a constructor, it will probably loop forever, waiting for timer ticks that haven't been set up.)
Right, I concluded that too. Now, constructors are mostly empty and I added such begin() methods to complete initialization.
Also, I noticed that I have to initialized Serial again, even if it already got initialized globally.
OK, the following clearly demonstrates, that Serial needs to be re-initialized in setup().
The call to _init.begin() in setup() is required to actually make "setup()" appear in the Serial Monitor window; without it, nothing appears.
class Init
{
public:
Init(void)
{
begin();
}
void begin(void)
{
Serial.begin(9600);
while(!Serial);
Serial.print("Init::begin()\n");
Serial.flush();
}
} _init;
void setup() {
// put your setup code here, to run once:
_init.begin();
Serial.print("setup()\n");
Serial.flush();
}
void loop() {
// put your main code here, to run repeatedly:
}
Aside from that, I have gotten beyond these issues and am back to standard debugging.
Thanks!!
Serial always needs to be initialized in setup (with Serial.begin())
Serial is NOT generally initialized before that (AVR sketches that don't use Serial don't include any Serial code at all, for example.)
(However, boards with native USB support (including SAMD21) may always include at least the USB side of the USBSerial connection, so as to support the auto-reset dance.)
I'm not sure how the IDE 2.x debug support interacts with Serial... Zero has a separate debug chip that talks directly to SWD, but many other SAMD21 boards don't, and could presumably be running a gdb "stub" over Serial over USB (which sounds a bit scary, but could still be useful.)
Understood.
Having that global Init class is still useful. I derive my global classes from that Init class, so that I can track the invocation of their constructors and their initializations.
Yeah, yeah. There is a lot of code in Arduino that is Not The Way that an experienced embedded C programmer would have written it, and certainly not the way that any particular experience programmer would have written it. I assume that the experienced C++ programmers have even more complaints (but I'm not sure that I trust them to do anything in a deeply embedded environment )
You have to "Let it Go."
And/or "Choose your battles."
And always "Remember the target audience." (this doesn't just mean the end users making their neopixels blink in pretty patterns, but also intermediate folks; the ones who have written libraries for many obscure sensors, implemented other cores, or helped beginners here by "reading the source code.")
The Arduino core source code needs to be highly readable, and "obvious to anyone versed in the field." Obviousness trumps cleverness, almost all the time.
(Example 1: I consider myself a competent low-level C programmer, and I've taken enough C++ classes to have what I think is a reasonable feel for the basics of C++ (the language. I'm way behind when it comes to any of the "development libraries" like Boost.) But I've looked at the C++ STL code now an then, and find it extremely cryptic; almost like it's a separate language from C++ applications. Grr.)
(Example 2. More on-subject. The Arduino init code COULD be moved to a section that executes before C++ constructors. All it would take would be ... mysterious gcc incantations that would be ... mysterious to most people. And there would be a complicated chicken-and-egg problem about not using C++ objects in the init code before they'd been constructed...)
Now, for the last 15 years or so that the Arduino IDE has been in use, it has NOT had any debugger support. That's all new in IDE 2.x. So ... with all of the above said, if you have ideas about how the new debugger experience can be improved (for the target audience), that might very well be one of the Battles Worth Choosing!
Hey, I wasn't complaining. Just reporting what I found.
Re my background, I have experience in C++, some in embedded processors and am a newbie to Arduino. I agree with every thing you said about STL and the more arcane C++ features (especially C++ 12 and up), but those are mostly for library writers anyway.
My current project goes a bit beyond tiny project and the lack of debugger is noticeable. But even IDE 2.0 wouldn't have helped, i guess, because the Nano won't support that. Maybe I need to step up to a newer board, but I like the Nano's form factor. We'll see.