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保存当前状态和错误码,便于外部查询和日志记录。