在状态机 + 事件驱动的嵌入式架构中,如果所有事件都简单塞进一个 FIFO,高优先级事件可能被低优先级事件阻塞,导致实时性下降。实现事件优先级排序的核心思想是:让高优先级事件先于低优先级事件被处理,同时不破坏状态机的主逻辑。总体设计思想:把系统行为抽象为事件触发状态迁移,用 FIFO 解耦事件生产与消费,用优先级保证关键事件实时响应。
c
`#ifndef CORE_EVENT_H
#define CORE_EVENT_H
#include <stdint.h>
#include <stdbool.h>
#define EVT_QUEUE_SIZE 8
typedef uint16_t EvtId;
typedef uint8_t EvtPrio;
/* 事件参数 */
typedef enum {
PARAM_NONE = 0,
PARAM_U8,
PARAM_U16,
PARAM_U32,
} ParamType;
typedef union {
uint8_t u8;
uint16_t u16;
uint32_t u32;
} ParamData;
typedef struct {
ParamType type;
ParamData data;
} EventParam;
/* 事件 */
typedef struct {
EvtId id;
EventParam param;
} Event;
/* 优先级 */
typedef enum {
PRIO_HIGH = 0,
PRIO_MID,
PRIO_LOW,
PRIO_NUM
} EvtPrioEnum;
void Event_Init(void);
bool Event_Post(EvtId id, const EventParam *p);
bool Event_Get(Event *e);
#endif`
c
#include "core_event.h"
typedef struct {
Event buf[EVT_QUEUE_SIZE];
uint8_t head;
uint8_t tail;
} EventQueue;
static EventQueue s_queue[PRIO_NUM];
void Event_Init(void)
{
for (int i = 0; i < PRIO_NUM; i++) {
s_queue[i].head = 0;
s_queue[i].tail = 0;
}
}
static bool Enqueue(EventQueue *q, const Event *e)
{
uint8_t next = (q->tail + 1) % EVT_QUEUE_SIZE;
if (next == q->head) return false;
q->buf[q->tail] = *e;
q->tail = next;
return true;
}
static bool Dequeue(EventQueue *q, Event *e)
{
if (q->head == q->tail) return false;
*e = q->buf[q->head];
q->head = (q->head + 1) % EVT_QUEUE_SIZE;
return true;
}
bool Event_Post(EvtId id, const EventParam *p)
{
static const EvtPrio prio[] = {
[1] = PRIO_HIGH,
[2] = PRIO_HIGH,
[3] = PRIO_MID,
[4] = PRIO_LOW,
};
Event e = {
.id = id,
.param = *p
};
EvtPrio p = (id < sizeof(prio)) ? prio[id] : PRIO_LOW;
return Enqueue(&s_queue[p], &e);
}
bool Event_Get(Event *e)
{
for (int p = PRIO_HIGH; p < PRIO_NUM; p++) {
if (Dequeue(&s_queue[p], e))
return true;
}
return false;
}
c
#ifndef CORE_FSM_H
#define CORE_FSM_H
#include "core_event.h"
typedef void (*ActionFn)(Event *e);
typedef struct {
uint8_t state;
EvtId event;
ActionFn action;
uint8_t nextState;
} FsmTable;
void FSM_Init(const FsmTable *table, uint8_t tableSize, uint8_t initState);
void FSM_Dispatch(Event *e);
#endif
c
#include "core_fsm.h"
static const FsmTable *s_table;
static uint8_t s_tableSize;
static uint8_t s_state;
void FSM_Init(const FsmTable *table, uint8_t tableSize, uint8_t initState)
{
s_table = table;
s_tableSize = tableSize;
s_state = initState;
}
void FSM_Dispatch(Event *e)
{
for (uint8_t i = 0; i < s_tableSize; i++) {
const FsmTable *t = &s_table[i];
if (t->state == s_state && t->event == e->id) {
if (t->action) t->action(e);
s_state = t->nextState;
return;
}
}
}
应用层:
c
typedef enum {
EVT_KEY = 1,
EVT_TEMP,
EVT_FAULT,
EVT_MAX
} AppEvent;
typedef enum {
ST_IDLE = 0,
ST_RUN,
ST_ERR,
ST_MAX
} AppState;
c
#include "core_fsm.h"
#include "app_event.h"
#include <stdio.h>
static void Act_Start(Event *e);
static void Act_Temp(Event *e);
static void Act_Fault(Event *e);
static void Act_Null(Event *e) { (void)e; }
static const FsmTable s_appFsm[] = {
{ST_IDLE, EVT_KEY, Act_Start, ST_RUN},
{ST_RUN, EVT_TEMP, Act_Temp, ST_RUN},
{ST_RUN, EVT_FAULT, Act_Fault, ST_ERR},
{ST_ERR, EVT_KEY, Act_Start, ST_IDLE},
};
void App_FsmInit(void)
{
FSM_Init(s_appFsm, sizeof(s_appFsm)/sizeof(s_appFsm[0]), ST_IDLE);
}
static void Act_Start(Event *e)
{
printf("Start, key=%d\r\n", e->param.data.u8);
}
static void Act_Temp(Event *e)
{
printf("Temp=%d\r\n", e->param.data.u16);
}
static void Act_Fault(Event *e)
{
printf("Fault=%lu\r\n", e->param.data.u32);
}
主程序
c
#include "core_event.h"
#include "core_fsm.h"
#include "app_event.h"
int main(void)
{
EventParam p;
Event_Init();
App_FsmInit();
/* 模拟事件 */
p.type = PARAM_U8; p.data.u8 = 1;
Event_Post(EVT_KEY, &p);
p.type = PARAM_U16; p.data.u16 = 25;
Event_Post(EVT_TEMP, &p);
while (1) {
Event e;
if (Event_Get(&e)) {
FSM_Dispatch(&e);
} else {
/* 低功耗 / 睡眠 */
}
}
}