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插入一个 ...
随机推荐
- kafka之一:kafka简介
现在从事java开发的同学,不论是在面试过程中还是在日常的工作中,肯定会碰到消息队列的情况,市面上消息队列有很多:kafka.rocketMQ.rabbitMQ.zeroMQ等,从本篇博客起计划分享一 ...
- leetcode -- 二进制
leetcode -- 二进制 在学习编程语言的运算符时,大部分语言都会有与,或等二进制运算符,我在初期学习这些运算符的时候,并没有重点留意这些运算符,并且在后续的业务代码中也没有频繁的使用过,直到后 ...
- Go语言协程并发---条件变量
package main import ( "fmt" "sync" "time" ) func main() { //要监听的变量 bit ...
- Scrapy中的错误
TabError: Inconsistent use of tabs and spaces in indentation 需要将 .py 文件中的使用 tab 做的空格符删掉,打成空格符.任何一个 ...
- Vue&Element 前端应用开发之菜单和路由的关系
我们一般的应用系统,菜单是很多功能界面的入口,菜单为了更好体现功能点的设置,一般都是动态从数据库生成的,而且还需要根据用户角色的不同,过滤掉部分没有权限的菜单:在Vue&Element的纯前端 ...
- 构建编译TVM方法
构建编译TVM方法 本文提供如何在各种系统上构建和安装TVM包的说明.它包括两个步骤: 1. 首先从C代码构建共享库( libtvm.so for linux, libtvm.dylib fo ...
- 旷视MegEngine网络搭建
旷视MegEngine网络搭建 在 基本概念 中,介绍了计算图.张量和算子,神经网络可以看成一个计算图.在 MegEngine 中,按照计算图的拓扑结构,将张量和算子连接起来,即可完成对网络的搭建.M ...
- nvGRAPH原理概述
nvGRAPH原理概述 nvGRAPH的API参考分析. 简介 数据分析是高性能计算的不断增长的应用.许多高级数据分析问题可以称为图形问题.反过来,当今许多常见的图形问题也可以称为稀疏线性代数.这是N ...
- windows 设置nginx开机自启动
将Nginx设置为Windows服务 需要借助"Windows Service Wrapper"小工具,项目地址: https://github.com/kohsuke/winsw ...
- 保姆级尚硅谷SpringCloud学习笔记(更新中)
目录 前言 正文内容 001_课程说明 002_零基础微服务架构理论入门 微服务优缺点[^1] SpringCloud与微服务的关系 SpringCloud技术栈 003_第二季Boot和Cloud版 ...