由于ESP32使用了FreeRTOS实时操作系统,所以避免不了事件,任务的使用。使用事件组件库可以申明其他组件可以向其注册处理程序的事件,代码将在事件发生时执行。这允许松耦合的组件将所需的行为附加到其他组件的状态更改。
使用接口
- 用户定义一个函数,该函数在事件发布循环时运行。此函数称为事件处理程序。它具有与esp_event_handler_t相同的标志。
- 组件使用esp_event_handler_register_with() 将事件处理注册到循环中,处理程序可以通过多个循环注册。
- 组件使用esp_event_handler_unregister_with() 从循环中取消注册。
常用函数
事件注册
esp_err_t esp_event_handler_instance_register_with(esp_event_loop_handler_t event_loop, esp_event_base_t event_base, int32_t event_id, esp_event_handler_t event_handler,void *event_handler_arg, esp_event_handler_instance_t *instance)
将事件处理注册到特定的循环。
此函数可用于为已下任一注册处理程序:
1. 特定事件
2. 特定事件库的所有事件
3. 系统事件循环已知的所有事件
特定事件:指定确切的event_base和event_id
特定基数的所有事件:指定确切event_base并使用ESP_EVENT_ANY_ID作为event_id
循环已知的所有事件:使用ESP_EVENT_ANY_BASE表示event_base,ESP_EVENT_ANY_ID作为event_id
该函数的返回值除了错误之外,还返回一个实例对象作为输出参数来表示每个注册。这对于在删除事件循环之前删除(取消注册)注册是必须的。可以将多个处理程序注册到事件,将单个处理程序注册到多个事件,以及将同一处理程序注册到同一事件。每个注册都会生成一个不同的实例对象,该对象在注册生存周期内标识它。
参数:
event_loop:要注册此处处理程序函数的事件循环中,不得为NULL
event_base:要为其注册处理程序的事件的基本ID
event_id:要为其注册处理程序的事件ID
event_handler:调度事件时处理程序函数
event_handler_arg:数据,除了事件数据,在调度处理程序时传毒给处理程序
instance:与已注册的事件处理程序和数据相关的事件处理程序实例对象可以为NULL。一般都设置为NULL。
返回:
ESP_Ok:成功
ESP_ERR_NO_MEM:无法为处理程序分配内存
ESP_ERR_INVALID_ARG:事件与事件ID或实例的组合无效为NULL
其他:失败
事件注册
esp_err_t esp_event_handler_instance_register (esp_event_base_t event_base,int32_t event_id,esp_event_handler_t event_handler,void *event_handler_arg, esp_event_handler_instance_t *instance)
将事件处理程序的实例注册到默认循环
参数:
event_base:要为其注册处理程序的事件的基本ID
event_id:要为其注册处理程序的事件ID
event_handler:调度事件时处理程序函数
event_handler_arg:数据,除了事件数据,在调度处理程序时传毒给处理程序
instance:与已注册的事件处理程序和数据相关的事件处理程序实例对象可以为NULL。一般都设置为NULL。
返回值:
ESP_Ok:成功
ESP_ERR_NO_MEM:无法为处理程序分配内存
ESP_ERR_INVALID_ARG:事件与事件ID或实例的组合无效为NULL
其他:失败
事件注销
esp_err_t esp_event_handler_instance_unregister(esp_event_base_t event_base. int32_t event_id, esp_event_handler_t event_handler)
向x系统事件循环注销处理程序。
实例
前面的wifi实例并没有使用事件监听,效果并不直观。一起看看使用了事件监听的效果.代码写的很烂,只能将就一下。
#include <stdio.h>
#include "esp_system.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_event_base.h"
#include "esp_event.h"
#include "nvs_flash.h"
#include "esp_wifi.h"
#include "esp_log.h"
const static char *TAG = "wifi event";
static void System_Init(void);
static void WiFi_Init(void);
static void event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *data);
void app_main(){
System_Init();
WiFi_Init();
}
static void event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *data){
if(event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START){
ESP_ERROR_CHECK(esp_wifi_connect());
ESP_LOGI(TAG, "WIFI event start");
}else if(event_base==WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED){
esp_wifi_connect();
ESP_LOGI(TAG, "esp wifi disconnected");
ESP_LOGI(TAG,"retry ...");
}
}
static void WiFi_Init(){
ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_event_handler_instance_t esp_any_id;
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,ESP_EVENT_ANY_ID,&event_handler,NULL,&esp_any_id));
wifi_init_config_t cnf = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cnf));
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
wifi_config_t con = {
.sta = {
.ssid="CeHi",
.password="13017069426zhc",
.threshold.authmode=WIFI_AUTH_WPA2_PSK
}
};
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &con));
ESP_ERROR_CHECK(esp_wifi_start());
ESP_ERROR_CHECK(esp_event_handler_instance_unregister(WIFI_EVENT,ESP_EVENT_ANY_ID,esp_any_id));
}
static void System_Init(){
esp_err_t ret = nvs_flash_init();
if(ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND){
ESP_ERROR_CHECK(ret);
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
}
评论 (0)