Search code examples
c++arduinomicrocontrolleresp32platformio

How converting a char on a esp32 can crash it?


i'm running into a problem understanding why my program is crashing while running on an esp32 processor and is causing it to repeatedly reset. I am working on a NODEMCU devkit version of the esp32. I am using PlatformIO and utilizing the esp32 version of the Arduino codebase.

In my program, I am making a debug class to replicate what Serial does, but over UDP to any device on the network listening. Basically all it does is check if Serial is connected and sends the print statements to it. Otherwise it sends the print statements over UDP.

To do this, I created a class from the Stream class like Serial has been. This means I needed to make functions that write calls are sent to. Calls where all data has been converted to uint8_t. To send the data to Serial though, I have to convert it to a type it accepts. Effectively, this is how a char character ends up being passed to Serial:

Serial.print((const char*)((const uint8_t *) '-'));

Now, this basically just converts a char around. The conversion to uint8_t is done before I get it, I'm simply converting it to something the Serial class will accept. What I get instead is my controller crashing and a panic and resetting. Now, yes, I can change this around fairly easily by trying to prevent a char from being printed, but I would rather understand what's going wrong here, If this is imploding, likely there are other landmines I haven't stepped on yet and this one has already set me back far enough as it is.

Can anyone explain why converting a char around causes a crash?


Solution

  • The problem is that you cast a char, '-', into a pointer, making an address out of the the char value. It's the same as doing reinterpret_cast<const char*>('-') and, assuming ASCII, it's the same as providing the address 0x2d to the print function which will then start reading from address 0x2d, which is unlikely a valid address for your program, so you'll have undefined behavior.

    If you have a uint8_t something; then do

    Serial.print(static_cast<char>(something));
    

    which will use the Serial.print overload taking a single char.