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插入一个 ...
随机推荐
- 加载动画效果 HTML+ CSS
加载动画效果 写在前面 在无限的时间的河流里,人生仅仅是微小又微小的波浪.--郭小川 实现效果 实现原理 通过2个伪元素来设置3条颜色边框 通过定位将3个圆弧边框层叠再一起,再通过旋转实现一个圆的效果 ...
- 开源项目核心商城(CoreShop)
帮小伙伴推一下他的开源项目作者是@大灰灰 核心商城(CoreShop)Beta 支持可视化布局的.Net小程序商城 [ : 机器人对话流中加入帮助和取消按钮功能 (The Bot Framework Composer tutorials)
欢迎来到微软机器人编辑器使用教程,从这里开始,创建一个简单的机器人. 在该系列文章中,每一篇都将通过添加更多的功能来构建机器人.当完成教程中的全部内容后,你将成功的创建一个天气机器人(Weather ...
- 一篇文章带你吃透,Java界最神秘技术ClassLoader
ClassLoader 是 Java 届最为神秘的技术之一,无数人被它伤透了脑筋,摸不清门道究竟在哪里.网上的文章也是一篇又一篇,经过本人的亲自鉴定,绝大部分内容都是在误导别人.本文我带读者彻底吃透 ...
- 【模拟7.14】B. 熟练剖分(tree) (概率DP)
一道概率神题,考试时没读清题考完看了学长的玄学题解看了好几个小时 首先f[i][j]表示在点 i 为根的子树中,向下最长轻链长度小于等于 j 的概率. 首先递归下去并求出子树大小,然后枚举重儿子,枚举 ...
- RobotFramework + Python 自动化入门 二 (关键字)
在<RobotFramwork + Python 自动化入门 一>中,完成了Robot环境搭建及测试脚本的创建和执行. 本节,对RobotFramework的关键字使用和查看源码进行介绍. ...
- Java基础-封装和继承
@ 目录 Java基础知识(封装和继承) 一. 封装 1.1 封装的目的 1.2 封装的好处 1.3 封装的步骤 1.4 封装的例子 1.5 小结 二. 继承 2.1 继承的介绍 2.2 生活中的继承 ...