Teensy 4.1 function call order in setup() affects the flow of code

Hi y'all

I have been having a couple of issues with a sketch on my Teensy 4.1. I am running the latest Teensyduino version, but I was having the same issue with the previous version (1.58), i'm using PlatformIO ad VsCode under Windows 10.

The problem regards the sequence of function calls in setup(). I have a particular function, mts.initializeVariables(), that retrieves values from EEPROM.
I usually called it at the beginning of the setup(), and it has been working fine on some of my Teensys 4.1. I recently bought a couple more 4.1s, and the very same binaries that were previously fine are now causing the MCU to hang indefinitely at startup. I couldn't trace it to any particular fault in the code. I ended up "fixing" it by moving the mts.initializeVariables() to the very end of setup(). This has since been working fine on all boards.

Here's the setup(), in a way that's working:

void setup()
{
pinMode(TEST_PIN, OUTPUT);
digitalWrite(TEST_PIN, LOW);

coreTermometer.begin();

Serial.begin(115200); // Baud Rate set to 115200
Serial.setTimeout(10000); // Timeout set to 1 second

// Serial Messages
rcv_msg.reserve(512);

// Init status
currentStatus = STATUS_DISCONNECTED;


class.initializeVariables(); <----- This one
}

If instead I put it first, it doesn't work at all:

void setup()
{
class.initializeVariables(); <---- This one

pinMode(TEST_PIN, OUTPUT);
digitalWrite(TEST_PIN, LOW);

coreTermometer.begin();

Serial.begin(115200); // Baud Rate set to 115200
Serial.setTimeout(10000); // Timeout set to 1 second

// Serial Messages
rcv_msg.reserve(512);

// Init status
currentStatus = STATUS_DISCONNECTED;
}

And here's the function itself:

int Class::initializeVariables()
{

// Read the currentIndex from EEPROM
int currentIndex;
EEPROM.get(INDEX_ADDRESS, currentIndex);

EEPROM.get(DEVICE_ID_ADDRESS, m_deviceId);

return 0;
}
};

My questions now are: should the sequence of execution in setup() be this influential on the flow?
Does it have anything to do with a initialization of the EEPROM library/physical memory? Is it influenced by the addresses I'm trying to access (addresses and sizes are fine and fixed)? Any way to fix this, maybe using a different library?

Thanks All,
-Marco.
 
int Class::initializeVariables()
{

// Read the currentIndex from EEPROM
int currentIndex;
EEPROM.get(INDEX_ADDRESS, currentIndex);

// Read the m_deviceIdfrom EEPROM
EEPROM.get(DEVICE_ID_ADDRESS, m_deviceId);

return 0;

};
 
Just a guess, maybe one of those other functions does not like the scenario where INDEX_ADDRESS or DEVICE_ID_ADDRESS is a number like 255 (the uninitialized EEPROM value)?
 
Hi, there are no problems with uninitialized values, the point is that the function works, but based on where I place it in setup() it no longer works.

Thanks you anyway

-Marco
 
I am a beginner in C++, but is it allowed to use class to name a class ?????
And you have Class and class.
 
I am guessing along the same lines as Paul mentioned. That is maybe the values read in are not as expected and maybe something
called after this point errored on these values.

If it were me, I would print out the values returned from the EEPROM get methods, and potentially put in checks for validity.

I would also probably scatter in some debug prints along the way in setup to see how far it goes before it dies...
Note: I would start off setup with something like: while (!Serial && millis() < 5000) {}
As to make sure you have a valid Serial port to output to...
And in some cases I would flush Serial output...

like:
Code:
Serial.println("After iniitialzeVariables"); Serial.flush();
Why? Sometimes when it hard crashes, the stuff that is in the output queue is not output, and you spend a lot of
time debugging in the wrong place. Done that!
 
Hi, I thank you for your attention, The values obtained from the EPROM are not used for now, just to debug this problem , so the operation remains the same whether I use them or not, the problem is with the EPROM in my opinion or some problem on the memory, is it possible?
As I mentioned moving the InitializeVariable() function to the end of the setup() function makes things work.

-Marco
 
Sorry we only see a few bits and pieces of your code, so we can only throw darts and hopefully one will hit the mark.

Can it be a memory issue? Yes
That is for example maybe one or more things you call or do corrupts the memory. For example, overwriting an array, and so whatever is
after it gets corrupted. If on Stack maybe stack corrupted and jumps to never never land.

Does it hang or crash? if crash have you tried putting in something like:
Code:
while (!Serial && millis() < 5000) {}
if (CrashReport) Serial.print(CrashReport);

As I mentioned in previous post, would suggest sprinkle debug outputs or the like in the startup code find out where things went wrong...

As for EEPROM: I should first mention there is no EEPROM on the Teensy 4.x. It is emulated by using the top part of the FLASH memory as you
can see in the memory section of the Teensy 4.1 page:

Which maps into the memory space: On the T4.1:
Code:
#elif defined(ARDUINO_TEENSY41)
#define FLASH_BASEADDR 0x607C0000
#define FLASH_SECTORS  63
It uses 63 sectors of memory. For read operations, it simply needs to read this memory.
It converts the EEPROM address passed in, into which of these 63 pages to use, it then scans this page for the last
occurrence of this index to retrieve the current value. Writes are more complicated...
 
Hi, there are no problems with uninitialized values,

Well, this was just a guess. But it fits the facts you mentioned, that the code had worked on a previously used Teensy 4.1 but failed when you tried on a new Teensy 4.1. The uninitialized contents of emulated EEPROM would be a likely explanation.

I would still urge you to not quickly dismiss this out of hand. Please allow me to state as clearly as possible, simply reading EEPROM early or later in setup() should not by itself cause your program to crash. If it is crashing, I would strongly suspect a software problem in one of the functions (which we can't see) your code calls from setup(). By reading EEPROM later, those global scope variables will be initialized with zeros. But reading EEPROM early will of course initialize them before your setup() function calls other stuff. I really believe you should try to put aside any dismissive bias and really try to look as objectively as possible at whether any of those functions is crashing when the variables you initialized early from EEPROM have values of 255 (the state of EEPROM which has never been used before).

Of course, there could be some other explanation. But from what little we can see, only the words and code fragments you've shown so far, the values in those global scope variables are the only thing that ought to be different when you do the EEPROM reads earlier.
 
I would suggest, that if you have not already done so, see if the compiler is giving you any hints. That is make sure you have
the option turned on to show all warnings.
1714737602144.png

Notice the compiler warnings: All

And rebuild the code. I don't remember if it just changing an option will rebuild everything here or not. If not I would try to get the compiler to rebuild everything again, as it caches compiler runs to minimize how much has to be rebuilt. In cases like this, I often wipe out their cache:
Open up explorer window and go to the: %temp%/arduino directory and I clear the sketches folder.

And then do a verify or upload command. And then look through all of the warnings, and understand or better yet resolve them and see if one of them fixes the issue. Things like, un-initialized variables or array bounds...

Also does your sketch have enough free stack space? I have run into cases where the stack grew down into your normal variable area and you end up with real strange errors.

good luck
 
Back
Top