Mécanisme de gestion des événements ESP32 "Event Handling"

1. Aujourd'hui, je vais vous présenter le mécanisme de gestion des événements d'ESP32 "Gestion des événements".

Lien vers le document https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32/api-guides/event-handling.html

Question 1. Qu'est-ce qu'un événement? Quel est le mécanisme de gestion des événements?

A mon avis, les événements et les signaux sont en fait les mêmes: un événement (ou signal) vient exécuter une fonction pour gérer certaines choses, similaire à l'interruption d'un ordinateur monopuce.

La façon d'utiliser les événements et les fonctions de gestion d'événements pour résoudre des problèmes devient un mécanisme de gestion d'événements.

Certains composants d'ESP32 utilisent des événements pour notifier les applications lorsque leur état change, comme les événements de connexion Wi-Fi et de déconnexion. Ce qui suit accepte le mécanisme de gestion des événements d'ESP32.

Boucle d'événement héritée Boucle d'événement héritée

Avant l'introduction de la bibliothèque d'événements esp_event Library, les événements du pilote wifi, d'Ethernet et de la pile de protocoles tcp / ip étaient tous traités via la boucle d'événements traditionnelle, qui peut être considérée comme une boucle while (1) ;. La boucle d'événements traditionnelle ne prend en charge que l'ID d'événement et la structure d'informations d'événement que le système a définis, et elle ne peut pas gérer les événements définis par l'utilisateur et les événements de maillage Bluetooth. Les événements traditionnels ne prennent en charge qu'une seule fonction de traitement d'événements, et les composants d'application ne peuvent pas gérer seuls les événements wifi et ip, et l'application doit lancer ces événements.

Boucle d'événements de la bibliothèque esp_event La boucle d'événements fournie par la bibliothèque d'événements esp

La bibliothèque d'événements est utilisée pour remplacer la boucle d'événements traditionnelle et fournit une boucle d'événements par défaut pour gérer les événements wifi et ip.

Les capacités de la bibliothèque d'événements:

La bibliothèque d'événements permet aux composants de déclarer un événement à la fonction de traitement enregistrée par d'autres composants et d'exécuter la fonction de traitement correspondante lorsque l'événement se produit. Cela permet aux composants faiblement couplés d'effectuer les opérations correspondantes lorsque l'état des autres composants change sans être appelés par l'application. Par exemple, placez tout le traitement de connexion dans une bibliothèque avancée, abonnez-vous aux événements de connexion d'autres composants et lorsque l'état de connexion d'autres composants change, le traitement avancé effectue les opérations correspondantes. Ce mécanisme simplifie la gestion des événements de manière sérialisée et retarde l'exécution du code dans un autre contexte. En termes simples, il s'agit de séparer le lieu de l'événement et le lieu de traitement des événements, le lieu de traitement des événements pour s'abonner à l'événement qui se produira sur le lieu de l'événement, et le traitement des événements de l'ensemble du système est placé au même endroit pour le traitement, ce qui simplifie la conception du système.

2. Utilisation de l'API de la bibliothèque esp_event.

API 位置 : esp-idf-v4.1 \ components \ esp_event

Créer une boucle d'événement utilisateur:
#include "esp_event.h"
#include "string.h"
// famille d'événements personnalisés
(de s_test_base1) ESP_EVENT_DECLARE_BASE;
ESP_EVENT_DEFINE_BASE (s_test_base1);
// IDévénement
ENUM {     TEST_EVENT_BASE1_EV1,     TEST_EVENT_BASE1_EV2,     TEST_EVENT_BASE1_MAX};/ / Fonction de gestion d'événementsvoid handle (void * event_handler_arg, esp_event_base_t event_base, int32_t event_id, void * event_data){     printf ("event_data:% s \ n", (char *) event_data);}








void app_main ()
{     char buf [] = "test event handle";     // Définir l'objet de la boucle d'événements     esp_event_loop_handle_t loop1;     // Configuration de la boucle d'événements     esp_event_loop_args_t loop_config = {         .queue_size = 32, // File d'attente d'événements, définir le nombre d'événements qui peut être reçu         .task_name = "loop", // L'événement repose sur une tâche freertos distincte pour définir le nom de la         tâche.task_priority = 1, // task priority.task_stack_size         = 2048, // task stack         size.task_core_id = 0 // utilisé par la tâche cpu core id     };     // Créer une boucle d'événements     esp_event_loop_create (& loop_config, & loop1);     // Enregistrer les événements et les gestionnaires d'événements dans la boucle     esp_event_handler_register_with (loop1, s_test_base1, TEST_EVENT_BASE1_EV1, ​​handle, NULL);     while (1) {















    

        // Evénement de déclenchement, vérifiez si la fonction de traitement est appelée
        esp_event_post_to (loop1, s_test_base1, TEST_EVENT_BASE1_EV1, ​​buf, strlen (buf) + 1, portMAX_DELAY);
        vTaskDelay (1000 / portTICK_PERIOD_MS);
    }
}

Créer une boucle d'événements par défaut (par rapport à la boucle d'événements utilisateur, il y a moins de poignées représentant la boucle d'événements)

#include "esp_event.h"
#include "string.h"
// famille d'événement défini par l' utilisateur
ESP_EVENT_DECLARE_BASE (s_test_base1);
ESP_EVENT_DEFINE_BASE (s_test_base1);
// id événement
ENUM {     TEST_EVENT_BASE1_EV1,     TEST_EVENT_BASE1_EV1,     TEST_EVENT_BASE1 } 2, TEST_MAX



noid handle (void * event_handler_arg, esp_event_base_t event_base, int32_t event_id, void * event_data)
{     printf ("event_data:% s \ n", (char *) event_data); }

void app_main ()
{     char buf [] = "le descripteur d'événement de te";     esp_event_loop_create_default ();     esp_event_handler_register (s_test_base1, TEST_EVENT_BASE1_EV1, ​​handle, NULL);


    while (1) {         esp_event_post (s_test_base1, TEST_EVENT_BASE1_EV1, ​​buf, strlen (buf) + 1, portMAX_DELAY);         vTaskDelay (1000 / portTICK_PERIOD_MS);     } }



Créer des boucles d'événements qui n'utilisent pas de tâches propriétaires (principalement correctes esp_event_loop_run()函数本质的解读)

esp_err_t esp_event_loop_run ( esp_event_loop_handle_t  event_loop , TickType_t  ticks_to_run )

La description officielle de la fonction est d'assigner un événement à la boucle d'événements. En fait, il est difficile de comprendre clairement à partir de ce niveau. À partir du sens littéral de la fonction, on peut voir que laisser une boucle d'événements event_loop exécuter ticks_to_run tick Pour dire les choses franchement, cela signifie une opération temporaire. Cet événement est en boucle pendant un certain temps. Si vous mettez cette fonction dans while (1), elle s'exécutera tout le temps. Cette fonction est pour le nom de la tâche n'est pas spécifié lorsque la boucle temporelle est créée (essentiellement, une tâche freertos n'est pas ouverte séparément pour la boucle d'événements), alors ce n'est qu'en laissant la boucle d'événements s'exécuter qu'elle peut normalement recevoir des événements et appeler le traitement des événements fonction, on l'appelle doncesp_event_loop_run函数启动事件循环的操作。

Ci-dessous, je vais créer une tâche distincte à exécuteresp_event_loop_run()函数为例进行了测试。

#include "esp_event.h"

#include "string.h"

// Famille d'événements définie par l'utilisateur

ESP_EVENT_DECLARE_BASE (s_test_base1);

ESP_EVENT_DEFINE_BASE (s_test_base1);

// ID d'événement

enum {

    TEST_EVENT_BASE1_EV1,

    TEST_EVENT_BASE1_EV2,

    TEST_EVENT_BASE1_MAX

};

// Fonction de traitement d'événement

poignée vide (void * event_handler_arg, esp_event_base_t event_base, int32_t event_id, void * event_data)

{

    printf ("données_événement:% s \ n", (char *) données_événement);

}

 

static void event_loop (void * args)

{

    esp_event_loop_handle_t event_loop = (esp_event_loop_handle_t) args;

 

    tandis que (1) {

        esp_event_loop_run (event_loop, portMAX_DELAY);

    }

}

 

void app_main ()

{

    char buf [] = "gestionnaire d'événement de test 3";

    // Définit l'objet de la boucle d'événement

    esp_event_loop_handle_t loop1;

    // Configuration de la boucle d'événements

    esp_event_loop_args_t loop_config = {

        .queue_size = 32, // File d'attente d'événements, définit le nombre d'événements pouvant être reçus

        .task_name = "loop", // L'événement repose sur une tâche freertos distincte pour définir le nom de la tâche

        .task_priority = 1, // priorité de la tâche

        .task_stack_size = 2048, // taille de la pile de tâches

        .task_core_id = 0 // L'identifiant du cœur du processeur utilisé par la tâche

    };

    loop_config.task_name = NULL;

    // Créer une boucle temporelle

    esp_event_loop_create (& loop_config, & loop1);

    // Enregistrer les événements et les gestionnaires d'événements dans la boucle

    esp_event_handler_register_with (loop1, s_test_base1, TEST_EVENT_BASE1_EV1, ​​handle, NULL);

 

    TaskHandle_t mtask;

    xTaskCreate (boucle_événement, "tâche", 2584, (void *) boucle1, 1, & mtask);

    // esp_event_loop_run (event_loop, portMAX_DELAY);

    tandis que (1) {

        // Evénement de déclenchement, vérifie si la fonction de traitement est appelée

        esp_event_post_to (loop1, s_test_base1, TEST_EVENT_BASE1_EV1, ​​buf, strlen (buf) + 1, portMAX_DELAY);

        vTaskDelay (1000 / portTICK_PERIOD_MS);

    }

}

Pour résumer:

Étapes pour utiliser l'API de la bibliothèque esp_event:

1. Créer une boucle d'événements
2. Enregistrer des événements et des fonctions de traitement d'événements (pour la définition des événements et des fonctions de traitement d'événements, veuillez vous référer à mon cas)
3. Déclencher des événements et exécuter des fonctions de traitement d'événements

Je suppose que tu aimes

Origine blog.csdn.net/qq_34473570/article/details/108548214
conseillé
Classement