esp-idf-svc
esp-idf-svc copied to clipboard
MQTT on esp32c6 (and probably esp32c3) different behaviour than esp32
This is more of a note for other that stumble into this and hopefully saves them a few hours of debugging. (If there is a better place for this, I will gladly move it)
Testing around with the ESP32C6 I noticed that the mqtt client behaves way different.
First of all a (currently) non recoverable panic in the main loop happens, if you try to subscribe to any topic, before the connected callback is received (I do not know if this was ever valid, but it worked):
let mut client = EspMqttClient::new_cb(&config.mqtt_url, &mqtt_client_config, move |event| {yadda yadda}
client.subscribe(stay_alive_topic.as_str(), ExactlyOnce)?;
If you do this you get a:
Guru Meditation Error: Core 0 panic'ed (Load access fault). Exception was unhandled.
Core 0 register dump:
MEPC : 0x42072eca RA : 0x42072ec6 SP : 0x40839a50 GP : 0x408173e4
0x42072eca - run_event_loop
at /home/empire/workspace/PlantCtrl/rust/.embuild/espressif/esp-idf/v5.2.1/components/mqtt/esp-mqtt/mqtt_client.c:1539
0x42072ec6 - run_event_loop
at /home/empire/workspace/PlantCtrl/rust/.embuild/espressif/esp-idf/v5.2.1/components/mqtt/esp-mqtt/mqtt_client.c:1539
0x408173e4 - __global_pointer$
at ??:??
the same code works on a esp32 with the xtensa toolchain, so apparently there is some difference in the blocking/async behaviour of the idf core here. While I would prefer the subscribe return a error result, I'm not sure if this is even possible (or a good idea for that) without storing the connection state from the callbacks somewhere in the idf wrapper.
As a workaround waiting for the connected event in the callback, and only subscribing after it works fine on the C6.
Additionally, since the naming is confusing. The boolean connected in the embedded_svc::mqtt::client::EventPayload::Connected(connected) actually represents session_present. This flag serves as an indicator for the client, informing it whether a previously established session is still available on the broker. -> Does it make sense to rename this to session_present? If so I would offer to create a pull request for it.
Additionally, since the naming is confusing. The boolean connected in the embedded_svc::mqtt::client::EventPayload::Connected(connected) actually represents session_present. This flag serves as an indicator for the client, informing it whether a previously established session is still available on the broker. -> Does it make sense to rename this to session_present? If so I would offer to create a pull request for it.
Please do.
This is more of a note for other that stumble into this and hopefully saves them a few hours of debugging. (If there is a better place for this, I will gladly move it)
Testing around with the ESP32C6 I noticed that the mqtt client behaves way different.
First of all a (currently) non recoverable panic in the main loop happens, if you try to subscribe to any topic, before the connected callback is received (I do not know if this was ever valid, but it worked):
let mut client = EspMqttClient::new_cb(&config.mqtt_url, &mqtt_client_config, move |event| {yadda yadda} client.subscribe(stay_alive_topic.as_str(), ExactlyOnce)?;
If you do this you get a:
Guru Meditation Error: Core 0 panic'ed (Load access fault). Exception was unhandled. Core 0 register dump: MEPC : 0x42072eca RA : 0x42072ec6 SP : 0x40839a50 GP : 0x408173e4 0x42072eca - run_event_loop at /home/empire/workspace/PlantCtrl/rust/.embuild/espressif/esp-idf/v5.2.1/components/mqtt/esp-mqtt/mqtt_client.c:1539 0x42072ec6 - run_event_loop at /home/empire/workspace/PlantCtrl/rust/.embuild/espressif/esp-idf/v5.2.1/components/mqtt/esp-mqtt/mqtt_client.c:1539 0x408173e4 - __global_pointer$ at ??:??
the same code works on a esp32 with the xtensa toolchain, so apparently there is some difference in the blocking/async behaviour of the idf core here. While I would prefer the subscribe return a error result, I'm not sure if this is even possible (or a good idea for that) without storing the connection state from the callbacks somewhere in the idf wrapper.
We have to - as annoying as it is - first understand the root cause. Perhaps by looking at the C code. I don't think it is normal for the MQTT client to panic.
Thanks for reporting it!
Can you also please give additional context for the riscv case:
What rust compiler version, optimization level where you using?
From logs you are using ESP-IDF 5.2.1