ESP32 default method uses "legacy" RMT driver, conflicting with some cores
Describe the bug
With some cores, such as esp32s3 (for the Espressif ESP32-S3 dev board), simply referencing a default-method NeoPixelBus in the code (not necessarily actually using it!) causes a boot loop with an error message like this
ELF file SHA256: d2dd9a167d544b2f
Rebooting...
ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0xc (RTC_SW_CPU_RST),boot:0x9 (SPI_FAST_FLASH_BOOT)
Saved PC:0x40378489
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce3818,len:0x508
load:0x403c9700,len:0x4
load:0x403c9704,len:0xad0
load:0x403cc700,len:0x29e4
entry 0x403c9880
E (98) rmt(legacy): CONFLICT! driver_ng is not allowed to be used with the legacy driver
abort() was called at PC 0x4200f903 on core 0
Backtrace: 0x40377e76:0x3fceb200 0x4037c8a5:0x3fceb220 0x4038241d:0x3fceb240 0x4200f903:0x3fceb2c0 0x4201354a:0x3fceb2e0 0x4037817b:0x3fceb310 0x403cd852:0x3fceb340 0x403cdafe:0x3fceb380 0x403c98d5:0x3fceb4b0 0x40045c01:0x3fceb570 0x40043ab6:0x3fceb6f0 0x40034c45:0x3fceb710
To Reproduce Steps to reproduce the behavior:
- Create a simple sketch using
NeoWs2812xMethod - Add https://espressif.github.io/arduino-esp32/package_esp32_index.json to "additional board manager URLs"
- Select the "ESP32S3 Dev Module" board
- Compile, upload, run
Expected behavior Sketch runs as usual.
Development environment (please complete the following information):
- OS: Ubuntu 24.04 LTS
- Build Environment - arduino-cli 1.0.2
- Board target - ESP32-S3
- Library version - 2.8.0
Additional context I believe this is why this happens:
- on ESP32-S3 (and ESP32 in general) NeoPixelBus uses the RMT peripheral by default, via the "legacy" RMT driver from ESP-IDF (see ESP-IDF documentation) https://github.com/Makuna/NeoPixelBus/blob/bf72b6ecc93c53f359ed28aea65776a753c376c8/src/internal/methods/NeoEsp32RmtMethod.h#L49
- ESP-IDF will abort on startup if both "legacy" and "next gen" RMT drivers are even linked into the firmware (not necessarily used) https://github.com/espressif/esp-idf/blob/5ca9f2a49aaabbfaf726da1cc3597c0edb3c4d37/components/driver/deprecated/rmt_legacy.c#L1405
- the ESP32 Arduino core has its own
neopixelWrite()function which much like NeoPixelBus uses the RMT peripheral, using the "next gen" API https://github.com/espressif/arduino-esp32/blob/614c72b4d3e9fd04dcccfe313bb2353b3b0eea46/cores/esp32/esp32-hal-rgb-led.c#L5 - if the
RGB_BUILTINmacro is defined,digitalWrite()will actually callneopixelWrite()if that pin is written https://github.com/espressif/arduino-esp32/blob/614c72b4d3e9fd04dcccfe313bb2353b3b0eea46/cores/esp32/esp32-hal-gpio.c#L169 - since any script is likely to pull in things like
digitalWrite()directly or indirectly, that means ifRGB_BUILTINis defined, you end up linking inneopixelWrite()and thus the "next gen" RMT driver, and if you're using NeoPixelBus you're also pulling in the "legacy" RMT driver, so that explodes - various board definitions (such as the dev board mentioned above) do define that symbol, thus causing this problem
E (98) rmt(legacy): CONFLICT! driver_ng is not allowed to be used with the legacy driver
@Makuna this looks familiar. It only happens with arduino-esp32 v3.0.x, in particular v3.0.0 thru 3.0.2. The problem is that the arduino core makes reference to the "new RMT" driver, so any other lib that still uses "legacy RMT" will trigger the bootloop error.
arduino-esp32 version 3.0.3 should have a solution.
- https://github.com/espressif/arduino-esp32/pull/9941
Until 3.0.3 gets released, the smartest solution is to stay on version 2.0.14 (and maybe in general v2.0.x is preferable, when looking at the long list of breaking changes in 3.0.x ;-)
@egnor and @softhack007 I will leave this around; it is related to moving to the next core API. Currently, I have no implementation for the next API yet, it is on my list but isn't coming soon. I still have consumers using the older cores.
This is a failure on the core to reference something that will cause legacy API which are depreciated but still supported to cause such a failure. Please raise this with them to get an immediate fix.
FYI here's a corresponding issue with Adafruit's library: https://github.com/adafruit/Adafruit_NeoPixel/issues/375
For ESP-IDF v3 compatibility, Adafruit added a quick function to use the arduino-esp32 RMT layer, but, that requires spelling out all the timing transitions in a buffer (since the Arduino RMT driver doesn't expose the custom timing translation feature), which they allocated on the stack in show(), which doesn't work for longer strips.
I assume FastLED and others are addressing this in their own way. (Or maybe FastLED doesn't use RMT?)
We use RMT. We are also broken.
Came here to see if NeoPixelBus fixed it... they haven't yet.
We are all in the same boat. IDF 5.1 is a painful break for everyone.
Working Branch for RMT fixes: https://github.com/Makuna/NeoPixelBus/tree/CORE3
FastLED this week agreed on a path forward for RMT 5.1 with an internal demo.
All the technical issues have been theoretically solved and it seems like it's downhill from here.
It will be a couple weeks or more before the new driver lands because we have to implement support for parallel async which has some innovation but which seems straight forward.
There's a lot of issues this is going to solve which the tail end of users face. Short story is that yes, it's coming and it's going to be awesome and memory efficient.
Working Branch for RMT fixes: https://github.com/Makuna/NeoPixelBus/tree/CORE3
would you mind sharing some plans for that branch @Makuna ? Thank you!
Working Branch for RMT fixes: https://github.com/Makuna/NeoPixelBus/tree/CORE3
would you mind sharing some plans for that branch @Makuna ? Thank you!
What details are you looking for?
Last I knew it was working within the limitations of what has been released in the core at that time. It is waiting on some of the last "fixes" to come through the pipeline that was hinted at by the FastLed comments and then address those before being released. I have not had much time to actually track that though.