[Solved] Upgrading IDF 3.3 to 4.3: question 1 on event handler

zliudr
Posts: 357
Joined: Thu Oct 03, 2019 5:15 am

[Solved] Upgrading IDF 3.3 to 4.3: question 1 on event handler

Postby zliudr » Fri Mar 05, 2021 5:50 pm

Reference is on document page 1151 2.7.8 Event Loop Library
I'm upgrading my huge project from 3.3 to 4.3. I encountered a number of problems so I would like to break them down into individual problems in case others encounter them as well.

The first question is event handler. I admit I didn't read the event handler's mechanism before. I'm doing search and read on 4.3 doc now. I would appreciate a pointer where it is covered.

Anyway, here is question 1 in three parts, A, B, and C: event_handler() function for wifi connection, my code based on 3.3 example and 4.3 wifi/getting_started example code:

My code (3.3):

Code: Select all

esp_err_t event_handler(void *ctx, system_event_t *event)
{
	switch(event->event_id)
	{
		case SYSTEM_EVENT_STA_START:
		ESP_LOGI(TAG, "SYSTEM_EVENT_STA_START");
		ESP_ERROR_CHECK(esp_wifi_connect());
		break;
		
		case SYSTEM_EVENT_STA_GOT_IP:
		ESP_LOGI(TAG, "SYSTEM_EVENT_STA_GOT_IP");
		ESP_LOGI(TAG, "Got IP: '%s'",
				ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip));
		xEventGroupSetBits(wifi_event_group, WIFI_CONNECTED_BIT); // dev twin
		break;
		
		case SYSTEM_EVENT_STA_DISCONNECTED:
		ESP_LOGI(TAG, "SYSTEM_EVENT_STA_DISCONNECTED");
		ESP_ERROR_CHECK(esp_wifi_connect());
		xEventGroupClearBits(wifi_event_group, WIFI_CONNECTED_BIT); // dev twin
		break;
		
		default:
		break;
	}
	return ESP_OK;
}
wifi/getting_started (4.3)

Code: Select all

static void event_handler(void* arg, esp_event_base_t event_base,
                                int32_t event_id, void* event_data)
{
    if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
        esp_wifi_connect();
    } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
        if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) {
            esp_wifi_connect();
            s_retry_num++;
            ESP_LOGI(TAG, "retry to connect to the AP");
        } else {
            xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
        }
        ESP_LOGI(TAG,"connect to the AP fail");
    } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
        ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
        ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
        s_retry_num = 0;
        xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
    }
}
About registering handlers, my understanding: this event_handler() was initialized differently between IDF versions. I'll go ahead and learn that. My understanding is:
3.3 version of registration doesn't offer a filter so the 3.3 handler sees all events and only handles three of them specifically related to wifi connectivity, SYSTEM_EVENT_STA_START, SYSTEM_EVENT_STA_GOT_IP, SYSTEM_EVENT_STA_DISCONNECTED. It reads an event_id struct member returned by a system_event_t pointer called event.

4.3 is offering filters for registering event handlers that reads instance_any_id or instance_got_ip. The init code registers the same event_handler() to both event types in two calls:

Code: Select all

    ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
                                                        ESP_EVENT_ANY_ID,
                                                        &event_handler,
                                                        NULL,
                                                        &instance_any_id));
    ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
                                                        IP_EVENT_STA_GOT_IP,
                                                        &event_handler,
                                                        NULL,
                                                        &instance_got_ip));
Question 1A: why not registering just any_id and be done? It sounds like it sees all events. Why registering a second type STA_GOT_IP? Will this cause the same event to be processed twice?
Answer: Because now wifi events about station start or disconnect and ip events such as getting ip belong to different bases, WIFI_EVENT and IP_EVENT. The single handler that handles these events belonging to different bases must be registered to both bases. The "legacy" event library didn't have different bases so effectively "all your bases are belong to system" :lol:

About event filtering and processing:
3.3 version system_event_t is a struct that has event_id, no base (nice grouping).
4.3 version esp_event_base_t looks like enum but doc says it's const char*. I can't find the exact value of WIFI_EVENT in doc but assume they are just pointers to strings so you compare pointers for equals and avoid the cpu cost of running strcmp. Not sure why not using enum but that's ok. Developer's choice.
Then event_id that is a struct member in 3.3 but a separate enum (int32) in 4.3.

Question 1B: will I be able to use the old event handler that listens to system events in 4.3? I saw system_event_t still defined in 4.3 doc. Should this be discouraged for some reason?
Answer: I found on the new doc page 1162 under API reference, a section called Legacy API with header esp_event_legacy.h so I can use at my own risk or switch over to new API.

About event data,
3.3 version is a bit convoluted. It does this &event->event_info.got_ip.ip_info.ip. So I'm guessing event_info is compared to 4.3's void* event_data. Then got_ip is a member of a union to access got_ip-related event info.
4.3 version is more clear. It takes event_data and casts it into respective event data pointer type, such as for ip events: ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
Data are still the same data (maybe) but no more unions (or was there ever any)?

Question 1C: was I understanding the differences of event data correct?
Answer: yes, the union is defined on page 1163 for system_event_info_t where system_event_sta_got_ip_t is a member so are system_event_sta_connected_t and disconnected_t.

Thank you!

Who is online

Users browsing this forum: No registered users and 237 guests