app_led_cfg.c
get_sys_color_status()(hmi/led/app_led_cfg.c:47-77)4.2 get_soc_color_to_rgb()(hmi/led/app_led_cfg.c:79-97)4.3 颜色值的后续处理4.4 与定时/调度的关系5. 对外接口6. 依赖关系7. 备注与风险点源文件路径:
hmi/led/app_led_cfg.c所属模块:hmi/led(人机界面 - WS2812 灯带配置层) 代码行数:105
1. 文件职责
本文件是灯带模块的纯查表函数实现,只做一件事:把业务状态枚举翻译成 24 位 RGB 颜色值。它不访问任何硬件、不读写全局变量、不做任何业务判断,是两个无副作用的 switch 查表函数。
它处在灯带数据流的"最后一跳之前"位置:上游由 hmi/led/app_led.c:156-157 的 led_build_full_buffer() 传入 STATUS_LED_COLOR_E(系统状态,来自 sys_current_status_color)和 SOC_LED_COLOR_E(联网状态,来自 g_stEMSInfo.bIsLogin);下游返回值被 apply_brightness() 做亮度缩放后送进 ws2812_set_color_hex() 编码。
本文件被谁驱动:不主动运行,完全由 led_display_task() → led_build_full_buffer() 的调用链驱动,即"事件驱动 + 1 秒兜底刷新"。
它不包含状态机、不含静态缓冲,唯一的行为细节是 default 分支统一返回 0(全灭)。
2. 关键数据结构与宏
本文件不定义任何结构体、枚举或宏,全部使用 hmi/led/app_led_cfg.h 中的定义。
| 名称 | 类型(结构体/枚举/宏/联合体) | 说明 |
|---|---|---|
STATUS_LED_COLOR_E | 枚举(hmi/led/app_led_cfg.h:48-54) | 入参类型 1:0=SYS_STATUS_NOT_RUN_LED_OFF、1=SYS_STATUS_NORMAL_LED_GREEN、2=SYS_STATUS_FAULT_LED_RED、3=SYS_STATUS_WARNING_LED_YELLOW |
SOC_LED_COLOR_E | 枚举(hmi/led/app_led_cfg.h:58-62) | 入参类型 2:0=SOC_LED_BLUE(未联网)、1=SOC_LED_WHITE(已联网) |
SYS_COLOR_OFF | 宏(0x000000,app_led_cfg.h:26) | 熄灭色,对应 SYS_STATUS_NOT_RUN_LED_OFF |
SYS_COLOR_GREEN | 宏(0x00FF00,app_led_cfg.h:27) | 正常绿 |
SYS_COLOR_RED | 宏(0xFF0000,app_led_cfg.h:28) | 故障红 |
SYS_COLOR_YELLOW | 宏(0xFFFF00,app_led_cfg.h:29) | 告警黄 |
SOC_COLOR_WHITE / SOC_COLOR_BLUE | 宏(app_led_cfg.h:32-33,值 0xFFFFFF/0x0000FF) | 定义了但在本文件中未被使用,本文件用的是等值字面量 |
u32 | 类型别名(includes.h) | 函数返回类型(24 位有效颜色) |
3. 函数清单
| 函数名 | 作用域(static/全局) | 说明(一句话) |
|---|---|---|
get_sys_color_status | 全局(定义 hmi/led/app_led_cfg.c:47) | 按 STATUS_LED_COLOR_E 返回长灯带颜色:灭/绿/红/黄,未识别值返回 0 |
get_soc_color_to_rgb | 全局(定义 hmi/led/app_led_cfg.c:79) | 按 SOC_LED_COLOR_E 返回短灯带颜色:白(联网)/蓝(未联网),未识别值返回 0 |
本文件共 2 个函数,已全部列出。文件内无 static 函数、无静态变量。
4. 核心逻辑解析
4.1 get_sys_color_status()(hmi/led/app_led_cfg.c:47-77)
u32 color_value;
switch (color)
{
case SYS_STATUS_NOT_RUN_LED_OFF: color_value = SYS_COLOR_OFF; break; // 0x000000
case SYS_STATUS_NORMAL_LED_GREEN: color_value = SYS_COLOR_GREEN; break; // 0x00FF00
case SYS_STATUS_FAULT_LED_RED: color_value = SYS_COLOR_RED; break; // 0xFF0000
case SYS_STATUS_WARNING_LED_YELLOW: color_value = SYS_COLOR_YELLOW; break; // 0xFFFF00
default: color_value = 0; break;
}
return color_value;
- 无状态、无副作用,同一输入永远返回同一颜色。
- 变量
color_value在switch前未初始化,所有分支(含default)都赋值后才return,逻辑上无"未初始化读取"问题;但如果将来新增分支漏写break/赋值,编译器不会告警(Keil 对switch覆盖性检查较弱)。 - 映射关系与
hmi/led.c:628-656的状态判定一一对应:故障→红、告警(BMS 已连接但未工作)→黄、正常(cNormalMode/cUPS)→绿、其余→灭。
4.2 get_soc_color_to_rgb()(hmi/led/app_led_cfg.c:79-97)
switch (color)
{
case SOC_LED_WHITE: color_value = 0xFFFFFF; break; // 白色(已联网)
case SOC_LED_BLUE: color_value = 0x0000FF; break; // 蓝色(未联网)
default: color_value = 0; break;
}
return color_value;
- 入参由
hmi/led/app_led.c:105的(SOC_LED_COLOR_E)get_network_status()提供,get_network_status()直接返回g_stEMSInfo.bIsLogin,因此颜色语义是"已登录云端=白,未登录=蓝",与 SOC 电量无关。 - 函数名
get_soc_color_to_rgb容易让人以为与 SOC 有关,实际是"联网状态→颜色"。
4.3 颜色值的后续处理
本文件返回的 0xRRGGBB 会被下游改变字节序:
hmi/led/app_led.c:60-66的apply_brightness()做逐通道亮度缩放,保持0xRRGGBB排列;hmi/led/led_dev.c:124-128把0xRRGGBB转成 WS2812 要求的GRB:grb = (g<<16)|(r<<8)|b;ws2812_set_color_hex()再把 GRB 的 24 个 bit 逐位编码成一串 CCR 比较值写入 DMA 缓冲。
因此本文件的颜色是"逻辑颜色",最终灯珠上看到的是 GRB 字节序。
4.4 与定时/调度的关系
无。本文件不含任何 OSTime* 调用,也不访问中断、信号量、邮箱。它的执行时机完全取决于 led_display_task() 是否被任务调用(当前没有被调用,见 hmi/led/app_led.c.md 第 7 节)。
5. 对外接口
本文件导出
| 名称 | 类型 | 使用方 |
|---|---|---|
get_sys_color_status | 全局函数(声明于 hmi/led/app_led_cfg.h:79) | hmi/led/app_led.c:157 |
get_soc_color_to_rgb | 全局函数(声明于 hmi/led/app_led_cfg.h:80) | hmi/led/app_led.c:156 |
本文件不导出任何全局变量。
本文件调用的外部函数/变量
| 名称 | 来源 |
|---|---|
SYS_COLOR_* 宏 | hmi/led/app_led_cfg.h:26-29 |
STATUS_LED_COLOR_E、SOC_LED_COLOR_E | hmi/led/app_led_cfg.h:48-62 |
u32 | includes.h(经 app_led_cfg.h:18) |
本文件不调用任何函数(两个函数体都只有 switch 与赋值),也不读写任何全局变量,是灯带模块中耦合度最低的文件。
6. 依赖关系
依赖(本文件 include):app_led_cfg.h(14)、led_dev.h(15)、ems.h(16)。
led_dev.h与ems.h在本文件正文中没有任何符号被使用(app_led_cfg.h已经包含了led_dev.h),属多余 include。
被依赖:
hmi/led/app_led.c:156-157(唯一调用方)- 通过
hmi/led/app_led_cfg.h:79-80的声明供其他模块使用;实际无其他调用点。
7. 备注与风险点
- 返回值 0 与"未识别状态"重载:两个函数的
default都返回 0(全灭),而0x000000本身也是合法的"系统未运行"颜色,因此枚举越界/未定义值与合法熄灭态不可区分,现场无法通过灯带判断是逻辑错误还是正常熄灭。 - 宏与字面量混用:
app_led_cfg.h定义了SOC_COLOR_WHITE(0xFFFFFF)、SOC_COLOR_BLUE(0x0000FF),但本文件写的是字面量(hmi/led/app_led_cfg.c:87、90),宏定义成为死代码;将来若调整颜色宏,短灯带颜色不会跟着改变。 - 命名与语义不符:
get_soc_color_to_rgb()实际是"联网状态→颜色"映射(见 4.2),维持现状时容易误导后续修改。 color_value未初始化:u32 color_value;(hmi/led/app_led_cfg.c:49、81)声明后未初始化,依赖switch全分支覆盖。当前逻辑正确,但若增加case时漏掉赋值会出现未定义值(Keil 无-Wmaybe-uninitialized级别的默认告警)。- 风格不一致:
get_soc_color_to_rgb函数签名的参数括号前多了空格(SOC_LED_COLOR_E color,hmi/led/app_led_cfg.c:79),且return color_value;的缩进与其他函数不同(hmi/led/app_led_cfg.c:96)。 - 文件末尾(
hmi/led/app_led_cfg.c:98-105)有 8 行空行,属编辑遗留。 - 两个函数都未做"入参越界钳位",但因
default分支存在,越界不会造成内存错误。