Skip to content
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

ESP32-S3 Won't Compile in Arduino 2.2.1 #298

Closed
vicatcu opened this issue Oct 2, 2023 · 6 comments
Closed

ESP32-S3 Won't Compile in Arduino 2.2.1 #298

vicatcu opened this issue Oct 2, 2023 · 6 comments
Labels

Comments

@vicatcu
Copy link

vicatcu commented Oct 2, 2023

The following sketch

#include <SoftwareSerial.h>

EspSoftwareSerial::UART testSerial;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  testSerial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:

}

Results in the following verbose compiler error outut:

In file included from /home/vic/Arduino/libraries/EspSoftwareSerial/src/SoftwareSerial.h:25,
                 from /tmp/.arduinoIDE-unsaved202391-25181-wzr2t0.fwh5m/sketch_oct1a/sketch_oct1a.ino:1:
/home/vic/Arduino/libraries/EspSoftwareSerial/src/circular_queue/circular_queue.h: In constructor 'circular_queue<T, ForEachArg>::circular_queue(size_t)':
/home/vic/Arduino/libraries/EspSoftwareSerial/src/circular_queue/circular_queue.h:69:85: error: 'make_unique' is not a member of 'std'
     circular_queue(const size_t capacity) : m_bufSize(capacity + 1), m_buffer{ std::make_unique<T[]>(m_bufSize) }
                                                                                     ^~~~~~~~~~~
/home/vic/Arduino/libraries/EspSoftwareSerial/src/circular_queue/circular_queue.h:69:85: note: 'std::make_unique' is only available from C++14 onwards
/home/vic/Arduino/libraries/EspSoftwareSerial/src/circular_queue/circular_queue.h:69:98: error: expected primary-expression before '[' token
     circular_queue(const size_t capacity) : m_bufSize(capacity + 1), m_buffer{ std::make_unique<T[]>(m_bufSize) }
                                                                                                  ^
/home/vic/Arduino/libraries/EspSoftwareSerial/src/circular_queue/circular_queue.h:69:99: error: expected primary-expression before ']' token
     circular_queue(const size_t capacity) : m_bufSize(capacity + 1), m_buffer{ std::make_unique<T[]>(m_bufSize) }
                                                                                                   ^
/home/vic/Arduino/libraries/EspSoftwareSerial/src/circular_queue/circular_queue.h: In member function 'bool circular_queue<T, ForEachArg>::capacity(size_t)':
/home/vic/Arduino/libraries/EspSoftwareSerial/src/circular_queue/circular_queue.h:270:40: error: 'make_unique' is not a member of 'std'
     std::unique_ptr<T[] > buffer{ std::make_unique<T[]>(cap + 1) };
                                        ^~~~~~~~~~~
/home/vic/Arduino/libraries/EspSoftwareSerial/src/circular_queue/circular_queue.h:270:40: note: 'std::make_unique' is only available from C++14 onwards
/home/vic/Arduino/libraries/EspSoftwareSerial/src/circular_queue/circular_queue.h:270:53: error: expected primary-expression before '[' token
     std::unique_ptr<T[] > buffer{ std::make_unique<T[]>(cap + 1) };
                                                     ^
/home/vic/Arduino/libraries/EspSoftwareSerial/src/circular_queue/circular_queue.h:270:54: error: expected primary-expression before ']' token
     std::unique_ptr<T[] > buffer{ std::make_unique<T[]>(cap + 1) };
                                                      ^

Using library EspSoftwareSerial at version 8.1.0 in folder: /home/vic/Arduino/libraries/EspSoftwareSerial 
exit status 1

Compilation error: exit status 1
@vicatcu
Copy link
Author

vicatcu commented Oct 3, 2023

I did some Googling and then decided to try some stuff. I was able to make a basic example compile by including the following code in a file called _make_unique.h in the circular_queue folder:

#ifndef ___MY_MAKE_UNIQUE___
#define ___MY_MAKE_UNIQUE___

#include <cstddef>
#include <memory>
#include <type_traits>
#include <utility>

namespace std {
    template<class T> struct _Unique_if {
        typedef unique_ptr<T> _Single_object;
    };

    template<class T> struct _Unique_if<T[]> {
        typedef unique_ptr<T[]> _Unknown_bound;
    };

    template<class T, size_t N> struct _Unique_if<T[N]> {
        typedef void _Known_bound;
    };

    template<class T, class... Args>
        typename _Unique_if<T>::_Single_object
        make_unique(Args&&... args) {
            return unique_ptr<T>(new T(std::forward<Args>(args)...));
        }

    template<class T>
        typename _Unique_if<T>::_Unknown_bound
        make_unique(size_t n) {
            typedef typename remove_extent<T>::type U;
            return unique_ptr<T>(new U[n]());
        }

    template<class T, class... Args>
        typename _Unique_if<T>::_Known_bound
        make_unique(Args&&...) = delete;
}
#endif

...and then adding #include "_make_unique.h" at the top of circular_queue/circular_queue.h.

The example that I wrote to see if it would compile is this:

#include <SoftwareSerial.h>
EspSoftwareSerial::UART swSerial;
EspSoftwareSerial::Config swSerialConfig = EspSoftwareSerial::SWSERIAL_8E1;

void setup() {
  Serial.begin(115200);
  swSerial.begin(9600, swSerialConfig, 10, 9, false, 128);
  delay(2000);
  Serial.println("Hello World");
}

void loop() {
  // put your main code here, to run repeatedly:
  if(Serial.available() > 0) {
    swSerial.write(Serial.read());
  }

  if(swSerial.available() > 0) {
    Serial.write(swSerial.read());
  }
}

I took inspiration from this SO post: https://stackoverflow.com/questions/24609271/errormake-unique-is-not-a-member-of-std which pointed me to this implementation https://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique.

I'm not sure this is how you'd like to see this fixed, but let me know if you'd like me to make a PR.

@dok-net
Copy link
Collaborator

dok-net commented Oct 7, 2023

I'm sorry, I can't confirm. Currently, EspSoftwareSerial is ahead of the upcoming update of all ESP32 cores to IDF 5.1. I don't know which of the new chips are and which are not supported prior to IDF 5.1 anyway. As things are, the ghostl-async implementation that I'm focussed on is a part of EspSoftwareSerial, so if you think you needed to update EspSoftwareSerial - which you didn't as far as features are concerned - please checkout one of the latest IDF 5.1 based cores from Github, update the toolchains manually, and everything should compile just fine. I have built for ESP32S3 Dev Module successfully just this minute.

@vicatcu
Copy link
Author

vicatcu commented Oct 7, 2023

I've been advised that SoftwareSerial should be generally be avoided in ESP32 by Espressif folks in arduino-esp gitter.

@dok-net
Copy link
Collaborator

dok-net commented Oct 7, 2023

@vicatcu On what grounds, if I may ask? Generally speaking, it's always wrong to use SW serial unless it offers features that you don't get from the HW UARTs. Like, being available at all :-)

@dok-net
Copy link
Collaborator

dok-net commented Oct 7, 2023

HW serial doesn't work on ESP32 with current IDF 5.1 based Arduino core. Reverting to release 2.0.14 of course yields the make_unique issue you noticed.
I am reverting to the new operator in HEAD.

@dok-net dok-net closed this as completed Oct 7, 2023
@vicatcu
Copy link
Author

vicatcu commented Oct 7, 2023

On the basis that there are 3 multiplexed hardware UARTs on the ESP32-S3 and if you only need to talk to one Serial input at a time you can just switch the pins a hardware UART at runtime by doing Serial.end followed by Serial.begin

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

No branches or pull requests

2 participants