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

Fix ESP32 system restart problems #2543

Merged
merged 2 commits into from
Sep 13, 2022
Merged

Conversation

mikee47
Copy link
Contributor

@mikee47 mikee47 commented Aug 24, 2022

See #2500 for discussion.

@mikee47
Copy link
Contributor Author

mikee47 commented Sep 10, 2022

The cause of the WDT is because the call to esp_wifi_stop() hangs waiting on a queued message to be handled. Because the call originates from the same task which handles the message queue, a deadlock occurs. That means a regular IDF application would behave the same way if esp_wifi_stop() were called from within an event handler (not yet confirmed, but easy enough to test).

The problem can be avoided by calling esp_restart() in the context of another task:

esp_ipc_call(0, esp_ipc_func_t(esp_restart), nullptr);

The following demonstrates that the cause is indeed in esp_wifi_stop as it too succeeds:

esp_ipc_call(0, esp_ipc_func_t(esp_wifi_stop), nullptr);
esp_restart();

@mikee47 mikee47 changed the title [WIP] Fix ESP32 system restart problems Fix ESP32 system restart problems Sep 11, 2022
@slaff
Copy link
Contributor

slaff commented Sep 13, 2022

@kmihaylov can you test if this change is fixing the restart issue for you?

@kmihaylov
Copy link
Contributor

Sure, just need to do some daily tasks and I'll try it in the afternoon.

@kmihaylov
Copy link
Contributor

It looks like Mike's patch is working!

I'm updating Sming this way:

git fetch origin pull/2543/head:pr/2543
git checkout pr/2543
make dist-clean
make Sming-clean

Here is the code:

#include <SmingCore.h>
#include "esp_wifi.h"
#include <esp_ipc.h>

Timer testTimer;

void wifiInit() {
	esp_wifi_deinit();
	esp_netif_create_default_wifi_sta();
	wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
	ESP_ERROR_CHECK(esp_wifi_init(&cfg));
	esp_wifi_set_mode(WIFI_MODE_STA);
	wifi_config_t wifiCfg;
	esp_wifi_set_config(WIFI_IF_STA, &wifiCfg);
	esp_wifi_start();
}

void shutdown() {
	//esp_ipc_call(0, esp_ipc_func_t(esp_wifi_stop), nullptr);
	//esp_wifi_stop();
	System.restart();
}

void init()
{
	wifiInit();
	testTimer.initializeMs(5000, shutdown).startOnce();
}

This code successfully restarts the app. If I use the esp_wifi_stop() then WDT occurs. Calling it in the context of another task (alone; w/o System.restart()) doesn't trigger the WDT. Calling both esp_wifi_stop() (in another task) and then System.restart() triggers WDT, but I think this might be expected...?

@slaff slaff merged commit 50d32f4 into SmingHub:develop Sep 13, 2022
@slaff slaff removed the 3 - Review label Sep 13, 2022
@mikee47 mikee47 deleted the fix/esp32-restart branch September 13, 2022 09:49
@slaff slaff mentioned this pull request Nov 8, 2022
5 tasks
@mikee47
Copy link
Contributor Author

mikee47 commented Feb 9, 2023

Note that with IDF 4.4 (#2612) IPC is no longer available for single-core SOCs, so instead the call can be handled by the esp_timer task (see #2371).

const esp_timer_create_args_t create_args = {
  .callback = esp_timer_cb_t(esp_restart),
  .dispatch_method = ESP_TIMER_TASK,
};
esp_timer_handle_t handle{nullptr};
esp_timer_create(&create_args, &handle);
esp_timer_start_once(handle, 100);

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