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
ESP32-默认事件循环的更多相关文章
- 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 ...
- 事件循环和线程没有必然关系(就像Windows子线程默认没有消息循环一样),模态对话框和事件循环也没有必然关系(QWidget直接就可以)
周末天冷,索性把电脑抱到床上上网,这几天看了 dbzhang800 博客关于 Qt 事件循环的几篇 Blog,发现自己对 Qt 的事件循环有不少误解.从来只看到现象,这次借 dbzhang800 的博 ...
- Qt事件机制浅析(定义,产生,异步事件循环,转发,与信号的区别。感觉QT事件与Delphi的事件一致,而信号则与Windows消息一致)
Qt事件机制 Qt程序是事件驱动的, 程序的每个动作都是由幕后某个事件所触发.. Qt事件的发生和处理成为程序运行的主线,存在于程序整个生命周期. Qt事件的类型很多, 常见的qt的事件如下: 键盘事 ...
- QDialog 模态对话框与事件循环(exec其实就是调用了show和eventLoop.exec)
起源 qtcn中文论坛中有网友问到: 假设程序正常运行时,只有一个简单的窗体A,此时只有一个GUI主线程,在这个主线程中有一个事件循环处理窗体上的事件.当此程序运行到某阶段时,弹出一个模态窗体B(书上 ...
- Qt 的线程与事件循环——可打印threadid进行观察槽函数到底是在哪个线程里执行,学习moveToThread的使用)
周末天冷,索性把电脑抱到床上上网,这几天看了 dbzhang800 博客关于 Qt 事件循环的几篇 Blog,发现自己对 Qt 的事件循环有不少误解.从来只看到现象,这次借 dbzhang800 的博 ...
- 【转】Qt事件循环与线程 二
转自:http://blog.csdn.net/changsheng230/article/details/6153449 续上文:http://blog.csdn.net/changsheng230 ...
- 深入理解 JavaScript 事件循环(一)— event loop
引言 相信所有学过 JavaScript 都知道它是一门单线程的语言,这也就意味着 JS 无法进行多线程编程,但是 JS 当中却有着无处不在的异步概念 .在初期许多人会把异步理解成类似多线程的编程模式 ...
- [译] 所有你需要知道的关于完全理解 Node.js 事件循环及其度量
原文地址:All you need to know to really understand the Node.js Event Loop and its Metrics 原文作者:Daniel Kh ...
- node事件循环和process
1.node.js事件循环 node.js事件可以继续插入事件,如果有事件就继续执行下去,每一次事件处理结束后等待下一个事件的发生:没有要处理的事件了,那整个就结束了; setTimeout插入一个 ...
随机推荐
- Freemaker生成复杂样式图片并无文件损坏的excel
Freemaker生成复杂样式图片并无文件损坏的excel 参考Freemarker整合poi导出带有图片的Excel教程,优化代码实现 功能介绍:1.支持Freemarker导出Excel的所有功能 ...
- 几年前,为什么我撸了一套RabbitMQ客户端?
之前文章说过,如果使用 RabbitMQ,尽可能使用框架,而不要去使用 RabbitMQ 提供的 Java 版客户端. 细说起来,其实还是因为 RabbitMQ 客户端的使用有很多的注意事项,稍微不注 ...
- SSTI漏洞-fastapi
0x00 原理 SSTI漏洞全称服务器模板注入漏洞,服务器模板接收了用户输入的恶意代码,未经过滤便在服务端执行并通过渲染模板返回给用户,使得用户可以通过构造恶意代码在服务端执行命令. 0x01 c ...
- gin使用validator库参数校验若干实用技巧
validator库参数校验若干实用技巧 本文介绍了使用validator库做参数校验的一些十分实用的使用技巧,包括翻译校验错误提示信息.自定义提示信息的字段名称.自定义校验方法等. validato ...
- V $ BACKUP_DATAFILE
V$BACKUP_DATAFILE 从控制文件显示有关备份集中的控制文件和数据文件的信息. 柱 数据类型 描述 RECID NUMBER 备份数据文件记录ID STAMP NUMBER 备份数据文件记 ...
- modelMapper使用,将数据库查询对象直接转成DTO对象
1.pom引入 <dependency> <groupId>org.modelmapper</groupId> <artifactId>modelmap ...
- Redis-内存优化(一)
一.正确使用redis 数据类型 我们先了解下 String 类型的内存空间消耗问题,以及选择节省内存开销的数据类型的解决方案.例如一个图片存储系统,要求这个系统能快速地记录图片 ID 和图片在存储系 ...
- HashMap源码:聊聊Map的遍历性能问题(一)
目录 引言 迭代器测试 迭代器源码探究 其他遍历方法 增强型for循环 Map.forEach Stream.forEach 总结 附:四种遍历源码 附:完整测试类与测试结果+一个奇怪的问题 引言 今 ...
- OneFlow 并行特色
OneFlow 并行特色 在 Consistent 与 Mirrored 视角中,已经知道 OneFlow 提供了 mirrored 与 consistent 两种看待分布式系统的视角,并且提前知道了 ...
- LeetCode---105. 从前序与中序遍历序列构造二叉树 (Medium)
题目:105. 从前序与中序遍历序列构造二叉树 根据一棵树的前序遍历与中序遍历构造二叉树. 注意: 你可以假设树中没有重复的元素. 例如,给出 前序遍历 preorder = [3,9,20,15,7 ...