1. 网关启动状态机初始化

网关启动状态机初始化 学习卡片

任务说明

实现智能网关上电后的启动状态机,依次完成硬件初始化、网络配置加载、核心服务启动三个阶段,最终进入运行状态。若任一阶段失败,则进入故障状态并记录错误码。状态转换关系如下:

POWER_ON → HW_INIT → NET_CFG_LOAD → SERVICE_START → RUNNING
                              ↓                ↓
                           FAULT(任一阶段失败)

核心实现

#include <stdio.h>
#include <string.h>

/* 状态定义 */
typedef enum {
    ST_POWER_ON,
    ST_HW_INIT,
    ST_NET_CFG_LOAD,
    ST_SERVICE_START,
    ST_RUNNING,
    ST_FAULT
} GatewayState;

/* 事件定义 */
typedef enum {
    EVT_INIT_OK,
    EVT_INIT_FAIL,
    EVT_CFG_OK,
    EVT_CFG_FAIL,
    EVT_SERVICE_OK,
    EVT_SERVICE_FAIL
} GatewayEvent;

/* 错误码 */
typedef enum {
    ERR_NONE = 0,
    ERR_HW_INIT = 1,
    ERR_NET_CFG = 2,
    ERR_SERVICE = 3
} ErrorCode;

/* 状态机上下文 */
typedef struct {
    GatewayState state;
    ErrorCode error;
    int hw_ready;
    int cfg_loaded;
    int service_up;
} GatewayContext;

/* 硬件初始化:模拟检测外设就绪 */
static int hw_init(void) {
    /* 实际工程中此处调用具体外设驱动 */
    return 1;  /* 返回1表示成功 */
}

/* 网络配置加载:模拟从Flash读取配置 */
static int net_cfg_load(void) {
    /* 实际工程中此处读取配置文件并解析 */
    return 1;  /* 返回1表示成功 */
}

/* 服务启动:模拟启动核心服务 */
static int service_start(void) {
    /* 实际工程中此处启动MQTT/HTTP等服务线程 */
    return 1;  /* 返回1表示成功 */
}

/* 状态转移处理 */
static void handle_event(GatewayContext *ctx, GatewayEvent evt) {
    switch (ctx->state) {
    case ST_POWER_ON:
        if (evt == EVT_INIT_OK) {
            ctx->state = ST_HW_INIT;
            ctx->hw_ready = 1;
        } else {
            ctx->state = ST_FAULT;
            ctx->error = ERR_HW_INIT;
        }
        break;

    case ST_HW_INIT:
        if (evt == EVT_CFG_OK) {
            ctx->state = ST_NET_CFG_LOAD;
            ctx->cfg_loaded = 1;
        } else {
            ctx->state = ST_FAULT;
            ctx->error = ERR_NET_CFG;
        }
        break;

    case ST_NET_CFG_LOAD:
        if (evt == EVT_SERVICE_OK) {
            ctx->state = ST_SERVICE_START;
            ctx->service_up = 1;
        } else {
            ctx->state = ST_FAULT;
            ctx->error = ERR_SERVICE;
        }
        break;

    case ST_SERVICE_START:
        if (evt == EVT_INIT_OK) {
            ctx->state = ST_RUNNING;
        }
        break;

    default:
        break;
    }
}

/* 启动流程驱动 */
static void gateway_boot(GatewayContext *ctx) {
    ctx->state = ST_POWER_ON;
    ctx->error = ERR_NONE;
    ctx->hw_ready = 0;
    ctx->cfg_loaded = 0;
    ctx->service_up = 0;

    /* 阶段1:硬件初始化 */
    if (hw_init()) {
        handle_event(ctx, EVT_INIT_OK);
    } else {
        handle_event(ctx, EVT_INIT_FAIL);
        return;
    }

    /* 阶段2:网络配置加载 */
    if (net_cfg_load()) {
        handle_event(ctx, EVT_CFG_OK);
    } else {
        handle_event(ctx, EVT_CFG_FAIL);
        return;
    }

    /* 阶段3:服务启动 */
    if (service_start()) {
        handle_event(ctx, EVT_SERVICE_OK);
    } else {
        handle_event(ctx, EVT_SERVICE_FAIL);
        return;
    }

    /* 进入运行态 */
    handle_event(ctx, EVT_INIT_OK);
}

/* 状态名映射 */
static const char* state_name(GatewayState s) {
    switch (s) {
    case ST_POWER_ON:      return "POWER_ON";
    case ST_HW_INIT:       return "HW_INIT";
    case ST_NET_CFG_LOAD:  return "NET_CFG_LOAD";
    case ST_SERVICE_START: return "SERVICE_START";
    case ST_RUNNING:       return "RUNNING";
    case ST_FAULT:         return "FAULT";
    default:               return "UNKNOWN";
    }
}

int main(void) {
    GatewayContext ctx;
    gateway_boot(&ctx);

    printf("Final state: %s\n", state_name(ctx.state));
    printf("Error code: %d\n", ctx.error);
    printf("hw_ready=%d cfg_loaded=%d service_up=%d\n",
           ctx.hw_ready, ctx.cfg_loaded, ctx.service_up);

    /* 验证:正常路径应到达RUNNING且无错误 */
    if (ctx.state == ST_RUNNING && ctx.error == ERR_NONE) {
        printf("BOOT SEQUENCE PASSED\n");
        return 0;
    } else {
        printf("BOOT SEQUENCE FAILED\n");
        return 1;
    }
}

编译与运行

gcc -o gateway_boot gateway_boot.c
./gateway_boot

验证方法

程序输出应包含以下内容即判定通过:

Final state: RUNNING
Error code: 0
hw_ready=1 cfg_loaded=1 service_up=1
BOOT SEQUENCE PASSED

若要验证故障路径,可将hw_init()、net_cfg_load()或service_start()中的返回值改为0,重新编译运行后应看到Final state: FAULT及对应的非零错误码。

状态机说明

本实现采用事件驱动方式:每个启动阶段完成后产生对应成功事件,驱动状态前进;失败则产生失败事件,直接跳转到FAULT状态。实际工程中,各初始化函数内部应包含真实硬件寄存器操作、配置文件解析和服务线程创建逻辑,此处用返回固定值模拟以聚焦状态机本身。状态机上下文结构体GatewayContext保存当前状态和错误码,便于外部查询和日志记录。