esp-idf-svc icon indicating copy to clipboard operation
esp-idf-svc copied to clipboard

MQTT on esp32c6 (and probably esp32c3) different behaviour than esp32

Open empirephoenix opened this issue 4 months ago • 3 comments

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.

empirephoenix avatar Apr 22 '24 10:04 empirephoenix

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.

ivmarkov avatar Apr 22 '24 10:04 ivmarkov

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.

ivmarkov avatar Apr 22 '24 10:04 ivmarkov

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

Vollbrecht avatar Apr 22 '24 10:04 Vollbrecht