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插入一个 ...
随机推荐
- curl测试代理连接某个域名的连接时间
缘由:需要查询一下某些代理访问指定域名所消耗的时间,来判断是否是代理连接受限 以下代理均为示例代理,无法真正连接 1. 通过curl方式来测试指定代理的连接情况,代理无账号密码 curl -x 127 ...
- SpringMVC=>web.xml基本配置
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmln ...
- 重新整理 .net core 实践篇—————服务与配置之间[十一二]
前言 前面基本介绍了,官方对于asp .net core 设计配置和设计服务的框架的一些思路.看下服务和配置之间是如何联系的吧. 正文 服务: public interface ISelfServic ...
- CPU性能PK
CPU性能PK AMD vs Intel 2020: Who Makes the Best CPUs? 英文原文链接:https://www.tomshardware.com/features/amd ...
- 利用NVIDIA-NGC中的MATLAB容器加速语义分割
利用NVIDIA-NGC中的MATLAB容器加速语义分割 Speeding Up Semantic Segmentation Using MATLAB Container from NVIDIA NG ...
- 解决:django.core.exceptions.ImproperlyConfigured: Requested setting INSTALLED_APPS, but settings are not 的方法
错误类型: 该错误是在在创建Django工程时出现遇到的错误 完整报错信息:(博文标题输入长度有限制) django.core.exceptions.ImproperlyConfigured: Req ...
- Nebula 基于 ElasticSearch 的全文搜索引擎的文本搜索
本文首发于 Nebula Graph 公众号 NebulaGraphCommunity,Follow 看大厂图数据库技术实践. 1 背景 Nebula 2.0 中已经支持了基于外部全文搜索引擎的文本查 ...
- 【MySQL】MySQL Workbench 8.0 CE 界面汉化
汉化前: 找到这个文件: 打开文件,复制下面这段替换进去保存,重新打开软件即可:(*改之前备份一下) <?xml version="1.0"?> <data> ...
- 安装ogg软件报错:[INS-75012]Sofware Location specified is already an existing Oracle
1.安装ogg软件时报错: [INS-75012]Sofware Location specified is already an existing Oracle 2.根据报错,是说我们选择ogg软件 ...
- 『无为则无心』Python基础 — 16、Python序列之字符串的下标和切片
目录 1.序列的概念 2.字符串的下标说明 3.字符串的切片说明 1.序列的概念 序列sequence是Python中最基本的数据结构.指的是一块可存放多个值的连续内存空间,这些值按一定顺序排列,可通 ...