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

General Question about Default Event Loop #2

Open
GitProdEnv opened this issue Sep 7, 2022 · 1 comment
Open

General Question about Default Event Loop #2

GitProdEnv opened this issue Sep 7, 2022 · 1 comment

Comments

@GitProdEnv
Copy link

Some snippet of your Main::setup code

status |= wifi.init();
if (ESP_OK == status) status |= wifi.begin();

I know that wifi.begin will only execute esp_wifi_connect() if we are in state_e::READY_TO_CONNECT, this function is implemented this way in your code. But this is an asynchronous call, I'm a bit confused that the app_main code works (i.e. calling wifi.begin() directly after wifi.init() without waiting for the events to happen.

wifi.begin should be called after we get back the WIFI_EVENT_STA_START as far as I know. For example in the ESP IDF code we execute the esp_wifi_connect inside the default event loop at the time when the event happens. (Until now I'm struggling if this is a good habit, to call functions inside the default event loop?

I have seen already other implementations (nKolban), where on those events, e.g. WIFI_EVENT_STA_START semaphores are taken and wifi->init() method waits for this semaphore to be given back by the event, to make the call synchronous, such that the implementation thereafter calls wifi->begin().

The only explanation for me could be because of the higher prioritization of the default event loop vs the main loop which is 1 priority higher than the lowest priority.

@howroyd
Copy link
Owner

howroyd commented Dec 5, 2024

For some reason I didn't get a notification for this issue, my apologies.

The return of begin() is protected, so if the timing doesn't work out we force a reboot, rather than calling functions that shouldn't yet be called:

ESP_ERROR_CHECK(my_main.setup());

You're quite right that this effectively relies on luck that the callback has happened and changed the state so begin() can have a chance to succeed. An improvement can definitely be made here, I certainly wouldn't rely on that for production code!

Calling any functions that do significant work in a callback is generally a no-no, in the documentation they put esp_wifi_connect in the callback, as you spotted. I suspect this is because it is simple, reads nicely, and easier to comprehend for beginners. In general the reason why is because callbacks are often called by interrupts. When you are in an interrupt, other interupts may be disabled. So if something time critical needs to happen, that is synchronised by an interrupt, it will be ignored. That can be all sorts of internals like a keepalive response to a wifi router, which then when you exit the callback, has not been served and causes issues (by way of hypothetical example.)

It is generally safer to just use callbacks (including event loops) to set some atomic state and then return as fast as possible. Then have some other lower priority task that is sitting waiting on that atomic state to change so it can then do some work. Obviously, that is much more complex and much less beginner friendly!

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

No branches or pull requests

2 participants