# led_module **Repository Path**: posty_banana/led_module ## Basic Information - **Project Name**: led_module - **Description**: led_module子仓库 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 3 - **Forks**: 0 - **Created**: 2026-08-05 - **Last Updated**: 2026-09-13 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Post LED HAL 模块说明 对底层 LED 做统一封装:点亮/熄灭/翻转、亮度调节、同步/异步闪烁。上层通过 `Post_Hal_Led*` API 操作适配器;平台侧实现对应后端的 `Ops`(GPIO / PWM / 灯控芯片),再完成总线上下文与适配器构造。 ## 1. 目录结构 | 路径 | 说明 | |------|------| | `inc/post_led.h` | 对外 LED API(adapter / 亮度 / 闪烁) | | `inc/post_led_gpio.h` | GPIO 移植接口(Ops / 总线上下文 / CreateAdapter) | | `inc/post_led_pwm.h` | PWM 调光移植接口 | | `inc/post_led_chip.h` | 灯控芯片通道移植接口 | | `src/post_led.c` | 通用适配器逻辑(参数检查、API 分发) | | `src/post_led_gpio.c` / `post_led_pwm.c` / `post_led_chip.c` | 各后端算法实现 | | `lib/post_common_type.h` | 公共类型、`POST_ERR`、内存宏等(可用 CMake 关掉,改用父工程) | | `lib/post_common_log.h` / `lib/post_common_log.c` | 最小日志(可用 CMake 关掉,改用父工程) | | `CMakeLists.txt` | CMake 工程入口 | | `Makefile` | 薄封装:`make` / `make rebuild` / `make test` / `make run` | | `test/mock/` | 板级 Ops 模拟(`.h` / `.cpp` 同目录) | | `test/tool/` | 夹具、建适配器工具、gtest 入口 | | `test/core/` | 单元测试用例(`TEST_F`) | 独立使用时带走:`inc/` + `src/` + `lib/`。作为子工程且父工程已有 type/log 时,可只带走 `inc/` + `src/`。 ## 2. 使用约定 ### 2.1 返回值与错误码 - 返回类型为 `POST_ERR`:`POST_SUCCESS` / `POST_FAILURE` - 详细错误见 `Post_Hal_LedGetLastError()`(`Post_Hal_LedErrorCode`) ### 2.2 适配器与状态 - 业务只操作 `Post_Hal_LedAdapter`,不要直接改后端 `BusContext` 内部闪烁状态 - 异步闪烁期间 `m_isBusy == TRUE`,手动改亮度 / `On` / `Off` / `Toggle` 会返回 `BUSY` - 异步闪烁需在主循环/任务中周期调用 `Post_Hal_LedLoop()` ### 2.3 闪烁参数 - `cycleTimeMs` 为单次「亮 + 灭」总周期,须满足 `0 < cycleTimeMs < POST_LED_MAX_CYCLE_TIME_MS` - 阻塞闪烁 `times` 必须 `> 0` - 异步闪烁可用 `POST_LED_BLINK_FOREVER`(0)表示持续闪烁 - 亮灭比例:`POST_HAL_LED_PROPORTION_1_3` / `1_2` / `1_1`,或 `CUSTOM` + `onParts` / `offParts` ### 2.4 亮度语义 - GPIO:`m_maxBrightness = 1` - PWM / CHIP:由 config 的 `m_maxBrightness` 决定 - PWM 亮度映射:`duty = period * brightness / maxBrightness`(`active_low` 时反相) ## 3. 移植步骤 ### 3.1 GPIO 控灯 1. 实现 `Post_Hal_LedGpioOps`(至少 `m_setValue`;阻塞闪烁再实现 `m_delayMs`;异步再实现 `m_getTimeMs`) 2. `Post_Hal_LedGpioInitBusContext(...)` 绑定 instance、ops、config(`m_activeLow`) 3. `Post_Hal_LedGpioCreateAdapter(...)` 得到 `Post_Hal_LedAdapter` 4. `Post_Hal_LedInit` → 业务控制 → `Post_Hal_LedLoop`(异步时)→ `Post_Hal_LedUninit` ### 3.2 PWM 调光 1. 实现 `Post_Hal_LedPwmOps`(至少 `m_applyDuty`) 2. `Post_Hal_LedPwmInitBusContext(...)` 填入 `m_period` / `m_maxBrightness` / `m_activeLow` 3. `Post_Hal_LedPwmCreateAdapter(...)` → `Post_Hal_LedInit` → `Post_Hal_LedSetBrightness` 等 ### 3.3 灯控芯片 1. 实现 `Post_Hal_LedChipOps`(至少 `m_writeChannel`;寄存器编码由板级完成) 2. `Post_Hal_LedChipInitBusContext(...)` 填入 `m_channel` / `m_maxBrightness` 3. `Post_Hal_LedChipCreateAdapter(...)` → 后续同公共 API ## 4. 使用示例 ### 4.1 GPIO:点亮 / 熄灭 / 异步闪烁 ```c #include "post_led.h" #include "post_led_gpio.h" static Post_Hal_LedAdapter g_ledAdapter; static Post_Hal_LedGpioBusContext g_ledBus; static POST_ERR LedGpio_SetValue(void *instance, POST_U8 value) { (void)instance; /* 写 GPIO 端口电平:1=高,0=低 */ return POST_SUCCESS; } static POST_ERR LedGpio_GetTimeMs(void *instance, POST_U32 *timeMs) { (void)instance; /* *timeMs = 当前毫秒时基(须单调递增) */ return POST_SUCCESS; } static POST_ERR LedGpio_DelayMs(void *instance, POST_U32 delayMs) { (void)instance; (void)delayMs; /* 阻塞延时,供 BlinkBlocking 使用 */ return POST_SUCCESS; } static const Post_Hal_LedGpioOps g_ledGpioOps = { .m_init = NULL, .m_uninit = NULL, .m_setValue = LedGpio_SetValue, .m_getTimeMs = LedGpio_GetTimeMs, .m_delayMs = LedGpio_DelayMs, }; POST_ERR Device_LedInit(void) { Post_Hal_LedGpioConfig config = { .m_activeLow = POST_TRUE, /* 低电平点亮 */ }; if (Post_Hal_LedGpioInitBusContext(&g_ledBus, NULL, &g_ledGpioOps, &config) != POST_SUCCESS) { return POST_FAILURE; } if (Post_Hal_LedGpioCreateAdapter(&g_ledAdapter, "status", &g_ledBus) != POST_SUCCESS) { return POST_FAILURE; } return Post_Hal_LedInit(&g_ledAdapter); } void Device_LedTask(void) { /* 点亮 / 熄灭 */ (void)Post_Hal_LedOn(&g_ledAdapter); (void)Post_Hal_LedOff(&g_ledAdapter); /* 阻塞闪烁:周期 200ms,闪 3 次,亮:灭 = 1:1 */ (void)Post_Hal_LedBlinkBlocking(&g_ledAdapter, 200u, 3u, POST_HAL_LED_PROPORTION_1_1, 0u, 0u); /* 异步持续闪烁:需在主循环里调 Loop */ (void)Post_Hal_LedBlinkAsync(&g_ledAdapter, 200u, POST_LED_BLINK_FOREVER, POST_HAL_LED_PROPORTION_1_3, 0u, 0u); } void Device_LedLoop(void) { (void)Post_Hal_LedLoop(&g_ledAdapter); } POST_ERR Device_LedUninit(void) { return Post_Hal_LedUninit(&g_ledAdapter); } ``` ### 4.2 PWM:设置亮度 ```c #include "post_led.h" #include "post_led_pwm.h" static Post_Hal_LedAdapter g_pwmLed; static Post_Hal_LedPwmBusContext g_pwmBus; static POST_ERR LedPwm_ApplyDuty(void *instance, POST_U32 period, POST_U32 duty) { (void)instance; /* 下发 PWM:period / duty 同单位 */ (void)period; (void)duty; return POST_SUCCESS; } static const Post_Hal_LedPwmOps g_ledPwmOps = { .m_init = NULL, .m_uninit = NULL, .m_applyDuty = LedPwm_ApplyDuty, .m_getTimeMs = NULL, .m_delayMs = NULL, }; POST_ERR Device_PwmLedInit(void) { Post_Hal_LedPwmConfig config = { .m_period = 1000u, .m_maxBrightness = 100u, .m_activeLow = POST_FALSE, }; if (Post_Hal_LedPwmInitBusContext(&g_pwmBus, NULL, &g_ledPwmOps, &config) != POST_SUCCESS) { return POST_FAILURE; } if (Post_Hal_LedPwmCreateAdapter(&g_pwmLed, "backlight", &g_pwmBus) != POST_SUCCESS) { return POST_FAILURE; } if (Post_Hal_LedInit(&g_pwmLed) != POST_SUCCESS) { return POST_FAILURE; } /* 25% 亮度 => duty = 1000 * 25 / 100 = 250 */ return Post_Hal_LedSetBrightness(&g_pwmLed, 25u); } ``` ### 4.3 灯控芯片:写通道亮度 ```c #include "post_led.h" #include "post_led_chip.h" static Post_Hal_LedAdapter g_chipLed; static Post_Hal_LedChipBusContext g_chipBus; static POST_ERR LedChip_WriteChannel(void *instance, POST_U8 channel, POST_U32 brightness) { (void)instance; /* 经 I2C/SPI 把 brightness 写到芯片 channel 对应寄存器 */ (void)channel; (void)brightness; return POST_SUCCESS; } static const Post_Hal_LedChipOps g_ledChipOps = { .m_init = NULL, .m_uninit = NULL, .m_writeChannel = LedChip_WriteChannel, .m_getTimeMs = NULL, .m_delayMs = NULL, }; POST_ERR Device_ChipLedInit(void) { Post_Hal_LedChipConfig config = { .m_channel = 0u, .m_maxBrightness = 255u, }; if (Post_Hal_LedChipInitBusContext(&g_chipBus, NULL, &g_ledChipOps, &config) != POST_SUCCESS) { return POST_FAILURE; } if (Post_Hal_LedChipCreateAdapter(&g_chipLed, "rgb:red", &g_chipBus) != POST_SUCCESS) { return POST_FAILURE; } if (Post_Hal_LedInit(&g_chipLed) != POST_SUCCESS) { return POST_FAILURE; } return Post_Hal_LedSetBrightness(&g_chipLed, 128u); } ``` ## 5. 常用 API ### 5.1 生命周期 | API | 说明 | |-----|------| | `Post_Hal_LedInit` / `Uninit` | 初始化 / 反初始化 | | `Post_Hal_LedLoop` | 异步闪烁节拍(主循环调用) | ### 5.2 开关与亮度 | API | 说明 | |-----|------| | `Post_Hal_LedOn` / `Off` / `Toggle` | 点亮 / 熄灭 / 翻转 | | `Post_Hal_LedSetBrightness` / `GetBrightness` | 设置 / 读取亮度 | ### 5.3 闪烁与辅助 | API | 说明 | |-----|------| | `Post_Hal_LedBlinkBlocking` | 阻塞闪烁(需 `delayMs`) | | `Post_Hal_LedBlinkAsync` | 启动异步闪烁(需 `getTimeMs` + `Loop`) | | `Post_Hal_LedCalcDelays` | 按比例拆分 `cycleTimeMs` → 亮/灭时长 | | `Post_Hal_LedGetLastError` | 读取最近一次错误码 | ## 6. 工程集成 ### 6.1 CMake 接入 ```cmake add_subdirectory(led_module) target_link_libraries(your_app PRIVATE post_led) ``` ### 6.2 CMake 常用选项 - `POST_LED_BUILD_TESTS`:是否编单测(顶层工程默认开) - `POST_LED_USE_BUNDLED_TYPE` / `POST_LED_USE_BUNDLED_LOG`:是否用本模块自带 `lib/` ### 6.3 本地编译与验证 ```bash cd led_module make rebuild # 仅配置并编译 make test # rebuild + 跑全部用例 make run # 跑全部 gtest make run HWM_UNIT_LED_GPIO_OnOffActiveLow # 跑单个用例 make clean # 清理 build/ ```