默认的事件循环是一个事件循环的系统应用发布和处理事件(例如,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

ESP32-默认事件循环的更多相关文章

  1. libuv事件循环

    目录 1.说明 2.数据类型 2.1.uv_loop_t 2.2.uv_walk_cb 3.API 3.1.uv_loop_init 3.2.uv_loop_configure 3.3.uv_loop ...

  2. 事件循环和线程没有必然关系(就像Windows子线程默认没有消息循环一样),模态对话框和事件循环也没有必然关系(QWidget直接就可以)

    周末天冷,索性把电脑抱到床上上网,这几天看了 dbzhang800 博客关于 Qt 事件循环的几篇 Blog,发现自己对 Qt 的事件循环有不少误解.从来只看到现象,这次借 dbzhang800 的博 ...

  3. Qt事件机制浅析(定义,产生,异步事件循环,转发,与信号的区别。感觉QT事件与Delphi的事件一致,而信号则与Windows消息一致)

    Qt事件机制 Qt程序是事件驱动的, 程序的每个动作都是由幕后某个事件所触发.. Qt事件的发生和处理成为程序运行的主线,存在于程序整个生命周期. Qt事件的类型很多, 常见的qt的事件如下: 键盘事 ...

  4. QDialog 模态对话框与事件循环(exec其实就是调用了show和eventLoop.exec)

    起源 qtcn中文论坛中有网友问到: 假设程序正常运行时,只有一个简单的窗体A,此时只有一个GUI主线程,在这个主线程中有一个事件循环处理窗体上的事件.当此程序运行到某阶段时,弹出一个模态窗体B(书上 ...

  5. Qt 的线程与事件循环——可打印threadid进行观察槽函数到底是在哪个线程里执行,学习moveToThread的使用)

    周末天冷,索性把电脑抱到床上上网,这几天看了 dbzhang800 博客关于 Qt 事件循环的几篇 Blog,发现自己对 Qt 的事件循环有不少误解.从来只看到现象,这次借 dbzhang800 的博 ...

  6. 【转】Qt事件循环与线程 二

    转自:http://blog.csdn.net/changsheng230/article/details/6153449 续上文:http://blog.csdn.net/changsheng230 ...

  7. 深入理解 JavaScript 事件循环(一)— event loop

    引言 相信所有学过 JavaScript 都知道它是一门单线程的语言,这也就意味着 JS 无法进行多线程编程,但是 JS 当中却有着无处不在的异步概念 .在初期许多人会把异步理解成类似多线程的编程模式 ...

  8. [译] 所有你需要知道的关于完全理解 Node.js 事件循环及其度量

    原文地址:All you need to know to really understand the Node.js Event Loop and its Metrics 原文作者:Daniel Kh ...

  9. node事件循环和process

    1.node.js事件循环 node.js事件可以继续插入事件,如果有事件就继续执行下去,每一次事件处理结束后等待下一个事件的发生:没有要处理的事件了,那整个就结束了; setTimeout插入一个 ...

随机推荐

  1. CSS(2)盒子模型、定位浮动

    盒子模型 盒子模型:一个盒子中主要的属性就5个.width与height.padding.border.margin.盒子模型标准有两种为标准盒模型和IE盒模型.学习上以标准盒子模型为主 width和 ...

  2. 拖动登录框 HTML+CSS+js

    先上效果 代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...

  3. unity ab包打包和加载的简单学习示例

    闲着没事结合项目看了下unity AssetBundle打包和使用,写了一些测试例子,需要的可以拿去,导入一个空项目即可 链接:https://pan.baidu.com/s/1H85dnMNkRoW ...

  4. Scrum Master 生存指南

    近年来,出现了一批新兴且广受关注的岗位,以 Scrum Master 为典型代表.2018年,Scrum Master 的平均工资为98239美元.领英更是将其列为2019年最有前途的工作之一.但对于 ...

  5. .NET Core HttpClient请求异常详细情况分析

    前言 最近项目上每天间断性捕获到HttpClient请求异常,感觉有点奇怪,于是乎观察了两三天,通过日志以及对接方沟通确认等等,查看对应版本源码,尝试添加部分配置发布后,观察十几小时暂无异常情况出现, ...

  6. 如何为嵌入式应用选择适当的SSD

    如何为嵌入式应用选择适当的SSD Selecting the right SSD for evolving embedded applications 变革涉及技术的每一个要素,闪存也不例外.价格下跌 ...

  7. Charles下载及安装破解-自己编辑

    Charles下载地址 地址:https://www.charlesproxy.com/latest-release/download.do 2. Charles破解 破解地址:https://www ...

  8. 最短路径问题,BFS,408方向,思路与实现分析

    最短路径问题,BFS,408方向,思路与实现分析 继上回挖下的坑,不知道大家有没有认真看最小生成树呢?很简单,这回也讲讲正常难度的,看不懂就来这里看看,讲的很好~~ 最短路径问题 说起这个问题,先说个 ...

  9. Java8的Stream API确实很牛,但性能究竟如何?

    Stream Performance 已经对 Stream API 的用法鼓吹够多了,用起简洁直观,但性能到底怎么样呢?会不会有很高的性能损失?本节我们对 Stream API 的性能一探究竟. 为保 ...

  10. gRPC趁现在还没大火,抢先了解一下

    前言 系统分布式已经成为程序员的家常,将大型单体划分为相对简单的小模块,分散系统能力,提升系统扩展性.功能模块复用性等:各功能模块之间肯定会有很多数据共享和交互的应用场景,那就避免不了各模块之间的通信 ...