zoukankan      html  css  js  c++  java
  • ESP32-默认事件循环

    默认的事件循环是一个事件循环的系统应用发布和处理事件(例如,Wi-Fi无线事件)。

    基于ESP-IDF4.1

      1 #include "esp_log.h"
      2 #include "freertos/FreeRTOS.h"
      3 #include "freertos/task.h"
      4 #include "event_source.h"
      5 
      6 static const char* TAG = "default_event_loop";
      7 
      8 static char* get_id_string(esp_event_base_t base, int32_t id) {
      9     char* event = "";
     10     if (base == TIMER_EVENTS) {
     11         switch(id) {
     12             case TIMER_EVENT_STARTED:
     13             event = "TIMER_EVENT_STARTED";
     14             break;
     15             case TIMER_EVENT_EXPIRY:
     16             event = "TIMER_EVENT_EXPIRY";
     17             break;
     18             case TIMER_EVENT_STOPPED:
     19             event = "TIMER_EVENT_STOPPED";
     20             break;
     21         }
     22     } else {
     23         event = "TASK_ITERATION_EVENT";
     24     }
     25     return event;
     26 }
     27 
     28 //事件源周期定时器相关的定义
     29 ESP_EVENT_DEFINE_BASE(TIMER_EVENTS);
     30 
     31 esp_timer_handle_t TIMER;
     32 
     33 //计时器周期过期时执行回调,将计时器到期事件发布到默认事件循环
     34 static void timer_callback(void* arg)
     35 {
     36     ESP_LOGI(TAG, "%s:%s: posting to default loop", TIMER_EVENTS, get_id_string(TIMER_EVENTS, TIMER_EVENT_EXPIRY));
     37     ESP_ERROR_CHECK(esp_event_post(TIMER_EVENTS, TIMER_EVENT_EXPIRY, NULL, 0, portMAX_DELAY));
     38 }
     39 
     40 // 当计时器启动事件被循环执行时,执行的处理程序
     41 static void timer_started_handler(void* handler_args, esp_event_base_t base, int32_t id, void* event_data)
     42 {
     43     ESP_LOGI(TAG, "%s:%s: timer_started_handler", base, get_id_string(base, id));
     44 }
     45 
     46 //当计时器到期时间被循环执行时,执行的处理程序。处理程序跟踪计时器过期次数,当达到设置的过期次数,处理程序停止计时器并发送计时器停止事件
     47 static void timer_expiry_handler(void* handler_args, esp_event_base_t base, int32_t id, void* event_data)
     48 {
     49     static int count = 0;
     50     count++;
     51 
     52     if (count >= TIMER_EXPIRIES_COUNT) {
     53         // 停止计时器
     54         ESP_ERROR_CHECK(esp_timer_stop(TIMER));
     55         ESP_LOGI(TAG, "%s:%s: posting to default loop", base, get_id_string(base, TIMER_EVENT_STOPPED));
     56 
     57         //发送计时器停止事件
     58         ESP_ERROR_CHECK(esp_event_post(TIMER_EVENTS, TIMER_EVENT_STOPPED, NULL, 0, portMAX_DELAY));
     59     }
     60 
     61     ESP_LOGI(TAG, "%s:%s: timer_expiry_handler, executed %d out of %d times", base, get_id_string(base, id), count, TIMER_EXPIRIES_COUNT);
     62 }
     63 
     64 //任何计时器事件(启动/到期/停止)被循环执行时,执行的处理程序
     65 static void timer_any_handler(void* handler_args, esp_event_base_t base, int32_t id, void* event_data)
     66 {
     67     ESP_LOGI(TAG, "%s:%s: timer_any_handler", base, get_id_string(base, id));
     68 }
     69 
     70 //计时器停止事件被循环执行时,执行的处理程序。由于计时器已经停止,可以安全的删除它。
     71 static void timer_stopped_handler(void* handler_args, esp_event_base_t base, int32_t id, void* event_data)
     72 {
     73     ESP_LOGI(TAG, "%s:%s: timer_stopped_handler", base, get_id_string(base, id));
     74 
     75     // 删除计时器
     76     esp_timer_delete(TIMER);
     77 
     78     ESP_LOGI(TAG, "%s:%s: deleted timer event source", base, get_id_string(base, id));
     79 }
     80 
     81 //事件源任务相关的定义
     82 ESP_EVENT_DEFINE_BASE(TASK_EVENTS);
     83 
     84 //任务迭代处理
     85 static void task_iteration_handler(void* handler_args, esp_event_base_t base, int32_t id, void* event_data)
     86 {
     87     int iteration = *((int*) event_data);
     88     ESP_LOGI(TAG, "%s:%s: task_iteration_handler, executed %d times", base, get_id_string(base, id), iteration);
     89 }
     90 
     91 //任务时间源
     92 static void task_event_source(void* args)
     93 {
     94     for(int iteration = 1; iteration <= TASK_ITERATIONS_COUNT; iteration++) {
     95 
     96         ESP_LOGI(TAG, "%s:%s: posting to default loop, %d out of %d", TASK_EVENTS,
     97                 get_id_string(TASK_EVENTS, TASK_ITERATION_EVENT), iteration, TASK_ITERATIONS_COUNT);
     98 
     99         //发布该循环已迭代。注意,迭代计数已传递给处理程序。事件发布期间传递的数据是原始数据的深层副本。
    100         ESP_ERROR_CHECK(esp_event_post(TASK_EVENTS, TASK_ITERATION_EVENT, &iteration, sizeof(iteration), portMAX_DELAY));
    101 
    102         if (iteration == TASK_ITERATIONS_UNREGISTER) {
    103             ESP_LOGI(TAG, "%s:%s: unregistering task_iteration_handler", TASK_EVENTS, get_id_string(TASK_EVENTS, TASK_ITERATION_EVENT));
    104             ESP_ERROR_CHECK(esp_event_handler_unregister(TASK_EVENTS, TASK_ITERATION_EVENT, task_iteration_handler));
    105         }
    106 
    107         vTaskDelay(pdMS_TO_TICKS(TASK_PERIOD));
    108     }
    109 
    110     vTaskDelay(pdMS_TO_TICKS(TASK_PERIOD));
    111 
    112     ESP_LOGI(TAG, "%s:%s: deleting task event source", TASK_EVENTS, get_id_string(TASK_EVENTS, TASK_ITERATION_EVENT));
    113 
    114     vTaskDelete(NULL);
    115 }
    116 
    117 //所有时间的处理程序
    118 static void all_event_handler(void* handler_args, esp_event_base_t base, int32_t id, void* event_data)
    119 {
    120     ESP_LOGI(TAG, "%s:%s: all_event_handler", base, get_id_string(base, id));
    121 }
    122 
    123 //入口
    124 void app_main(void)
    125 {
    126     ESP_LOGI(TAG, "setting up");
    127 
    128     //创建默认的事件循环
    129     ESP_ERROR_CHECK(esp_event_loop_create_default());
    130 
    131     // 注册特定计时器事件处理程序
    132     ESP_ERROR_CHECK(esp_event_handler_register(TIMER_EVENTS, TIMER_EVENT_STARTED, timer_started_handler, NULL));
    133     ESP_ERROR_CHECK(esp_event_handler_register(TIMER_EVENTS, TIMER_EVENT_EXPIRY, timer_expiry_handler, NULL));
    134     ESP_ERROR_CHECK(esp_event_handler_register(TIMER_EVENTS, TIMER_EVENT_STOPPED, timer_stopped_handler, NULL));
    135 
    136     //注册所有计时器系列事件处理程序。将在计时器启动、到期或者停止时执行
    137     ESP_ERROR_CHECK(esp_event_handler_register(TIMER_EVENTS, ESP_EVENT_ANY_ID, timer_any_handler, NULL));
    138 
    139     //注册任务迭代事件的处理程序
    140     ESP_ERROR_CHECK(esp_event_handler_register(TASK_EVENTS, TASK_ITERATION_EVENT, task_iteration_handler, NULL));
    141 
    142     //为所有事件注册处理程序。如果计时器事件或者任务迭代事件发布到默认循环则执行此操作。
    143     ESP_ERROR_CHECK(esp_event_handler_register(ESP_EVENT_ANY_BASE, ESP_EVENT_ANY_ID, all_event_handler, NULL));
    144 
    145     //创建并启动事件源
    146     esp_timer_create_args_t timer_args = {
    147         .callback = &timer_callback,
    148     };
    149     ESP_ERROR_CHECK(esp_timer_create(&timer_args, &TIMER));
    150     ESP_LOGI(TAG, "starting event sources");
    151 
    152      // 创建与当前任务具有相同优先级的事件源任务
    153     xTaskCreate(task_event_source, "task_event_source", 2048, NULL, uxTaskPriorityGet(NULL), NULL);
    154 
    155     ESP_ERROR_CHECK(esp_timer_start_periodic(TIMER, TIMER_PERIOD));
    156 
    157     //发布计时器启动事件
    158     ESP_LOGI(TAG, "%s:%s: posting to default loop", TIMER_EVENTS, get_id_string(TIMER_EVENTS, TIMER_EVENT_STARTED));
    159     ESP_ERROR_CHECK(esp_event_post(TIMER_EVENTS, TIMER_EVENT_STARTED, NULL, 0, portMAX_DELAY));
    160 }

    原文:https://gitee.com/EspressifSystems/esp-idf/tree/master/examples/system/esp_event/default_event_loop

  • 相关阅读:
    SpringBoot Shiro 配置自定义密码加密器
    SpringBoot Druid 配置详解
    UOJ #164. 【清华集训2015】V | 线段树
    BZOJ 4552 [Tjoi2016&Heoi2016]排序 | 二分答案 线段树
    51nod 1462 树据结构 | 树链剖分 矩阵乘法
    BZOJ 3503 [CQOI2014]和谐矩阵
    BZOJ 4004 [JLOI2015]装备购买 | 线性基
    BZOJ 4785 [Zjoi2017]树状数组 | 二维线段树
    LOJ #2145. 「SHOI2017」分手是祝愿
    LOJ #2141. 「SHOI2017」期末考试
  • 原文地址:https://www.cnblogs.com/kerwincui/p/13965889.html
Copyright © 2011-2022 走看看