Boot sequence

PRE_STARTUP

In Device OS 6.4.0 a new PRE_STARTUP() function was added. If you need specific execution order guarantees and can deal with tighter limitations than STARTUP(), it is an option.

If you have existing code that uses STARTUP(), it is not necessary to change it as both will continue to be supported.

PRE_STARTUP() is guaranteed to run first before any STARTUP() or global object constructors.

Additionally, PRE_STARTUP() is an optional C function, not a macro. The code goes in the body of the function, not as an argument to the macro as with STARTUP().

void PRE_STARTUP() {
    Serial1.begin(115200);
    Serial1.println("PRE_STARTUP called");  
}

Because PRE_STARTUP() runs before the system thread is started, your code will essentially behave as if single-threaded.

Features available during PRE_STARTUP

Additional available APIs

Feature not available

  • Global objects will not have been constructed yet
  • Logging (Log.info, etc.)
  • Networking (Cellular, Ethernet, Wi-Fi)
  • BLE
  • System power manager functions such as System.powerSource(), System.batteryState(), System.batteryCharge()
  • Anything that is not allowed during STARTUP() also cannot be done during PRE_STARTUP().

Global objects

PRE_STARTUP() executes before global object construction, so you must not rely on global objects. In general, you should be cautious when using global object constructors even without PRE_STARTUP() because the order of global object instantiation is not predictable. A good alternative is to use the singleton pattern.

C++ POD structs are not initialized before PRE_STARTUP().

Global variables of primitive types such as int, char, float, enums, and pointers do have their values set.