Board at /dev/ttyACM0 is not available (in bizarre circs)

Here is a small, simple blink program. It runs just fine by itself. But whenever I include a module of experimental code in the build, even though the program does not refer to it in any way, the IDE successfully loads and verifies the executable but then always loses track of the serial port (ttyACM0), so I cannot use the serial monitor. (I get the message “Board at /dev/ttyACM0 is not available” and the light does not blink.)

#include <Arduino.h>

void blink(unsigned long msec) {
Serial.println(“LED is on”);
digitalWrite(LED_BUILTIN, HIGH);
delay(1000);
Serial.println(“LED is off”);
digitalWrite(LED_BUILTIN, LOW);
delay(1000);
}

void setup() {
Serial.begin(115200);
delay(1000);
while (!Serial);
delay(1000);
pinMode(LED_BUILTIN, OUTPUT);

while (true) {
blink(1000UL);
}
}

void loop() { }

The offending module is runtime.cpp. The other .cpp and .h files are present only to provide functions that runtime.cpp refers to. The blinkstat program includes no .h files (except Arduino.h) and contains no externs, so it clearly does refer to anything in runtime.cpp or any of the other modules.

If I rename runtime.cpp to runtime.XX and recompile, the program loads and runs correctly.

I’m using an AdaFruit Feather-M0 (ARM Cortex-M0) with 32KB of RAM and lots of program storage.

Here is a listing of the directory containing all modules:

-rw-rw-r-- 1 mike mike 408 Jun 26 01:21 main.cpp
-rw-rw-r-- 1 mike mike 910 Jan 12 08:13 databuf.h
-rw-rw-r-- 1 mike mike 185 May 14 11:53 gpsdatetime.h
-rw-rw-r-- 1 mike mike 9948 Jun 26 13:07 hw.cpp
-rw-rw-r-- 1 mike mike 1913 Jun 24 18:48 hw.h
-rw-rw-r-- 1 mike mike 796 May 14 11:53 record.h
-rw-rw-r-- 1 mike mike 17305 Jun 26 13:08 runtime.XX
-rw-rw-r-- 1 mike mike 4411 Jun 23 22:20 SAMD21_IntervalTimer.cpp
-rw-rw-r-- 1 mike mike 760 May 12 01:49 SAMD21_IntervalTimer.h
-rw-rw-r-- 1 mike mike 6015 Jun 7 05:34 xm2c.h

Can anyone tell me what’s going on?

Thanks for any help you can give me.

IMHO

should be

void setup() {
  Serial.begin(115200);
  delay(1000);
  while (!Serial);
  delay(1000);
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() { 
   blink(1000UL);
}

i.e. remove the endless loop in setup. Instead use loop().

P.S.: You don’t use the parameter msec inside of blink() :wink:

Thanks, BTW, for your help with a previous problem.

I don’t think it hurts anything to do everything within setup(). For instance, that’s what FreeRTOS does. I’ve also done so in many other sketches without harm.

Also sloppy of me to have a parameter I don’t use, but not lethal.

I “solved” the problem (more or less) as follows.

I started with the idea (or hope) that there might be a particular
passage of code that was responsible for the problem. (My foundation
for this notion was that orignally, the program worked properly if
I left out one particular module.)

I searched exhaustively at function granularity to try to isolate
a particular bit of code whose removal would allow it to work.
I actually found such a function: the Now function, which
reads the system clock and returns its value.

If I returned a constant zero from that function, the program would
work. If I read the clock and returned the actual system time, it failed.

KEEP IN MIND THAT NONE OF THIS CODE (except the little blink
program) GETS EXECUTED. It’s present in the loaded module
but never runs.

On a hunch, I let the function return the actual system time but
made it inline and moved it to a header. Since then, I’ve
had no further problem.

I tried to imagine what could cause such a thing. The most likely-seeming
explanation I could come up with is that a brilliant programmer who
works on the Arduino runtime has felt his sanity gradually slipping
away until he finally snapped and put in logic that checks the residues
of the length of the load module when divided by three particular
prime numbers, and if they add up to a certain unlucky sum, plops
an arbitrary value into a certain location in the code. But there could
be another explanation…