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

简要

  最大支持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          1

void 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);
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值