Skip to content

feat(firmware/rmcs_board): Add WS2812 status LED feedback#50

Merged
qzhhhi merged 2 commits intomainfrom
dev/ws2812-success
May 3, 2026
Merged

feat(firmware/rmcs_board): Add WS2812 status LED feedback#50
qzhhhi merged 2 commits intomainfrom
dev/ws2812-success

Conversation

@qzhhhi
Copy link
Copy Markdown
Member

@qzhhhi qzhhhi commented May 2, 2026

  • Expose USB, UART, and CAN backpressure plus fatal asserts through a shared status light path so board health is visible without a debugger.
  • Keep the pro variant initialized but non-driving so the same firmware path is ready for the next hardware revision.

WS2812 状态指示灯反馈功能(更新)

该拉取请求为固件添加了共享的 WS2812 状态指示灯路径,用于在无需调试器的情况下通过可视反馈暴露 USB/UART/CAN 的背压状态及致命断言信息;同时保留 pro 硬件变体的初始化但不驱动线路,以便未来硬件修订复用相同固件路径。

核心功能

  • WS2812 驱动(firmware/rmcs_board/app/src/led/ws2812.hpp)
    • 基于 PWM + DMA 实现的 WS2812 控制器,支持 24 位 GRB 输出与亮度缩放。
    • set_value(red, green, blue) 将颜色转换为 GRB 比较表并通过 DMA 推送,返回是否接受更新。
  • LED 状态管理(firmware/rmcs_board/app/src/led/led.hpp)
    • 新增 Led 类,使用两个原子“缓冲满重置”计数器追踪上行/下行背压(计数器置为 5000 周期)。
    • update(tick) 原子递减计数器并根据上/下行状态、相位等选择 RGB 输出;正常运行时显示绿色亮度循环。
    • 提供全局延迟初始化实例 led(utility::Lazy 用于延迟初始化)。
  • 周期时钟与中断(firmware/rmcs_board/app/src/timer/tick.hpp/.cpp)
    • 新增 Tick 类,配置约 1kHz 的 GPTMR 定时中断;irq_handler 增加 tick 计数并驱动 LED 更新。
    • 新增板级中断转发函数 tick_clock_irq_handler。

集成点(缓冲区/传输失败 -> 指示灯)

  • USB 上行缓冲满(firmware/rmcs_board/app/src/usb/interrupt_safe_buffer.hpp):调用 led::led->uplink_buffer_full()。
  • UART 下行缓冲满(firmware/rmcs_board/app/src/uart/uart.hpp):在 enqueue 失败时调用 led::led->downlink_buffer_full()。
  • CAN 下行(firmware/rmcs_board/app/src/can/can.hpp):检查 mcan_transmit_via_txfifo_nonblocking 返回值,失败时调用 led::led->downlink_buffer_full()。

断言视觉反馈

  • assert_func(firmware/rmcs_board/app/src/utility/assert.cpp)
    • 在记录断言位置前禁用全局中断,并在条件允许时触发 WS2812 红色序列(若可用)作为致命断言的视觉提示,然后调用 __builtin_trap()。

Lazy 访问语义变更(重要,破坏性)

  • utility::Lazy 的访问契约已调整以避免断言路径中的递归断言:
    • 非断言的探测路径(在提交信息与部分文件中以 try_get 或非断言 get 实现/文档说明出现):在未初始化时返回 nullptr,从而允许在断言/故障处理路径安全地探测可用性而不触发断言递归。
    • operator->() 与 operator*() 保持严格语义(仍会在未初始化时断言)。
  • 注意:调用方必须在解引用之前检查返回的指针(破坏性变更:探测前请检查指针是否为 nullptr)。

板级与 GPIO 改动

  • analog_gpio_pin.hpp:新增 constexpr 访问器 pwm_base()/pwm_ioc_function()/pwm_output_index(),并将 pwm_instance() 移至 public。
  • Lite/Pro 板级(firmware/rmcs_board/boards/*/app)
    • 新增 kWs2812Pin 描述、init_ws2812_pin()(Pro 版将引脚设为输入以避免驱动未焊接器件)、init_tick_clock() 以及 GPTMR1 的 ISR 转发(tick_isr/tick_clock_irq_handler)。
  • 应用初始化(firmware/rmcs_board/app/src/app.cpp)
    • 在应用构造期间初始化 LED 子系统与周期时钟(在引导/传感器初始化之后)。

其它

  • 新增或修改的导出实体:Led、Ws2812、Tick 类及对应的延迟初始化全局实例;若干板级初始化函数与宏。
  • 若干文件的实现细节与注释扩充,部分文件引入了必要的头文件以支持中断控制与 WS2812 操作。

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 2, 2026

Note

Reviews paused

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

该 PR 在 rmcs_board 上新增 WS2812 驱动(PWM+DMA)与 LED 控制逻辑、引入 1 kHz 的周期滴答定时器并将其与 LED 更新关联,更新若干通信模块在缓冲区溢出时触发 LED 指示,添加板级 WS2812 / GPTMR 初始化和中断接入;同时为 utility::Lazy 添加文档并新增非断言访问器 try_get()

Changes

LED/Timer 集成(主 DAG)

Layer / File(s) Summary
硬件驱动与数据形态
firmware/rmcs_board/app/src/led/ws2812.hpp
新增 Ws2812:基于 PWM1+DMA 的 WS2812 控制类,包含比特时序常量、DMA 比较表、set_value()init_dma() 与全局 lazy 实例 ws2812
控制逻辑
firmware/rmcs_board/app/src/led/led.hpp
新增 Led 类:两路原子“缓冲满”计数器、reset()uplink_buffer_full()/downlink_buffer_full()update(uint32_t),并导出 lazy 实例 led
定时器实现
firmware/rmcs_board/app/src/timer/tick.hpp, .../tick.cpp
新增 Tick:配置 GPTMR 生成 ~1kHz 重载中断、irq_handler() 递增计数并调用 led->update();添加板级转发函数 tick_clock_irq_handler()
板级中断与时钟初始化
firmware/rmcs_board/boards/*/app/board_app.{hpp,cpp}
为 lite/pro 板添加 kWs2812Pin 描述、init_ws2812_pin()init_tick_clock()BOARD_TICK_CLOCK 宏及 IRQn_GPTMR1 ISR 转发(tick_isr -> tick_clock_irq_handler)。
应用接入
firmware/rmcs_board/app/src/app.cpp
在应用初始化中调用 led::led.init()(BootMailbox 后)和 timer::tick.init()(BMI088 初始化后)。
通信/缓冲溢出触发点
firmware/rmcs_board/app/src/can/can.hpp, .../uart/uart.hpp, .../usb/interrupt_safe_buffer.hpp
CAN、UART、USB 的下/上行缓冲溢出路径现在在失败时调用相应的 led 通知接口(downlink_buffer_full() / uplink_buffer_full())。
断言处理增强
firmware/rmcs_board/app/src/utility/assert.cpp
assert_func 在记录位置前禁用中断,并在可用时通过 WS2812 做闪烁和置红后触发陷阱。

工具类改动(独立 DAG)

Layer / File(s) Summary
文档与 API
firmware/c_board/app/src/utility/lazy.hpp, firmware/rmcs_board/app/src/utility/lazy.hpp
utility::Lazy<T> 添加 Doxygen 风格文档;新增 constexpr T* try_get(),在未初始化时返回 nullptr,其它访问器保持原实现与断言语义(仅文档化警告)。
引用点(适配)
各新增 lazy 实例引用文件(见 LED/Timer 层)
新增的 ws2812ledtick 等都是基于 utility::Lazy 的全局延迟单例并被各层初始化/调用。

Sequence Diagram

sequenceDiagram
    participant App as App
    participant Timer as Tick Timer
    participant LED as Led Controller
    participant WS2812 as WS2812 Driver
    participant CANUARTUSB as CAN/UART/USB Buffers
    participant IRQ as IRQ Handler

    App->>Timer: timer::tick.init()
    App->>LED: led::led.init()
    LED->>WS2812: ws2812.init()
    WS2812->>WS2812: 配置 PWM + DMA

    loop 每 ~1ms
        IRQ->>Timer: GPTMR1 重载中断
        Timer->>Timer: tick_counter++
        Timer->>LED: update(tick_counter)
        LED->>WS2812: set_value(...) (根据计数器和相位)
    end

    CANUARTUSB->>LED: 缓冲区满触发
    LED->>LED: 设置相应计数器 = 5000
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Poem

🐰
嘀嗒千次小脚步,灯光随缓冲舞,
PWM 与 DMA 轻声弹,原子计数守护路。
绿与红在断言处,固件心跳更踏实。

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.64% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR标题准确反映了此PR的主要变更:添加WS2812状态LED反馈功能。标题清晰指出了新增功能的核心内容,与所有文件更改(LED驱动、定时器、缓冲区检测等)的目标保持一致。
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev/ws2812-success

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@firmware/rmcs_board/app/src/led/ws2812.hpp`:
- Around line 113-116: The DMA transfer size is set incorrectly in set_value():
ctrl.TRANSIZE uses compare_values_.size() (element count) but must be a byte
count to match init_dma() and tx semantics; change the assignment in set_value()
so ctrl.TRANSIZE is the number of bytes (e.g., sizeof(compare_values_)) rather
than the element count, consistent with how TRANSIZE is used in init_dma() and
tx_buffer.hpp.

In `@firmware/rmcs_board/app/src/utility/lazy.hpp`:
- Around line 54-63: Lazy::get() now returns nullptr instead of asserting;
update all callers to handle that case: search for uses of Lazy::get() (e.g.,
variables can1, can2 and the call sequence where can = can1.get(); can =
can2.get(); followed by can->handle_uplink()) and add a null-check before any
dereference (or replace with a checked accessor) and handle the uninitialized
path consistently (log/error/early-return or assert_if_critical). Ensure every
call site that previously assumed non-nullation either guards the pointer or
calls a new checked accessor on Lazy.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 46612772-632a-404c-a994-eadbd03ef43b

📥 Commits

Reviewing files that changed from the base of the PR and between d00cae1 and 3df186b.

📒 Files selected for processing (16)
  • firmware/c_board/app/src/utility/lazy.hpp
  • firmware/rmcs_board/app/src/app.cpp
  • firmware/rmcs_board/app/src/can/can.hpp
  • firmware/rmcs_board/app/src/gpio/analog_gpio_pin.hpp
  • firmware/rmcs_board/app/src/led/led.hpp
  • firmware/rmcs_board/app/src/led/ws2812.hpp
  • firmware/rmcs_board/app/src/timer/tick.cpp
  • firmware/rmcs_board/app/src/timer/tick.hpp
  • firmware/rmcs_board/app/src/uart/uart.hpp
  • firmware/rmcs_board/app/src/usb/interrupt_safe_buffer.hpp
  • firmware/rmcs_board/app/src/utility/assert.cpp
  • firmware/rmcs_board/app/src/utility/lazy.hpp
  • firmware/rmcs_board/boards/lite/app/board_app.cpp
  • firmware/rmcs_board/boards/lite/app/board_app.hpp
  • firmware/rmcs_board/boards/pro/app/board_app.cpp
  • firmware/rmcs_board/boards/pro/app/board_app.hpp

Comment thread firmware/rmcs_board/app/src/led/ws2812.hpp
Comment thread firmware/rmcs_board/app/src/utility/lazy.hpp
@qzhhhi qzhhhi force-pushed the dev/ws2812-success branch from 3df186b to ae80158 Compare May 3, 2026 09:47
@qzhhhi
Copy link
Copy Markdown
Member Author

qzhhhi commented May 3, 2026

@coderabbitai pause

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 3, 2026

✅ Actions performed

Reviews paused.

qzhhhi added 2 commits May 3, 2026 09:59
- Expose USB, UART, and CAN backpressure plus fatal asserts through a shared status light path so board health is visible without a debugger.
- Keep the pro variant initialized but non-driving so the same firmware path is ready for the next hardware revision.
- Introduce an explicit nullable probe accessor for firmware Lazy wrappers and keep get(), operator->(), and operator*() as strict accessors that require prior initialization.
- Use try_get() in the rmcs_board assert WS2812 path so assert handling can probe LED availability without re-entering Lazy assertions or triggering clang-tidy recursion diagnostics.
- Add Doxygen comments to document the split between nullable probing and strict access across both firmware variants.
@qzhhhi qzhhhi force-pushed the dev/ws2812-success branch from ae80158 to 36b0802 Compare May 3, 2026 10:03
@qzhhhi qzhhhi merged commit 36b0802 into main May 3, 2026
5 checks passed
@github-project-automation github-project-automation Bot moved this from Todo to Done in RMCS Slave SDK May 3, 2026
@qzhhhi qzhhhi deleted the dev/ws2812-success branch May 3, 2026 10:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant