核心原则
杜绝零散全局变量、杜绝魔数、按场景结构化收拢,易维护、易初始化、易传参、易兼容协议。
一、场景1:基础少量配置(5个以内,简单模块)
规范:常量 + 宏定义(只读固定配置)
适用:固件固定参数、波特率、超时阈值、引脚号
// config.h 统一归集,不散落代码里
#define UART_BAUD_RATE 115200U
#define MODULE_TIMEOUT_MS 500U
#define LED_GPIO_PIN GPIO_PIN_5
规范约束:
- 全大写+下划线命名;
- 加类型后缀
U/L防隐式转换; - 全部放独立头文件,禁止散落在业务c文件。
二、场景2:可修改/运行时可调配置(最常用!重点)
规范:用 结构体聚合所有参数(企业强制规范)
优势:传参只传一个结构体指针、初始化集中、代码整洁、不易漏参数。
1. 定义配置结构体(按模块拆分,不全局一锅烩)
// app_config.h
typedef struct
{
/* 通信配置 */
uint32_t uart_baud;
uint16_t mqtt_port;
uint8_t mqtt_client_id[32];
/* 业务阈值 */
uint16_t temp_high_limit;
uint16_t humi_low_limit;
/* 硬件控制 */
uint8_t pump_ctrl_enable;
uint32_t sample_interval_ms;
} AppConfig_t;
2. 全局单实例 + 外部引用规范
// app_config.c
static AppConfig_t g_app_config; // static 私有化,防越权修改
// 只读获取接口(规范:禁止直接外部修改全局结构体)
const AppConfig_t *AppConfig_GetReadOnly(void)
{
return &g_app_config;
}
// 统一修改接口(校验+赋值,防非法参数)
int AppConfig_Update(const AppConfig_t *new_cfg)
{
if(NULL == new_cfg) return -1;
// 参数合法性校验(强规范必备)
if(new_cfg->sample_interval_ms > 10000U) return -2;
memcpy(&g_app_config, new_cfg, sizeof(AppConfig_t));
return 0;
}
3. 默认初始化规范
void AppConfig_InitDefault(void)
{
AppConfig_t def = {
.uart_baud = 115200U,
.mqtt_port = 1883U,
.temp_high_limit = 600U,
.sample_interval_ms = 1000U,
.pump_ctrl_enable = 1U
};
memcpy(&g_app_config, &def, sizeof(def));
}
4. 业务层使用(干净极简)
void Sensor_Start(void)
{
const AppConfig_t *cfg = AppConfig_GetReadOnly();
HAL_UART_Init(cfg->uart_baud);
MQTT_Connect(cfg->mqtt_port);
}
三、场景3:多组不同配置(出厂配置/用户配置/调试配置)
规范:多结构体实例 + 切换接口
static AppConfig_t g_factory_cfg;
static AppConfig_t g_user_cfg;
// 一键切换出厂默认
void AppConfig_RestoreFactory(void);
四、场景4:需要落盘保存(Flash/EEPROM)
规范:结构体 + 校验和CRC(工业防损坏规范)
typedef struct
{
AppConfig_t cfg;
uint32_t crc32; // 校验位,防止配置损坏
} SaveConfig_t;
读写时:校验CRC合法再加载,不合法自动恢复默认。
五、C语言编码硬性规范(团队必守)
- 禁止零散全局变量
多个参数绝不单独定义int a; int b;,必须结构体收拢。 - 私有全局static化
配置实例加static隐藏,外部只能通过函数访问,禁止直接extern篡改。 - 参数必须合法性校验
范围、边界、空指针全校验,避免非法配置死机。 - 统一初始化入口
上电只调用一次Config_Init(),不零散初始化。 - 字符串/数组固定长度
比如mqtt clientid[32],避免动态内存碎片,适配嵌入式。 - 搭配你之前学的
snprintf
拼接配置字符串时,用结构体字段统一取值,安全格式化。
六、极简选型口诀
- 固定不变 → 宏定义归集头文件
- 运行可改少量/大量 → 结构体+私有全局+读写接口
- 需要存储 → 结构体+CRC校验落盘
- 多套参数 → 多实例结构体切换
需要我结合你鸿蒙Hi3861 + MQTT项目,直接给你一套可照搬的完整配置结构体+初始化+读写模板吗?