ESP32-IDF Event

Event_Loop 库本质上是为了实现当某些事情发生时(比如wifi完成了链接、定时器中断到了时间),系统可以自动调用回调函数来处理针对当前事件。

Event_Loop 包含两个,一个是用户可以自定义的Event_Loop ,还有一个是Event_Loop_default,是供系统设置好的事件的使用的,


对于每一个Event 都有两部分识别符,分别是 Event base 和 Event ID,Event base声明了这个事件属于哪个 事件族 而 Event ID 表明了是事件族的哪个事件。
 

使用流程:

  1. 创建事件循环,使用API esp_event_loop_create()

  2. 定义一个回调函数,并注册到事件循环中。esp_event_handler_register_with()

  3. 发布事件信息 esp_event_post_to()   (发布完成后就会时间循环就会执行我们注册的回调函数)

  4. 取消注册  esp_event_handler_unregister_with().

  5. 删除时间循环 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 - 云+社区 - 腾讯云

ESP32 《Event Handling》事件处理机制_lxing201971的博客-CSDN博客_esp32事件

ESP32学习笔记(5)——WiFi接口使用(STA和AP模式) - 简书

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值