EVENT事件调度(应用层级)操作注意事项

文章目录

    • 简要
    • 注意事项
    • API说明
      • 1、1毫秒计时驱动
      • 2、1秒计时驱动
      • 2、设置一个单位时间为1毫秒的周期性事件
      • 3、设置一个单位时间为1秒的周期性事件
      • 4、单次触发事件
      • 5、清除停止事件
      • 5、缓存事件触发标志
      • 6、获取事件状态
    • 示例
    • 源码

简要

  最大支持32个事件标志管理,倒计时精度为1毫秒的最大倒计时时间为4294967295毫秒,倒计时精度为1秒的最大倒计时时间为4294967295秒,可产生以下事件:

  • 立即触发事件
  • 单次超时事件
  • 循环周期性事件

注意事项

  • 内存访问一致性:主循环中获取事件标志或者调用事件触发和事件设置API都有可能导致读取的数据不一致,由于事件标志是4个字节长度,在事件标志读取和设置途中有可能在定时器中断中也会同时操作,这就导致在主循环中读取到的变量出现误差。所以会在相关函数入口和退出处控制控制所有中断开关。
  • __set_PRIMASK(1);关闭所有中断
  • __set_PRIMASK(0);打开所有中断

API说明

1、1毫秒计时驱动

void eventDriver(void);

调用setEvent(...)延时自动触发事件的倒计时就是在该API中执行,所以该函数需要放在一个周期为1毫秒的定时器中执行。

2、1秒计时驱动

void eventDriver1s(void);

调用setEvent1s(...)延时自动触发事件的倒计时就是在该API中执行,所以该函数需要放在一个周期为1秒的定时器中执行。
比如一些低功耗运行的场景,该定时器可以选择低功耗定时器

2、设置一个单位时间为1毫秒的周期性事件

void setEvent(uint32_t mask, bool first, bool reload, bool setCover, uint32_t timeOut_ms);

序号传参变量类型说明
1maskuint32_t需要设置的事件标志,一个事件占用一个bit内存
2firstbooltrue表示调用setEvent(...)后立即触发一次事件,false表示等待周期时间到了再触发产生事件
3reloadbooltrue表示周期性触发mask事件,false表示执行完第一次超时触发事件后,该事件就停止运行
4setCoverbooltrue表示重新计时,false表示不重新计时
5timeOut_msuint32_t0表示立即触发,无周期性事件,非0表示以时间做超时事件

3、设置一个单位时间为1秒的周期性事件

void setEvent1s(uint32_t mask, bool first, bool reload, bool setCover, uint32_t timeOut_s);

序号传参变量类型说明
1maskuint32_t需要设置的事件标志,一个事件占用一个bit内存
2firstbooltrue表示调用setEvent(...)后立即触发一次事件,false表示等待周期时间到了再触发产生事件
3reloadbooltrue表示周期性触发mask事件,false表示执行完第一次超时触发事件后,该事件就停止运行
4setCoverbooltrue表示重新计时,false表示不重新计时
5timeOut_suint32_t0表示立即触发,无周期性事件,非0表示以时间做超时事件

4、单次触发事件

void event_post(uint32_t mask);

执行后会立即触发该事件。

5、清除停止事件

void event_clear(uint32_t mask);

执行后会立即停止该事件的执行。

5、缓存事件触发标志

uint32_t event_pend(void);

该函数放在主循环中执行,会先把所有的事件标志缓存起来,供后续事件判断处理。

6、获取事件状态

uint32_t getEvent(uint32_t mask);

获取事件状态,返回值0表示该事件未触发,非0表示该事件已触发。

示例

#include <stdarg.h>
#include <string.h>
#include <stdio.h>
#include "eventUnit.h"#define EVENT_TIME_CYCLE_10ms           0
#define EVENT_TIME_CYCLE_500ms          1void MAIN_TIM_CALLBACK(uint8_t status, uint32_t param)
{static uint16_t timeCnt_1ms = 0;if(++ timeCnt_1ms == 5){timeCnt_1ms = 0;eventDriver();}
}
void MAIN_TIM_1S_CALLBACK(uint8_t status, uint32_t param)
{eventDriver1s();
}
int main(void)
{myTim3_init(200, 0);myIrqCallback_mainTimCallback.thisCb = MAIN_TIM_CALLBACK;TIM3_callbackRegiste(&myIrqCallback_mainTimCallback);setEvent(EVENT_TIME_CYCLE_10ms, true, true, true, 10);setEvent(EVENT_TIME_CYCLE_500ms, true, true, true, 500);while(1){event_pend();if (getEvent(EVENT_TIME_CYCLE_10ms)){}if (getEvent(EVENT_TIME_CYCLE_500ms)){}}
}

源码

eventUnit.h

#ifndef __EVENTUNIT_H
#define __EVENTUNIT_H
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
// #include "at32f423_clock.h"
#include "cmsis_armcc.h"#define EVENT_INDEX_MAX 32
typedef struct
{bool reload;            //bool flag_1s;            //uint32_t count;          //uint32_t countSet;            //
}eventParams_ts;void eventDriver(void);
void eventDriver1s(void);
void setEvent(uint32_t mask, bool first, bool reload, bool setCover, uint32_t timeOut_ms);
void setEvent1s(uint32_t mask, bool first, bool reload, bool setCover, uint32_t timeOut_s);
void event_post(uint32_t mask);
void event_clear(uint32_t mask);
uint32_t event_pend(void);
uint32_t getEvent(uint32_t mask);
#endif

eventUnit.c

#include "eventUnit.h"volatile eventParams_ts eventParams[EVENT_INDEX_MAX];
volatile uint32_t timerEventMask;
uint32_t getEventMask;
bool eventDriverSta;void eventDriver(void)
{int i;for ( i = 0; i < EVENT_INDEX_MAX; i++){if (eventParams[i].flag_1s == false && eventParams[i].countSet){if (++ eventParams[i].count >= eventParams[i].countSet - 1){eventParams[i].count = 0;if (eventParams[i].reload == false){eventParams[i].countSet = 0;}timerEventMask |= (1 << i);}}}
}
void eventDriver1s(void)
{int i;for ( i = 0; i < EVENT_INDEX_MAX; i++){if (eventParams[i].flag_1s && eventParams[i].countSet){if (++ eventParams[i].count >= eventParams[i].countSet - 1){eventParams[i].count = 0;if (eventParams[i].reload == false){eventParams[i].countSet = 0;}timerEventMask |= (1 << i);}}}
}
void setEvent(uint32_t mask, bool first, bool reload, bool setCover, uint32_t timeOut_ms)
{__set_PRIMASK(1);if (setCover){eventParams[mask].count = 0;}eventParams[mask].countSet = timeOut_ms;eventParams[mask].flag_1s = false;eventParams[mask].reload = reload;if ((timeOut_ms == 0) || first){timerEventMask |= (1 << mask);}__set_PRIMASK(0);//开总中断
}
void setEvent1s(uint32_t mask, bool first, bool reload, bool setCover, uint32_t timeOut_s)
{__set_PRIMASK(1);if (setCover){eventParams[mask].count = 0;}eventParams[mask].countSet = timeOut_s;eventParams[mask].flag_1s = true;eventParams[mask].reload = reload;if ((timeOut_ms == 0) || first){timerEventMask |= (1 << mask);}__set_PRIMASK(0);//开总中断
}
void event_post(uint32_t mask)
{__set_PRIMASK(1);eventParams[mask].countSet = 0;eventParams[mask].count = 0;eventParams[mask].reload = false;timerEventMask |= (1 << mask);__set_PRIMASK(0);//开总中断
}
void event_clear(uint32_t mask)
{__set_PRIMASK(1);eventParams[mask].countSet = 0;eventParams[mask].count = 0;eventParams[mask].reload = false;timerEventMask &= (~(1 << mask));__set_PRIMASK(0);//开总中断
}
uint32_t event_pend(void)
{uint32_t ret = 0;__set_PRIMASK(1);ret = timerEventMask;getEventMask = ret;timerEventMask = 0;__set_PRIMASK(0);//开总中断return ret;
}
uint32_t getEvent(uint32_t mask)
{return getEventMask & (1 << mask);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/8552.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java Io流学习归纳

- 固定套路&#xff1a;1. 创建IO流对象 2. 读写文件 3. 关闭流 - 固定的API方法&#xff1a; //读&#xff1a;read()&#xff1a; /*读一个字节/字符*/int read() /*读一个字节/字符数组*/ int read(byte[] buf)int read(char[] cbuf) //写&#xff1a;wri…

【数字经济】上市公司供应链数字化数据(2000-2022)

数据来源&#xff1a; 时间跨度&#xff1a;2000-2022年 数据范围&#xff1a;各上市企业 数据指标&#xff1a; 样例数据&#xff1a; 参考文献&#xff1a;[1]刘海建,胡化广,张树山,等.供应链数字化的绿色创新效应[J].财经研究,2023,49(03):4-18. 下载链接&#xff1a;https:…

Linux(openEuler、CentOS8)基于chrony企业内网NTP服务器搭建实验

一、知识点 chrony 是由 守护进程 chronyd 以及 命令行工具 chronyc 组成的 chronyd 在后台静默运行并通过 123 端口与时间服务器定时同步时间&#xff0c;默认的配置文件是 /etc/chrony.conf chronyc 通过 323 端口与 chronyd 交互&#xff0c;可监控 chronyd 的性能并在运…

基于springboot+vue+Mysql的口腔管理平台

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

【3dmax笔记】026:挤出和壳修改器的使用

文章目录 一、修改器二、挤出三、壳 一、修改器 3ds Max中的修改器是一种强大的工具&#xff0c;用于创建和修改复杂的几何形状。这些修改器可以改变对象的形状、大小、方向和位置&#xff0c;以生成所需的效果。以下是一些常见的3ds Max修改器及其功能&#xff1a; 挤出修改…

Day22 代码随想录打卡|字符串篇---实现 strStr()

题目&#xff08;leecode T28&#xff09;&#xff1a; 给你两个字符串 haystack 和 needle &#xff0c;请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标&#xff08;下标从 0 开始&#xff09;。如果 needle 不是 haystack 的一部分&#xff0c;则返回 -1…

第 8 章 电机测速(自学二刷笔记)

重要参考&#xff1a; 课程链接:https://www.bilibili.com/video/BV1Ci4y1L7ZZ 讲义链接:Introduction Autolabor-ROS机器人入门课程《ROS理论与实践》零基础教程 8.3.3 电机测速01_理论 测速实现是调速实现的前提&#xff0c;本节主要介绍AB相增量式编码器测速原理。 1.概…

可视化面板布局适配屏幕-基于 flexible.js + rem 智能大屏适配

可视化面板布局适配屏幕-基于 flexible.js rem 智能大屏适配 VScode 安装cssrem插件引入flexible.js在之后的开发都使用rem为单位&#xff0c;安装cssrem插件就是为了快捷将px转为rem我们的设计稿是1920px&#xff0c;设置最小宽度为1024px&#xff0c;最后&#xff0c;我们可…

管理非结构化数据

据IDC调查&#xff0c;当前企业80%的数据为非结构化数据或半结构化数据&#xff0c;而结构化数据是他们管理的重点&#xff0c;数据的大头-非结构化数据却被忽视。然而&#xff0c;非结构化数据也有着它的价值。 管理好非结构化数据对于公司释放有价值资产、高效决策和高效部署…

nodejs之log4js日志管理

log4js官网 npm i log4jsconst log4js require("log4js"); const path require("path"); Object.defineProperties; log4js.configure({appenders: {aaa: {type: "dateFile", //设置为这种类型&#xff0c;日志文件会分割filename: path.reso…

数据安全全场景覆盖

随着万物互联时代的到来&#xff0c;海量物联网设备产生的庞大数据逐渐超出云端服务器的处理能力&#xff0c;同时算力向边缘侧不断迁移&#xff0c;边缘计算逐渐成为云计算的重要延伸和补充。根据《中国边缘计算服务器市场报告》、《中国边缘云计算行业展望报告》等预测&#…

rdflib命名空间的问题

yaga Namespace("https://yago-knowledge.org/resource/") a yaga.Apple b yaga[Appel]这两者的区别&#xff0c;yaga[Appel]这里的Apple是变量&#xff0c;而yaga.Apple生成的实体就是“https://yago-knowledge.org/resource/Apple”

县供电公司员工向媒体投稿发文章用亲身经历告诉你并不难

在县供电公司的日子里,我肩负着一项至关重要的使命——信息宣传工作。这不仅仅是一份职责,更是连接公司与外界的桥梁,通过新闻稿件传递我们的声音,展示我们的成果。然而,回忆起刚刚踏入这个领域的时光,那段经历至今让我感慨万千。 初涉投稿,步履维艰 刚接手这项工作时,我的投稿…

又发现一个ai生成音乐的网站-heymusic

网址 https://heymusic.ai/ 尴尬&#xff0c;不挂梯子能登录进来&#xff0c;但是谷歌账号注册不了&#xff0c;刷新了几遍也没注册上。 看了下价格&#xff0c;应该不是免费的&#xff0c;所以也没了试用的兴趣。 我也不想用别的邮箱注册了&#xff0c;所以只能简单的水一…

Spring Boot应用部署 - Tomcat/Jetty/Undertow容器对比和使用场景

在前面的文章中&#xff0c;我们介绍了如何替换Tomcat容器&#xff0c;现总结下Tomcat/Jetty/Undertow容器。 那在Spring Boot应用部署中&#xff0c;常见的三种Web容器是Tomcat、Jetty和Undertow&#xff0c;它们各有特点&#xff0c;适用于不同的应用场景&#xff1a; Tomc…

频谱分析:深入解析与全面介绍

频谱分析 一、引言 频谱分析&#xff0c;作为一种广泛应用于信号处理和波谱分析的方法&#xff0c;其在现代科技领域的重要性不言而喻。从基础的物理现象到复杂的通信系统&#xff0c;频谱分析都扮演着至关重要的角色。本文将对频谱分析进行深入的解析和全面的介绍&#xff0…

速盾的具体防御能力如何?

速盾是一家专注于网络安全领域的技术公司&#xff0c;致力于为企业提供全方位的网络安全防护服务。其具体防御能力主要体现在以下几个方面&#xff1a; DDoS防御&#xff1a;速盾采用智能化的DDoS防护系统&#xff0c;能够及时识别和拦截各类DDoS攻击流量&#xff0c;确保企业网…

A*算法求最短路

Problem: 无链接 文章目录 思路解题方法复杂度Code 思路 这是一个经典的A寻路算法问题。A算法是一种启发式搜索算法&#xff0c;题解结合了最佳优先搜索和Dijkstra算法的优点&#xff0c;能够在寻找最短路径的过程中避免大量的无谓搜索&#xff0c;提高了效率。 在这个问题中&a…

VxTerm使用教程:连接SSH服务端设备,什么是SSH

一、什么是SSH&#xff1f; <摘自百度> 安全外壳协议 SSH&#xff0c;即安全外壳协议&#xff08;Secure Shell&#xff09;&#xff0c;是一种网络协议&#xff0c;用于在计算机网络上提供安全的远程登录和命令执行功能。 SSH通过加密通信通道来保护数据传输&#xff0c…

电子元器件选型中的关键考虑因素

电子元器件选型是电子设计中的重要环节&#xff0c;其直接影响到电路的性能、成本、可靠性等。在进行电子元器件选型时&#xff0c;应综合考虑以下关键因素&#xff1a;      1. 技术指标      功能&#xff1a; 所选元器件应能够满足电路的功能要求。例如&#xff0c;…