Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Fix connectErrorString return type for ESP-32 BSP 2.0.8 #222

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 21, 2023

Conversation

brentru
Copy link
Member

@brentru brentru commented Apr 21, 2023

This PR fixes return type of connectErrorString due to a change in espressif/arduino-esp32#7941 by adding a preprocessor for ESP32-arch and returning a const char * rather than a __FlashStringHelper to Serial.println().

Related: adafruit/Adafruit_Learning_System_Guides#2483

}
return statusMsg;
}
#else

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it work to just continue returning a F() for all cases? And then only add preproc around the function line to set the specific return type to match what F() ends up being. That would let the function code itself remain unchanged.

Copy link
Member Author

@brentru brentru Apr 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@caternuson I do not think so as F() provides different return types in different architectures. Could you give me a quick example of what you mean? Having trouble visualizing this solution.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something like this maybe?

#ifdef ARDUINO_ARCH_ESP32
const char *Adafruit_MQTT::connectErrorString(int8_t code) {
#else
const __FlashStringHelper *Adafruit_MQTT::connectErrorString(int8_t code) {
#endif
  switch (code) {
  case 1:
    return F(
        "The Server does not support the level of the MQTT protocol requested");

Basically just changing the return type as needed for whatever F() ends up being on a given platform.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented in a94f4d5, requesting a re-review before I make the same change to the Arduino Adafruit IO Library.

@mrengineer7777
Copy link

@brentru Hi, it's David from arduino-esp32. I'm a volunteer.

You shouldn't have to make new cases for ESP32. Just change the return type of function connectErrorString to const char *. That should be more universal and may work for other platforms. Worst case you might also have to redefine macro F for ESP32.

ESP32 currently defines F as:

#define FPSTR(pstr_pointer) (reinterpret_cast<const __FlashStringHelper *>(pstr_pointer))
#define F(string_literal) (FPSTR(PSTR(string_literal)))

https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/WString.h

You can override it something like this:

#ifdef ARDUINO_ARCH_ESP32
undef F
#define F(s) (s)
#endif

If you use the undef, you'll probably want it in your .cpp file so it doesn't affect compilation of other libraries.

@brentru
Copy link
Member Author

brentru commented Apr 21, 2023

@mrengineer7777

You shouldn't have to make new cases for ESP32. Just change the return type of function connectErrorString to const char *. That should be more universal and may work for other platforms.

Changing the return type to const char* causes the reverse of the original error to occur on AVR (and other?) platforms,
error: cannot convert 'const __FlashStringHelper*' to 'const char*' in return

@brentru
Copy link
Member Author

brentru commented Apr 21, 2023

@mrengineer7777

ESP32 currently defines F as: #define FPSTR(pstr_pointer) (reinterpret_cast<const __FlashStringHelper *>(pstr_pointer)) #define F(string_literal) (FPSTR(PSTR(string_literal)))

This is not true as of espressif/arduino-esp32#7941, it was changed to:

#define FPSTR(pstr_pointer) (pstr_pointer)
#define F(string_literal) (string_literal)

We're finding that the compiler does not seem to allow implicit casting to occur in either direction.

We could override the current macro to use the older one:

#ifdef ARDUINO_ARCH_ESP32
undef FPSTR
undef F
#define FPSTR(pstr_pointer) (reinterpret_cast<const __FlashStringHelper *>(pstr_pointer))
#define F(string_literal) (FPSTR(PSTR(string_literal)))
#endif

But I'm not sure if having divergent #defines between a BSP and library code is the best way to go - I like keeping things in-line.

@brentru brentru requested a review from caternuson April 21, 2023 19:44
@mrengineer7777
Copy link

@mrengineer7777

ESP32 currently defines F as: #define FPSTR(pstr_pointer) (reinterpret_cast<const __FlashStringHelper *>(pstr_pointer)) #define F(string_literal) (FPSTR(PSTR(string_literal)))

This is not true as of espressif/arduino-esp32#7941, it was changed to:

#define FPSTR(pstr_pointer) (pstr_pointer)
#define F(string_literal) (string_literal)

We're finding that the compiler does not seem to allow implicit casting to occur in either direction.

We could override the current macro to use the older one:

#ifdef ARDUINO_ARCH_ESP32
undef FPSTR
undef F
#define FPSTR(pstr_pointer) (reinterpret_cast<const __FlashStringHelper *>(pstr_pointer))
#define F(string_literal) (FPSTR(PSTR(string_literal)))
#endif

But I'm not sure if having divergent #defines between a BSP and library code is the best way to go - I like keeping things in-line.

Hmmm. That is messy. That PR is one of the breaking changes that will be discussed in our community meeting next week.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants