Event_Loop 库本质上是为了实现当某些事情发生时(比如wifi完成了链接、定时器中断到了时间),系统可以自动调用回调函数来处理针对当前事件。
Event_Loop 包含两个,一个是用户可以自定义的Event_Loop ,还有一个是Event_Loop_default,是供系统设置好的事件的使用的,
对于每一个Event 都有两部分识别符,分别是 Event base 和 Event ID,Event base声明了这个事件属于哪个 事件族 而 Event ID 表明了是事件族的哪个事件。
使用流程:
-
创建事件循环,使用API esp_event_loop_create()
-
定义一个回调函数,并注册到事件循环中。esp_event_handler_register_with().
-
发布事件信息 esp_event_post_to() (发布完成后就会时间循环就会执行我们注册的回调函数)
-
删除时间循环 esp_event_loop_delete().
// 1. Define the event handler
void run_on_event(void* handler_arg, esp_event_base_t base, int32_t id, void* event_data)
{
// Event handler logic
}
void app_main()
{
// 2. A configuration structure of type esp_event_loop_args_t is needed to specify the properties of the loop to be
// created. A handle of type esp_event_loop_handle_t is obtained, which is needed by the other APIs to reference the loop
// to perform their operations on.
esp_event_loop_args_t loop_args = {
.queue_size = ...,
.task_name = ...
.task_priority = ...,
.task_stack_size = ...,
.task_core_id = ...
};
esp_event_loop_handle_t loop_handle;
esp_event_loop_create(&loop_args, &loop_handle);
// 3. Register event handler defined in (1). MY_EVENT_BASE and MY_EVENT_ID specifies a hypothetical
// event that handler run_on_event should execute on when it gets posted to the loop.
esp_event_handler_register_with(loop_handle, MY_EVENT_BASE, MY_EVENT_ID, run_on_event, ...);
...
// 4. Post events to the loop. This queues the event on the event loop. At some point in time
// the event loop executes the event handler registered to the posted event, in this case run_on_event.
// For simplicity sake this example calls esp_event_post_to from app_main, but posting can be done from
// any other tasks (which is the more interesting use case).
esp_event_post_to(loop_handle, MY_EVENT_BASE, MY_EVENT_ID, ...);
...
// 5. Unregistering an unneeded handler
esp_event_handler_unregister_with(loop_handle, MY_EVENT_BASE, MY_EVENT_ID, run_on_event);
...
// 6. Deleting an unneeded event loop
esp_event_loop_delete(loop_handle);
}
典型示例:连接到指定ap
使用esp_wifi_connect() api来指定连接ap,该api我们看不见源码,乐鑫是以库的方式提供。
库的位置:esp-idf\components\esp_wifi\lib,对应的头文件的位置:esp-idf\components\esp_wifi\include\esp_wifi.h
Wi-Fi 库 - ESP32-C3 - — ESP-IDF 编程指南 latest 文档
猜测,esp_wifi_connect()函数执行完成的时候,会发送一个event。
/**
* @brief Connect the ESP32 WiFi station to the AP.
*
* @attention 1. This API only impact WIFI_MODE_STA or WIFI_MODE_APSTA mode
* @attention 2. If the ESP32 is connected to an AP, call esp_wifi_disconnect to disconnect.
* @attention 3. The scanning triggered by esp_wifi_start_scan() will not be effective until connection between ESP32 and the AP is established.
* If ESP32 is scanning and connecting at the same time, ESP32 will abort scanning and return a warning message and error
* number ESP_ERR_WIFI_STATE.
* If you want to do reconnection after ESP32 received disconnect event, remember to add the maximum retry time, otherwise the called
* scan will not work. This is especially true when the AP doesn't exist, and you still try reconnection after ESP32 received disconnect
* event with the reason code WIFI_REASON_NO_AP_FOUND.
*
* @return
* - ESP_OK: succeed
* - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init
* - ESP_ERR_WIFI_NOT_STARTED: WiFi is not started by esp_wifi_start
* - ESP_ERR_WIFI_CONN: WiFi internal error, station or soft-AP control block wrong
* - ESP_ERR_WIFI_SSID: SSID of AP which station connects is invalid
*/
esp_err_t esp_wifi_connect(void);
一旦esp_wifi_connect()被调用,Wi-Fi驱动程序将开始内部扫描/连接过程。
如果内部扫描/连接过程成功,将post event(WIFI_EVENT_STA_CONNECTED)
。在事件回调函数(event_handler)中,它将启动DHCP客户端,该客户端最终将触发DHCP进程。
由于例如密码错误,找不到AP等原因,Wi-Fi连接可能会失败。在这种情况下,会出现WIFI_EVENT_STA_DISCONNECTED并提供这种失败的原因。
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);
}
}
ref:
Event Loop Library - ESP32-C3 - — ESP-IDF 编程指南 latest 文档
ESP32-IDF Event_Loop库 实战分析_据说这是zzy的博客-CSDN博客
【玩转ESP32】7、ESP32连接wifi - 云+社区 - 腾讯云