第三章:嵌入式开发状态机的进阶技巧-C源码演示

第三章:状态机的进阶技巧

在前两章中,我们介绍了状态机的基本概念和简单实现方法。本章将深入探讨状态机的进阶技巧,包括状态机与事件驱动的结合、分层状态机设计、状态机的内存管理以及状态持久化与恢复等内容。这些技巧将帮助我们构建更加复杂、灵活和健壮的状态机系统。

3.1 状态机与事件驱动

事件驱动编程是一种常见的编程范式,特别适合与状态机结合使用。在事件驱动的状态机中,系统不是主动轮询状态和条件,而是被动地等待事件发生,然后根据当前状态和接收到的事件执行相应的动作。

3.1.1 事件队列

事件驱动状态机的核心是事件队列,它用于存储待处理的事件。事件可以来自多个源,如硬件中断、定时器、用户输入或其他任务。

// 事件结构体
typedef struct {
   
   
    EventType type;        // 事件类型
    void *data;            // 事件数据(可选)
    uint32_t timestamp;    // 事件时间戳
} Event;

// 事件队列结构体
typedef struct {
   
   
    Event *events;         // 事件数组
    uint16_t capacity;     // 队列容量
    uint16_t size;         // 当前事件数量
    uint16_t front;        // 队列头索引
    uint16_t rear;         // 队列尾索引
} EventQueue;

// 初始化事件队列
bool event_queue_init(EventQueue *queue, uint16_t capacity) {
   
   
    if (queue == NULL || capacity == 0) {
   
   
        return false;
    }
    
    queue->events = (Event *)malloc(capacity * sizeof(Event));
    if (queue->events == NULL) {
   
   
        return false;  // 内存分配失败
    }
    
    queue->capacity = capacity;
    queue->size = 0;
    queue->front = 0;
    queue->rear = 0;
    
    return true;
}

// 销毁事件队列
void event_queue_destroy(EventQueue *queue) {
   
   
    if (queue == NULL || queue->events == NULL) {
   
   
        return;
    }
    
    free(queue->events);
    queue->events = NULL;
    queue->capacity = 0;
    queue->size = 0;
    queue->front = 0;
    queue->rear = 0;
}

// 向队列添加事件
bool event_queue_push(EventQueue *queue, Event *event) {
   
   
    if (queue == NULL || queue->events == NULL || event == NULL) {
   
   
        return false;
    }
    
    // 检查队列是否已满
    if (queue->size >= queue->capacity) {
   
   
        return false;  // 队列已满
    }
    
    // 添加事件到队列尾部
    queue->events[queue->rear] = *event;
    queue->rear = (queue->rear + 1) % queue->capacity;  // 循环队列
    queue->size++;
    
    return true;
}

// 从队列获取事件
bool event_queue_pop(EventQueue *queue, Event *event) {
   
   
    if (queue == NULL || queue->events == NULL || event == NULL) {
   
   
        return false;
    }
    
    // 检查队列是否为空
    if (queue->size == 0) {
   
   
        return false;  // 队列为空
    }
    
    // 获取队列头部事件
    *event = queue->events[queue->front];
    queue->front = (queue->front + 1) % queue->capacity;  // 循环队列
    queue->size--;
    
    return true;
}

3.1.2 事件驱动状态机框架

下面是一个基于事件驱动的状态机框架:

// 状态机结构体
typedef struct {
   
   
    State current_state;    // 当前状态
    EventQueue event_queue; // 事件队列
    bool running;           // 运行标志
} StateMachine;

// 状态处理函数类型
typedef State (*StateHandler)(StateMachine *sm, Event *event);

// 状态处理函数映射表
StateHandler state_handlers[STATE_MAX] = {
   
   
    handle_state_idle,
    handle_state_active,
    handle_state_paused,
    handle_state_error
    // 其他状态处理函数...
};

// 初始化状态机
bool state_machine_init(StateMachine *sm, State initial_state, uint16_t queue_capacity) {
   
   
    if (sm == NULL) {
   
   
        return false;
    }
    
    sm->current_state = initial_state;
    sm->running = false;
    
    // 初始化事件队列
    if (!event_queue_init(&sm->event_queue, queue_capacity)) {
   
   
        return false;
    }
    
    return true;
}

// 销毁状态机
void state_machine_destroy(StateMachine *sm) {
   
   
    if (sm == NULL) {
   
   
        return;
    }
    
    sm->running = false;
    event_queue_destroy(&sm->event_queue);
}

// 向状态机发送事件
bool state_machine_send_event(StateMachine *sm, Event *event) {
   
   
    if (sm == NULL || event == NULL) {
   
   
        return false;
    }
    
    // 添加事件到队列
    return event_queue_push(&sm->event_queue, event);
}

// 状态机主循环
void state_machine_run(StateMachine *sm) {
   
   
    if (sm == NULL) {
   
   
        return;
    }
    
    sm->running = true;
    
    while (sm->running) {
   
   
        Event event;
        
        // 从队列获取事件
        if (event_queue_pop(&sm->event_queue, &event)) {
   
   
            // 调用当前状态的处理函数
            if (sm->current_state < STATE_MAX && state_handlers[sm->current_state] != NULL) {
   
   
                State next_state = state_handlers[sm->current_state](sm, &event);
                
                // 如果状态发生变化
                if (next_state != sm->current_state) {
   
   
                    // 执行状态转换
                    sm->current_state = next_state;
                }
            }
        } else {
   
   
            // 队列为空,可以休眠一段时间或让出CPU
            sleep_or_yield();
        }
    }
}

// 停止状态机
void state_machine_stop(StateMachine *sm) {
   
   
    if (sm == NULL) {
   
   
        return;
    }
    
    sm->running = false;
}

3.1.3 状态处理函数示例

// 空闲状态处理函数
State handle_state_idle(StateMachine *sm, Event *event) {
   
   
    switch (event->type) {
   
   
        case EVENT_START:
            printf("Idle state: Received START event, transitioning to ACTIVE\n");
            // 执行从IDLE到ACTIVE的转换动作
            return STATE_ACTIVE;
            
        case EVENT_ERROR:
            printf("Idle state: Received ERROR event, transitioning to ERROR\n");
            // 执行从IDLE到ERROR的转换动作
            return STATE_ERROR;
            
        default:
            printf("Idle state: Unhandled event %d\n", event->type);
            return STATE_IDLE;  // 保持当前状态
    }
}

// 活动状态处理函数
State handle_state_active(StateMachine *sm, Event *event) {
   
   
    switch (event->type) {
   
   
        case EVENT_PAUSE:
            printf("Active state: Received PAUSE event, transitioning to PAUSED\n");
            // 执行从ACTIVE到PAUSED的转换动作
            return STATE_PAUSED;
            
        case EVENT_STOP:
            printf("Active state: Received STOP event, transitioning to IDLE\n");
            // 执行从ACTIVE到IDLE的转换动作
            return STATE_IDLE;
            
        case EVENT_ERROR:
            printf("Active state: Received ERROR event, transitioning to ERROR\n");
            // 执行从ACTIVE到ERROR的转换动作
            return STATE_ERROR;
            
        default:
            printf("Active state: Unhandled event %d\n", event->type);
            return STATE_ACTIVE;  // 保持当前状态
    }
}

// 其他状态处理函数...

3.1.4 事件生成示例

事件可以从多个源生成,例如:

// 定时器中断处理函数
void timer_interrupt_handler(void) {
   
   
    // 创建定时器事件
    Event timer_event;
    timer_event.type = EVENT_TIMER;
    timer_event.data = NULL;
    timer_event.timestamp = get_system_time();
    
    // 发送事件到状态机
    state_machine_send_event(&global_state_machine, &timer_event);
}

// 按钮中断处理函数
void button_interrupt_handler(uint8_t button_id) {
   
   
    // 创建按钮事件
    Event button_event;
    button_event.type = EVENT_BUTTON_PRESS;
    
    // 分配并设置按钮数据
    ButtonData *button_data = (ButtonData *)malloc(sizeof(ButtonData));
    if (button_data != NULL) {
   
   
        button_data->button_id = button_id;
        button_data->press_time = get_system_time();
        button_event.data = button_data;
    } else {
   
   
        button_event.data = NULL;
    }
    
    button_event.timestamp = get_system_time();
    
    // 发送事件到状态机
    state_machine_send_event(&global_state_machine, &button_event);
}

3.1.5 事件驱动状态机的优缺点

优点:

  1. 响应性:能够快速响应异步事件
  2. 资源效率:在没有事件时可以休眠,节省CPU资源
  3. 解耦:事件生成和处理逻辑分离,提高模块化
  4. 可扩展性:容易添加新的事件类型和处理逻辑

缺点:

  1. 复杂性:比简单轮询更复杂,需要额外的队列管理
  2. 内存开销:事件队列需要额外的内存
  3. 调试难度:异步事件处理可能增加调试难度
  4. 优先级处理:基本实现不支持事件优先级,可能需要额外设计

3.2 分层状态机设计

随着系统复杂度增加,状态数量可能会爆炸性增长。分层状态机(Hierarchical State Machine,HSM)通过引入状态层次结构,有效地减少状态数量,提高状态机的可管理性。

3.2.1 分层状态机的概念

在分层状态机中,状态可以包含子状态,形成层次结构。当一个事件在当前状态无法处理时,会沿着状态层次向上传递,直到找到能处理该事件的父状态。

分层状态机的主要特点:

  1. 状态继承:子状态继承父状态的行为
  2. 事件冒泡:未处理的事件向上传递
  3. 转换层次:可以在不同层次间进行状态转换

3.2.2 分层状态机的C语言实现

// 状态ID定义
typedef enum {
   
   
    // 顶层状态
    STATE_TOP = 0,  // 虚拟顶层状态
    STATE_OPERATIONAL,
    STATE_FAULT,
    
    // STATE_OPERATIONAL的子状态
    STATE_IDLE,
    STATE_ACTIVE,
    STATE_SUSPENDED,
    
    // STATE_ACTIVE的子状态
    STATE_INITIALIZING,
    STATE_RUNNING,
    STATE_FINALIZING,
    
    // STATE_FAULT的子状态
    STATE_RECOVERABLE_FAULT,
    STATE_FATAL_FAULT,
    
    STATE_MAX
} StateId;

// 状态处理结果
typedef enum {
   
   
    HANDLED,            // 事件已处理
    NOT_HANDLED,        // 事件未处理,应传递给父状态
    TRANSITION,         // 状态转换
    SUPER                // 获取父状态
} StateResult;

// 状态处理函数类型
typedef StateResult (*StateHandler)(StateMachine *sm, Event *event);

// 状态结构体
typedef struct {
   
   
    StateId id;              // 状态ID
    StateHandler handler;    // 状态处理函数
    StateId parent_id;       // 父状态ID
} State;

// 状态表
const State state_table[STATE_MAX] = {
   
   
    {
   
   STATE_TOP, handle_state_top, STATE_TOP},  // 顶层状态是自己的父状态
    {
   
   STATE_OPERATIONAL, handle_state_operational, STATE_TOP},
    {
   
   STATE_FAULT, handle_state_fault, STATE_TOP},
    
    {
   
   STATE_IDLE, handle_state_idle, STATE_OPERATIONAL},
    {
   
   STATE_ACTIVE, handle_state_active, STATE_OPERATIONAL},
    {
   
   STATE_SUSPENDED, handle_state_suspended, STATE_OPERATIONAL},
    
    {
   
   STATE_INITIALIZING, handle_state_initializing, STATE_ACTIVE},
    {
   
   STATE_RUNNING, handle_state_running, STATE_ACTIVE},
    {
   
   STATE_FINALIZING, handle_state_finalizing, STATE_ACTIVE},
    
    {
   
   STATE_RECOVERABLE_FAULT, handle_state_recoverable_fault, STATE_FAULT},
    {
   
   STATE_FATAL_FAULT, handle_state_fatal_fault, STATE_FAULT}
};

// 分层状态机结构体
typedef struct {
   
   
    StateId current_state;   // 当前状态ID
    EventQueue event_queue;  // 事件队列
    bool running;            // 运行标志
} HierarchicalStateMachine;

// 初始化分层状态机
bool hsm_init(HierarchicalStateMachine *hsm, StateId initial_state, uint16_t queue_capacity) {
   
   
    if (hsm == NULL || initial_state >= STATE_MAX) {
   
   
        return false;
    }
    
    hsm->current_state = initial_state;
    hsm->running = false;
    
    // 初始化事件队列
    if (!event_queue_init(&hsm->event_queue, queue_capacity)) {
   
   
        return false;
    }
    
    // 执行初始状态的入口动作
    Event entry_event;
    entry_event.type = EVENT_ENTRY;
    entry_event.data = NULL;
    entry_event.timestamp = get_system_time();
    
    hsm_dispatch(hsm, &entry_event);
    
    return true;
}

// 分发事件到状态处理函数
void hsm_dispatch(HierarchicalStateMachine *hsm, Event *event) {
   
   
    if (hsm == NULL || event == NULL || hsm->current_state >= STATE_MAX) {
   
   
        return;
    }
    
    StateId state_id = hsm->current_state;
    StateResult result;
    
    // 尝试在当前状态及其父状态链中处理事件
    do {
   
   
        // 获取状态处理函数
        StateHandler handler = state_table[state_id].handler;
        if (handler == NULL) {
   
   
            break;
        }
        
        // 调用状态处理函数
        result = handler(hsm, event);
        
        // 根据处理结果执行相应操作
        switch (result) {
   
   
            case HANDLED:
                return;  // 事件已处理,结束
                
            case NOT_HANDLED:
                // 事件未处理,尝试父状态
                state_id = state_table[state_id].parent_id;
                break;
                
            case TRANSITION:
                // 状态转换,结束当前处理
                return;
                
            case SUPER:
                // 获取父状态,继续处理
                state_id = state_table[state_id].parent_id;
                break;
        }
    } while (state_id != STATE_TOP);  // 直到达到顶层状态
}

// 执行状态转换
void hsm_transition(HierarchicalStateMachine *hsm, StateId target_state) {
   
   
    if (hsm == NULL || target_state >= STATE_MAX) {
   
   
        return;
    }
    
    StateId source_state = hsm->current_state;
    StateId source_path[STATE_MAX];
    StateId target_path[STATE_MAX];
    int source_depth = 0;
    int target_depth = 0;
    
    // 构建源状态路径(从当前状态到顶层状态)
    StateId state_id = source_state;
    while (state_id != STATE_TOP) {
   
   
        source_path[source_depth++] = state_id;
        state_id = state_table[state_id].parent_id;
    }
    
    // 构建目标状态路径(从目标状态到顶层状态)
    state_id = target_state;
    while (state_id != STATE_TOP) {
   
   
        target_path[target_depth++] = state_id;
        state_id = state_table[state_id].parent_id;
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值