Skip to content

feat(i2c): Add cross-board I2C transport and harden transfer recovery - #45

Closed
gqsdjhh wants to merge 18 commits into
mainfrom
dev/i2c
Closed

feat(i2c): Add cross-board I2C transport and harden transfer recovery#45
gqsdjhh wants to merge 18 commits into
mainfrom
dev/i2c

Conversation

@gqsdjhh

@gqsdjhhgqsdjhh commented Apr 16, 2026

Copy link
Copy Markdown

功能与架构概述

c_boardrmcs_board 引入统一的 I2C0 协议通路,并补齐 host agent、固件驱动和协议层支持。rmcs_board 使用基于 HPM SDK 的非阻塞 DMA I2C 实现,c_board 将逻辑 I2C0 映射到 STM32 I2C2,同时围绕 USB
背压、超时恢复、错误上报和非法请求处理做了系统性加固。

主要变更要点

  • 协议层新增并完善 I2C0 字段的序列化与反序列化,区分 write、read request、read result 和 error,并拒绝空 I2C 传输。
  • 主机端为 CBoardRmcsBoardProRmcsBoardLite 增加 i2c0_write() / i2c0_read() 接口,以及对应的接收与错误回调入口。
  • rmcs_board 固件新增 I2C0 驱动、DMA completion callback 和 main-loop update 流程,启用 HPM I2C 组件,并在 Pro/Lite 板级层补充 I2C 引脚、时钟和总线恢复初始化。
  • c_board 固件新增逻辑 I2C0 通道,使用 STM32 I2C2 + DMA 实现读写,并补充 HAL 回调、中断路由、CubeMX 配置和超时恢复。
  • I2C 上行结果与错误在 USB 背压下会被保留并延后发送,避免 read resulterror 在缓冲区拥塞时静默丢失。
  • 错误处理路径保留寄存器地址、读写方向和数据长度上下文,并在传输未完成、超时或非法请求时统一上报错误。
  • 调整 c_board 的 I2C IRQ 优先级以减少与 USB 的冲突,并明确逻辑 I2C0 与物理 I2C2 的映射关系。
  • 更新 rmcs_board 使用的 HPM SDK 以恢复 hpm5300evk 相关板定义。

影响与兼容性

  • CBoardRmcsBoardProRmcsBoardLite 新增 I2C0 主机接口与回调入口。
  • 协议层不再接受空 I2C write/read request;此类请求现在会被拒绝或上报为错误。
  • c_board 的逻辑 I2C0 实际由 STM32 I2C2 承载,但 host/firmware 对外名称保持不变。

I2C0 跨板传输与传输恢复增强(含若干配套改动)

概述

本 PR 在主机、协议及两类板级固件(c_board / rmcs_board)间引入统一的逻辑 I2C0 传输通道,并强化传输的错误/超时恢复与上行缓冲策略。实现涵盖协议、主机 API、c_board(STM32 + DMA)与 rmcs_board(HPM + DMA)端的端到端支持,以及若干与构建、USB、中断相关的配套调整。修正了主机端 I2C 回调分发以避免覆盖/隐藏错误回调。

协议与数据结构

  • 新增协议常量与限制:core/include/librmcs/protocol/i2c.hpp(kI2cDataLengthBits = 9,kI2cMaxDataLength)。
  • 新增位域头部 I2cHeader(Payload 类型:kWrite / kReadRequest / kReadResult / kError;HasRegister、ErrorFlag、SlaveAddress、DataLength),并用 static_assert 验证位宽与最大长度一致性(core/src/protocol/protocol.hpp)。
  • 扩展数据定义:添加 DataId::kI2c0、I2cDataView、I2cReadConfigView、I2cErrorView;在 DataCallback 中新增 i2c_receive_callback 与 i2c_error_callback,并提供基于从机地址的辅助构造。

序列化/反序列化与主机协议处理

  • Serializer:新增 write_i2c_write / write_i2c_read_config / write_i2c_read_result / write_i2c_error(含便捷 overload);严格校验 field id、7-bit 从地址与长度上限,拒绝空写/空读请求。
  • Deserializer:新增 process_i2c_field 协程,按 I2cHeader 解析(含可选寄存器字节与 payload),在字节不足或非法时进入丢弃路径;按类型分发到对应反序列化回调。
  • host 层:增加 I2C 上行反序列化回调(读结果转发到 i2c_receive_callback,错误转发到 i2c_error_callback 并记录上下文);PacketBuilder/Handler 增加 write_i2c 系列 API,并对序列化结果做更严格的错误区分与处理。

主机 API 与代理类改动

  • 为 CBoard、RmcsBoardPro、RmcsBoardLite 的 PacketBuilder 添加 i2c0_write() 与 i2c0_read()(通过 mixin 实现),并暴露受保护的 i2c0_receive_callback / i2c0_error_callback 钩子以供上层实现。
  • 新增 agent 侧的 SingleI2c0DataCallback 与 I2c0PacketBuilderMixin,集中处理只针对 DataId::kI2c0 的回调路由与 PacketBuilder 便捷方法。

c_board 固件(STM32)实现要点

  • 新增逻辑 I2C 驱动(firmware/c_board/app/src/i2c/i2c.hpp/.cpp):基于 DMA 的异步 I2C 管理器,包含请求环形队列、块池、原子状态机、超时检测/恢复、上行缓冲与有界排队;写入分块到 DMA 缓冲,读取通过 DMA 填充后复制并上行或排队。
  • HAL 回调适配(firmware/c_board/app/src/i2c/i2c.cpp):将 HAL 的完成/错误回调映射到逻辑 I2C 实例(tx_complete/rx_complete/error_callback)。
  • 硬件与 CubeMX 支持:新增 i2c.h、i2c.c(配置 I2C2、DMA Stream2 RX、Stream7 TX、MSP init/deinit)、中断处理(I2C2_EV/ER、DMA1_Stream2/7)、GPIO PF0/PF1;在 App 初始化中调用 MX_I2C2_Init(),并在主循环中周期性调用 i2c0->update()。
  • 调整 NVIC/IRQ 配置以减轻与 USB 的冲突(IRQ 优先级与中断表更新)。
  • USB 传输缓冲解锁行为调整:try_unlock_and_clear() → try_unlock()(解锁不再自动清空队列,避免丢弃待发送批次);USB 下行反序列化错误由断言改为安全丢弃以提高稳健性。

rmcs_board 固件(HPM)实现要点

  • 新增 HPM 平台 I2C 驱动(firmware/rmcs_board/app/src/i2c/i2c.hpp/.cpp):使用非阻塞 HPM I2C DMA 接口、DMA 完成回调、缓存对齐与缓存管理;通过 DMA 管理器回调转发完成事件。
  • 恢复/超时策略:基于周期计数的超时检测;超时或异常时中止 DMA、清除 I2C/FIFO 状态、标记未初始化并发布错误上行;对特定 HPM 状态码条件性重新初始化。
  • 上行队列策略:支持即时序列化或有界排队(pending/blocked/retained),队列满或序列化失败时触发上行缓冲满指示(LED)。
  • 板级支持:Pro/Lite 提供 board_init_i2c(I2C_Type*)(引脚复用、时钟使能、总线清理/恢复逻辑)。

错误与流控细节(关键行为)

  • 在错误路径保留并上报上下文信息:从机地址、是否为读、可选寄存器地址与数据长度(便于上层定位失败原因)。
  • 对不完整/超时/非法传输产生错误上行(i2c_error),并在 USB 回压时可保留/延迟上行结果与错误以避免静默丢失(通过有界队列与重试/回退策略)。
  • 协议层拒绝空的写/读请求(作为非法输入处理并返回错误)。

构建与应用层变更

  • 在 c_board 与 rmcs_board 的 app.cpp 中初始化 i2c0 并在主循环中周期性调用 update。
  • rmcs_board CMakeLists.txt 通过 set(CONFIG_HPM_I2C 1) 启用 HPM I2C。
  • c_board 的 CubeMX/CMake 将 i2c.c 与 HAL I2C 源纳入构建,stm32f4xx_hal_conf.h 已启用 HAL_I2C_MODULE。
  • 更新 HPM SDK 以恢复 hpm5300evk 板定义。

其他配套与非功能性变更

  • .devcontainer/devcontainer.json:设置 userEnvProbe:"none",并将 postCreateCommand 的用户工具安装改为受 RMCS_DEVCONTAINER_INSTALL_USER_TOOLS 环境变量控制。
  • .gitignore:新增 firmware/rmcs_board/build-lite/。
  • CubeMX .ioc、DMA/中断初始化、stm32f4xx_it.h/c 等文件更新以支持 I2C2/DMA 路径。
  • USB 层与 InterruptSafeBuffer 接口行为调整(try_unlock 替代 try_unlock_and_clear),并将下行反序列化错误从断言改为丢弃以提高稳健性。

兼容性与注意事项

  • 新增主机 API 与回调:上游代码需适配 i2c0_write / i2c0_read,并可实现 i2c0_receive_callback / i2c0_error_callback。
  • 协议层拒绝空 I2C 写/读请求并强制长度上限;序列化/反序列化在非法输入时返回错误并按安全策略处理/丢弃。
  • 在 c_board 上逻辑 I2C0 物理映射为 STM32 I2C2(PF0/PF1),注意引脚复用与资源限制。
  • 评论/审阅状态:qzhhhi 请求了 @coderabbitai 审阅;自动机器人回复记录存在,但未产生技术讨论或变更请求。

@coderabbitai

coderabbitaiBot commented Apr 16, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a573e4b9-459e-4708-afd8-932cde6eb9a8

📥 Commits

Reviewing files that changed from the base of the PR and between 9adf3b5 and 18b590f.

📒 Files selected for processing (4)
  • host/include/librmcs/agent/c_board.hpp
  • host/include/librmcs/agent/detail/i2c0_common.hpp
  • host/include/librmcs/agent/rmcs_board_lite.hpp
  • host/include/librmcs/agent/rmcs_board_pro.hpp
🚧 Files skipped from review as they are similar to previous changes (2)
  • host/include/librmcs/agent/rmcs_board_lite.hpp
  • host/include/librmcs/agent/c_board.hpp

Walkthrough

新增 I2C 支持:协议常量与位域、数据视图与回调、序列化/反序列化扩展、主机封装与接收分派、STM32/HPM 固件驱动与板级初始化、USB 下/上行集成及若干工具/配置与 .gitignore 调整。

Changes

Cohort / File(s)Summary
协议数据与位域
core/include/librmcs/data/datas.hpp, core/include/librmcs/protocol/i2c.hpp, core/src/protocol/protocol.hpp
新增 DataId::kI2c0、I2C 视图类型(I2cDataView / I2cReadConfigView / I2cErrorView)、I2C 协议常量与 I2cHeader 位域及静态断言。
序列化 / 反序列化
core/src/protocol/serializer.hpp, core/src/protocol/deserializer.hpp, core/src/protocol/deserializer.cpp
新增 I2C 序列化 API(write_i2c_* / write_i2c_error)、大小/验证辅助函数与 Deserializer::process_i2c_field 协程;增加对应的反序列化回调声明与分发逻辑。
主机端 Handler / Agent 扩展
host/include/librmcs/protocol/handler.hpp, host/src/protocol/handler.cpp, host/include/librmcs/agent/*, host/include/librmcs/agent/detail/i2c0_common.hpp
PacketBuilder/Handler 增加 write_i2c* 接口;新增 i2c0 mixin 与 SingleI2c0DataCallback,CBoard/RmcsBoard(Lite/Pro) 改为使用 mixin/base 以仅处理 kI2c0。
STM32 BSP 与 HAL 集成 (c_board)
firmware/c_board/bsp/cubemx/Core/Inc/i2c.h, .../stm32f4xx_hal_conf.h, Core/Src/i2c.c, Core/Inc/stm32f4xx_it.h, Core/Src/stm32f4xx_it.c, Core/Src/dma.c, cmake/.../CMakeLists.txt, .../rmcs_slave.ioc
启用 HAL I2C 模块并添加 I2C2 HAL/DMA 句柄与 MX_I2C2_Init;配置 GPIO/DMA/MSP/NVIC 中断并更新 CubeMX .ioc 与 CMake 源列表。
STM32 固件驱动与 App 集成 (c_board app)
firmware/c_board/app/src/i2c/i2c.hpp, firmware/c_board/app/src/i2c/i2c.cpp, firmware/c_board/app/src/app.cpp
新增异步 I2C 驱动(请求队列、DMA 缓冲、超时/恢复、上行队列与错误发布),在 App 初始化中启用并在主循环周期性调用 i2c0->update();增加 HAL 回调到驱动的桥接实现。
HPM 平台驱动与板级 (rmcs_board)
firmware/rmcs_board/app/src/i2c/i2c.hpp, firmware/rmcs_board/app/src/i2c/i2c.cpp, firmware/rmcs_board/boards/*/board.c, .../board.h, firmware/rmcs_board/app/src/app.cpp, firmware/rmcs_board/app/CMakeLists.txt
为 HPM 平台添加异步 I2C 驱动与 DMA 完成回调、board_init_i2c 实现、构建开关 CONFIG_HPM_I2C 与主循环更新调用。
USB 缓冲 与 Vendor 层
firmware/*/app/src/usb/interrupt_safe_buffer.hpp, firmware/*/app/src/usb/vendor.hpp
try_unlock_and_clear() 重命名为 try_unlock()(解锁不再隐式 clear);在 USB Vendor 层添加 I2C 下行反序列化回调并将下行格式错误从断言改为丢弃/忽略。
DevContainer / .gitignore / 工具安装
.devcontainer/devcontainer.json, .gitignore
DevContainer 新增 userEnvProbe: "none"postCreateCommand 的用户工具安装由 ${RMCS_DEVCONTAINER_INSTALL_USER_TOOLS} 门控;新增 .gitignore 条目 firmware/rmcs_board/build-lite/

Sequence Diagram(s)

sequenceDiagram
rect rgba(180, 220, 255, 0.5)
participant HostUSB as Host (USB)
participant Deser as Deserializer
participant Vendor as USB Vendor
end
rect rgba(200, 255, 200, 0.5)
participant I2cDrv as Firmware I2C Driver
participant HALDMA as HAL / DMA / IRQ
end
rect rgba(255, 240, 200, 0.5)
participant Ser as Serializer
participant HostSer as Host (uplink)
end
HostUSB->>Deser: 下行数据 (含 I2C 字段)
Deser->>Vendor: process_i2c_field -> 调用回调
Vendor->>I2cDrv: handle_downlink_write / handle_downlink_read_config
I2cDrv->>I2cDrv: 入队并启动 DMA(若空闲)
I2cDrv->>HALDMA: 发起 HAL DMA 读/写 请求
HALDMA->>I2cDrv: 中断/回调 (tx/rx 完成 或 错误)
I2cDrv->>I2cDrv: 完成处理并构造上行结果/错误
I2cDrv->>Ser: write_i2c_read_result / write_i2c_error
Ser->>HostSer: 上行数据发送到主机
Loading

Estimated code review effort

🎯 4 (复杂) | ⏱️ ~45 分钟

Possibly related PRs

🐰 我在总线草丛轻跳跃,咔嚓一声发出字节香,
SDA 嗅到序列,SCL 数着节拍不慌张;
DMA 风铃响了又响,回调把消息带回巢,
新通道开道通天路,兔子在电路里笑哈哈。

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 6.72% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe PR title clearly describes the main objective: adding I2C transport support with transfer recovery hardening across boards.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev/i2c

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.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
host/src/protocol/handler.cpp (2)

182-193: ⚠️ Potential issue | 🟠 Major

process_result 缺少返回语句会导致未定义行为

静态分析正确指出:当 result 不是 kSuccesskBadAllockInvalidArgument 时,assert_failed_debug() 在 release 构建中可能不终止,导致函数无返回值退出。

🐛 建议修复
 static bool process_result(core::protocol::Serializer::SerializeResult result) {
using core::protocol::Serializer;
if (result == Serializer::SerializeResult::kSuccess) [[likely]]
return true;
if (result == Serializer::SerializeResult::kBadAlloc) {
logging::get_logger().error("Transmit buffer unavailable (acquire failed)");
return true;
}
if (result == Serializer::SerializeResult::kInvalidArgument)
return false;
core::utility::assert_failed_debug();
+ return false; // Unreachable, but satisfies compiler
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@host/src/protocol/handler.cpp` around lines 182 - 193, The function
process_result can exit without returning a bool if result is not
kSuccess/kBadAlloc/kInvalidArgument; update process_result (in handler.cpp) to
guarantee a return value by adding an explicit return after
core::utility::assert_failed_debug() (e.g. return false) so that for any
unexpected Serializer::SerializeResult enum value the function returns a defined
boolean; ensure references are to core::protocol::Serializer::SerializeResult
and the process_result function name when making the change.

195-207: ⚠️ Potential issue | 🟠 Major

process_result_strict 同样缺少返回语句

process_result 相同的问题,建议添加不可达的返回语句以满足编译器要求。

🐛 建议修复
 static bool process_result_strict(core::protocol::Serializer::SerializeResult result) {
using core::protocol::Serializer;
if (result == Serializer::SerializeResult::kSuccess) [[likely]]
return true;
if (result == Serializer::SerializeResult::kBadAlloc) {
logging::get_logger().error("Transmit buffer unavailable (acquire failed)");
return false;
}
if (result == Serializer::SerializeResult::kInvalidArgument) {
return false;
}
core::utility::assert_failed_debug();
+ return false; // Unreachable, but satisfies compiler
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@host/src/protocol/handler.cpp` around lines 195 - 207, The function
process_result_strict lacks a final return statement for all control paths;
update process_result_strict (which checks
core::protocol::Serializer::SerializeResult) to add an explicit unreachable
return (e.g., return false) after calling core::utility::assert_failed_debug(),
ensuring the function always returns a bool even if the assert is compiled out.
🧹 Nitpick comments (2)
core/src/protocol/protocol.hpp (1)

133-146: DataLength 补一个编译期边界。

这里把长度字段固定成 9 bit,最大只能表示 511;但上层 view 暴露的是 16 bit 长度。现在这个约束只藏在位宽里,后面如果协议 buffer 或允许的 I2C 长度再增长,很容易先在这里变成静默截断。建议把最大可编码长度显式化,并用 static_assert 钉死在协议层。

♻️ 可以考虑的约束方式
+#include "core/src/protocol/constant.hpp"+
struct I2cHeader : utility::Bitfield<3> {
+ static constexpr uint16_t kMaxDataLength = (1u << 9) - 1;+ static_assert(kProtocolBufferSize <= kMaxDataLength);+
enum class PayloadEnum : uint8_t {
kWrite = 0,
kReadRequest = 1,
kReadResult = 2,
kError = 3,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@core/src/protocol/protocol.hpp` around lines 133 - 146, The DataLength
bitfield currently encodes 9 bits implicitly; add an explicit constexpr named
(for example) I2cHeader::kMaxEncodableDataLength = (1u << 9) - 1 next to the
DataLength typedef and add a compile-time guard (static_assert) that
documents/checks the relationship to the upstream view length type (e.g. compare
against std::numeric_limits<uint16_t>::max() or the actual upstream length type)
with a clear message instructing to update the bitfield if the upstream/allowed
I2C length grows; place these next to the I2cHeader struct so DataLength,
kMaxEncodableDataLength, and the static_assert are colocated.
firmware/rmcs_board/app/src/i2c/i2c.hpp (1)

426-447: try_flush_blocked_uplink 中存在不可达代码

第 446-447 行的 return true; 永远不会被执行。循环在队列为空时从内部返回 true(第 432 行),或在 kBadAlloc 时返回 false(第 438 行)。

♻️ 建议移除不可达代码
 bool try_flush_blocked_uplink() {
while (true) {
const PendingUplink* blocked = nullptr;
{
const utility::InterruptLockGuard guard;
if (blocked_uplink_count_ == 0)
return true;
blocked = &blocked_uplinks_[blocked_uplink_tail_];
}
const auto result = try_publish_uplink(*blocked);
if (result == core::protocol::Serializer::SerializeResult::kBadAlloc)
return false;
core::utility::assert_always(
result != core::protocol::Serializer::SerializeResult::kInvalidArgument);
const utility::InterruptLockGuard guard;
blocked_uplink_tail_ = advance_blocked_uplink_index(blocked_uplink_tail_);
blocked_uplink_count_ = static_cast<uint8_t>(blocked_uplink_count_ - 1);
}
- return true;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@firmware/rmcs_board/app/src/i2c/i2c.hpp` around lines 426 - 447, The trailing
"return true;" at the end of try_flush_blocked_uplink is unreachable (the loop
either returns true when blocked_uplink_count_ == 0 or false on kBadAlloc);
remove the final return statement to clean up dead code in function
try_flush_blocked_uplink and ensure no other control paths are added that would
require a terminal return.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@core/include/librmcs/data/datas.hpp`:
- Around line 130-134: The default i2c_error_callback(DataId, const
I2cErrorView&) currently downgrades the rich I2cErrorView to just slave_address
by forwarding to i2c_error_callback(DataId, uint8_t), which silently discards
data_length, register info and direction; remove that forwarding implementation
and instead declare i2c_error_callback(DataId, const I2cErrorView&) as pure
virtual (and likewise ensure i2c_error_callback(DataId, uint8_t) is either
removed or also marked pure virtual/deprecated) so implementers must handle the
full I2cErrorView (symbols: i2c_error_callback, I2cErrorView, DataId).
---
Outside diff comments:
In `@host/src/protocol/handler.cpp`:
- Around line 182-193: The function process_result can exit without returning a
bool if result is not kSuccess/kBadAlloc/kInvalidArgument; update process_result
(in handler.cpp) to guarantee a return value by adding an explicit return after
core::utility::assert_failed_debug() (e.g. return false) so that for any
unexpected Serializer::SerializeResult enum value the function returns a defined
boolean; ensure references are to core::protocol::Serializer::SerializeResult
and the process_result function name when making the change.
- Around line 195-207: The function process_result_strict lacks a final return
statement for all control paths; update process_result_strict (which checks
core::protocol::Serializer::SerializeResult) to add an explicit unreachable
return (e.g., return false) after calling core::utility::assert_failed_debug(),
ensuring the function always returns a bool even if the assert is compiled out.
---
Nitpick comments:
In `@core/src/protocol/protocol.hpp`:
- Around line 133-146: The DataLength bitfield currently encodes 9 bits
implicitly; add an explicit constexpr named (for example)
I2cHeader::kMaxEncodableDataLength = (1u << 9) - 1 next to the DataLength
typedef and add a compile-time guard (static_assert) that documents/checks the
relationship to the upstream view length type (e.g. compare against
std::numeric_limits<uint16_t>::max() or the actual upstream length type) with a
clear message instructing to update the bitfield if the upstream/allowed I2C
length grows; place these next to the I2cHeader struct so DataLength,
kMaxEncodableDataLength, and the static_assert are colocated.
In `@firmware/rmcs_board/app/src/i2c/i2c.hpp`:
- Around line 426-447: The trailing "return true;" at the end of
try_flush_blocked_uplink is unreachable (the loop either returns true when
blocked_uplink_count_ == 0 or false on kBadAlloc); remove the final return
statement to clean up dead code in function try_flush_blocked_uplink and ensure
no other control paths are added that would require a terminal return.
🪄 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: 749f6914-8cfb-4042-9924-242e964662ec

📥 Commits

Reviewing files that changed from the base of the PR and between 9a1bda6 and dd3540c.

📒 Files selected for processing (38)
  • .codex
  • .devcontainer/devcontainer.json
  • .gitignore
  • core/include/librmcs/data/datas.hpp
  • core/src/protocol/deserializer.cpp
  • core/src/protocol/deserializer.hpp
  • core/src/protocol/protocol.hpp
  • core/src/protocol/serializer.hpp
  • firmware/c_board/app/src/app.cpp
  • firmware/c_board/app/src/i2c/i2c.cpp
  • firmware/c_board/app/src/i2c/i2c.hpp
  • firmware/c_board/app/src/usb/interrupt_safe_buffer.hpp
  • firmware/c_board/app/src/usb/vendor.hpp
  • firmware/c_board/bsp/cubemx/Core/Inc/i2c.h
  • firmware/c_board/bsp/cubemx/Core/Inc/stm32f4xx_hal_conf.h
  • firmware/c_board/bsp/cubemx/Core/Inc/stm32f4xx_it.h
  • firmware/c_board/bsp/cubemx/Core/Src/dma.c
  • firmware/c_board/bsp/cubemx/Core/Src/gpio.c
  • firmware/c_board/bsp/cubemx/Core/Src/i2c.c
  • firmware/c_board/bsp/cubemx/Core/Src/main.c
  • firmware/c_board/bsp/cubemx/Core/Src/stm32f4xx_it.c
  • firmware/c_board/bsp/cubemx/cmake/stm32cubemx/CMakeLists.txt
  • firmware/c_board/bsp/cubemx/rmcs_slave.ioc
  • firmware/rmcs_board/app/CMakeLists.txt
  • firmware/rmcs_board/app/src/app.cpp
  • firmware/rmcs_board/app/src/i2c/i2c.cpp
  • firmware/rmcs_board/app/src/i2c/i2c.hpp
  • firmware/rmcs_board/app/src/usb/interrupt_safe_buffer.hpp
  • firmware/rmcs_board/app/src/usb/vendor.hpp
  • firmware/rmcs_board/boards/lite/board.c
  • firmware/rmcs_board/boards/lite/board.h
  • firmware/rmcs_board/boards/pro/board.c
  • firmware/rmcs_board/boards/pro/board.h
  • host/include/librmcs/agent/c_board.hpp
  • host/include/librmcs/agent/rmcs_board_lite.hpp
  • host/include/librmcs/agent/rmcs_board_pro.hpp
  • host/include/librmcs/protocol/handler.hpp
  • host/src/protocol/handler.cpp

Comment threadcore/include/librmcs/data/datas.hpp Outdated

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
host/include/librmcs/agent/rmcs_board_pro.hpp (1)

73-89: [[unlikely]] 属性使用不一致。

RmcsBoardLitei2c0_writei2c0_read 方法在错误路径使用了 [[unlikely]] 属性(第 64-65、73-74 行),但 RmcsBoardPro 中相同的方法没有使用。

这是一个小的风格不一致,不影响正确性,但建议保持一致。

🔧 建议添加 [[unlikely]] 属性
 PacketBuilder& i2c0_write(const librmcs::data::I2cDataView& data) {
if (data.payload.empty() || data.payload.size() > kI2cMaxDataLength
- || data.slave_address > 0x7FU)+ || data.slave_address > 0x7FU) [[unlikely]]
throw std::invalid_argument{"I2C0 write failed: Invalid I2C data"};
- if (!builder_.write_i2c(data::DataId::kI2c0, data))+ if (!builder_.write_i2c(data::DataId::kI2c0, data)) [[unlikely]]
throw std::runtime_error{"I2C0 write failed: Transmit buffer unavailable"};
return *this;
}
PacketBuilder& i2c0_read(const librmcs::data::I2cReadConfigView& data) {
if (data.read_length == 0 || data.read_length > kI2cMaxDataLength
- || data.slave_address > 0x7FU)+ || data.slave_address > 0x7FU) [[unlikely]]
throw std::invalid_argument{"I2C0 read failed: Invalid I2C read config"};
- if (!builder_.write_i2c_read_config(data::DataId::kI2c0, data))+ if (!builder_.write_i2c_read_config(data::DataId::kI2c0, data)) [[unlikely]]
throw std::runtime_error{"I2C0 read failed: Transmit buffer unavailable"};
return *this;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@host/include/librmcs/agent/rmcs_board_pro.hpp` around lines 73 - 89, In
RmcsBoardPro add the same [[unlikely]] attribute to the error-condition branches
in PacketBuilder::i2c0_write and PacketBuilder::i2c0_read to match
RmcsBoardLite: mark the conditions that throw std::invalid_argument and the
checks of builder_.write_i2c / builder_.write_i2c_read_config with [[unlikely]]
so the throw paths are annotated consistently (update the if(...) throw ...
expressions inside i2c0_write and i2c0_read).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@host/include/librmcs/agent/rmcs_board_pro.hpp`:
- Around line 73-89: In RmcsBoardPro add the same [[unlikely]] attribute to the
error-condition branches in PacketBuilder::i2c0_write and
PacketBuilder::i2c0_read to match RmcsBoardLite: mark the conditions that throw
std::invalid_argument and the checks of builder_.write_i2c /
builder_.write_i2c_read_config with [[unlikely]] so the throw paths are
annotated consistently (update the if(...) throw ... expressions inside
i2c0_write and i2c0_read).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8ad35e1d-6b80-4ebb-be1d-48de37ec108d

📥 Commits

Reviewing files that changed from the base of the PR and between dd3540c and 482e7f7.

📒 Files selected for processing (9)
  • core/include/librmcs/data/datas.hpp
  • core/include/librmcs/protocol/i2c.hpp
  • core/src/protocol/protocol.hpp
  • core/src/protocol/serializer.hpp
  • firmware/c_board/app/src/i2c/i2c.hpp
  • firmware/rmcs_board/app/src/i2c/i2c.hpp
  • host/include/librmcs/agent/c_board.hpp
  • host/include/librmcs/agent/rmcs_board_lite.hpp
  • host/include/librmcs/agent/rmcs_board_pro.hpp
✅ Files skipped from review due to trivial changes (1)
  • core/include/librmcs/protocol/i2c.hpp
🚧 Files skipped from review as they are similar to previous changes (3)
  • host/include/librmcs/agent/c_board.hpp
  • core/src/protocol/protocol.hpp
  • firmware/c_board/app/src/i2c/i2c.hpp

@qzhhhi

Copy link
Copy Markdown
Member

@coderabbitai review

@coderabbitai

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@host/include/librmcs/agent/rmcs_board_pro.hpp`:
- Around line 161-176: The final dispatch i2c_error_callback(data::DataId id,
uint8_t slave_address) currently constructs an I2cErrorView and calls
i2c0_error_callback(const I2cErrorView&), which bypasses any override of
i2c0_error_callback(uint8_t); change the kI2c0 case to call
i2c0_error_callback(slave_address) so the uint8_t virtual is invoked and its
default implementation can forward to the I2cErrorView overload; apply the same
fix in rmcs_board_lite.hpp and c_board.hpp for their corresponding
i2c_error_callback/data::DataId::kI2c0 branches and ensure symbols referenced
are i2c_error_callback(data::DataId, uint8_t), i2c0_error_callback(uint8_t), and
i2c0_error_callback(const librmcs::data::I2cErrorView&).
🪄 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: c9e57eb0-403e-480e-bad3-8bb2021504ab

📥 Commits

Reviewing files that changed from the base of the PR and between 482e7f7 and f1129da.

📒 Files selected for processing (1)
  • host/include/librmcs/agent/rmcs_board_pro.hpp

Comment threadhost/include/librmcs/agent/rmcs_board_pro.hpp Outdated

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (3)
host/include/librmcs/agent/c_board.hpp (2)

158-160: 便捷重载会被派生类名称隐藏。

一旦用户派生类 overridei2c0_error_callback(const I2cErrorView&),这里 i2c0_error_callback(uint8_t) 在派生类中会被名称隐藏,派生类内调用 this->i2c0_error_callback(addr) 将无法编译,需要额外 using CBoard::i2c0_error_callback;。若预期用户会以 uint8_t 形式上报错误,建议在文档里说明,或直接把该重载移到 public: / 通过 using 暴露。rmcs_board_lite.hpp 同一模式也有同样问题。

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@host/include/librmcs/agent/c_board.hpp` around lines 158 - 160, The private
convenience overload void i2c0_error_callback(uint8_t) in CBoard will be
name-hidden when a derived class overrides i2c0_error_callback(const
librmcs::data::I2cErrorView&), causing calls like
this->i2c0_error_callback(addr) in subclasses to fail; fix by making the uint8_t
overload publicly visible (move the function declaration into public:) or add a
using CBoard::i2c0_error_callback; in the class so both overloads are visible to
derived classes, and apply the same change for the identical pattern in
rmcs_board_lite.hpp (referencing i2c0_error_callback(uint8_t),
i2c0_error_callback(const I2cErrorView&), and class CBoard).

53-79: 可选:将 I2C 入参校验逻辑抽出到共享帮助函数。

c_board.hpprmcs_board_lite.hpp(以及 PR 中提到的 rmcs_board_pro.hpp)的 i2c0_write / i2c0_read 校验条件完全一致,后续如果要改动上界或放宽从机地址规则,需要三处同步修改。可考虑在 agent/common.hppprotocol/i2c.hpp 里放一组 inline 校验帮助,让各 board 直接复用,降低漂移风险。

core/include/librmcs/data/datas.hpp (1)

132-134: 重载隐藏的潜在注意事项(可选)。

派生类一旦 override 了纯虚的 i2c_error_callback(DataId, const I2cErrorView&),同名的 uint8_t 便捷重载会被名称隐藏,派生类内部如需调用需额外 using DataCallback::i2c_error_callback;。当前使用方采用不同的函数名(i2c0_error_callback)各自再实现一遍便捷重载,所以这里不会出问题,但如果后续有用户直接继承 DataCallback 并想复用该便捷重载,会踩到这个坑。如果想彻底避免,可考虑改名(例如 i2c_error_callback_with_address)或在类中显式加 using 提示。

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@core/include/librmcs/data/datas.hpp` around lines 132 - 134, 当前类中提供了
i2c_error_callback(DataId, uint8_t) 这个便捷重载,会在派生类 override 纯虚函数
i2c_error_callback(DataId, const I2cErrorView&) 时引发名称隐藏,使得派生类不能直接复用该便捷重载;为修复,在
DataCallback 类中要么把便捷重载改名(例如
i2c_error_callback_with_address)以避免同名隐藏,要么在类定义中显式导出基类重载(添加 using
DataCallback::i2c_error_callback;)或在文档/注释中提醒继承者添加 using,确保派生类能够访问该 uint8_t
版本;参考符号:DataCallback::i2c_error_callback(DataId, const I2cErrorView&) 和
DataCallback::i2c_error_callback(DataId, uint8_t)。
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@core/include/librmcs/data/datas.hpp`:
- Around line 132-134: 当前类中提供了 i2c_error_callback(DataId, uint8_t) 这个便捷重载,会在派生类
override 纯虚函数 i2c_error_callback(DataId, const I2cErrorView&)
时引发名称隐藏,使得派生类不能直接复用该便捷重载;为修复,在 DataCallback 类中要么把便捷重载改名(例如
i2c_error_callback_with_address)以避免同名隐藏,要么在类定义中显式导出基类重载(添加 using
DataCallback::i2c_error_callback;)或在文档/注释中提醒继承者添加 using,确保派生类能够访问该 uint8_t
版本;参考符号:DataCallback::i2c_error_callback(DataId, const I2cErrorView&) 和
DataCallback::i2c_error_callback(DataId, uint8_t)。
In `@host/include/librmcs/agent/c_board.hpp`:
- Around line 158-160: The private convenience overload void
i2c0_error_callback(uint8_t) in CBoard will be name-hidden when a derived class
overrides i2c0_error_callback(const librmcs::data::I2cErrorView&), causing calls
like this->i2c0_error_callback(addr) in subclasses to fail; fix by making the
uint8_t overload publicly visible (move the function declaration into public:)
or add a using CBoard::i2c0_error_callback; in the class so both overloads are
visible to derived classes, and apply the same change for the identical pattern
in rmcs_board_lite.hpp (referencing i2c0_error_callback(uint8_t),
i2c0_error_callback(const I2cErrorView&), and class CBoard).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d84b0d61-f52c-4d71-86ce-fa2b9d949627

📥 Commits

Reviewing files that changed from the base of the PR and between f1129da and b7bb583.

📒 Files selected for processing (4)
  • core/include/librmcs/data/datas.hpp
  • host/include/librmcs/agent/c_board.hpp
  • host/include/librmcs/agent/rmcs_board_lite.hpp
  • host/include/librmcs/agent/rmcs_board_pro.hpp
🚧 Files skipped from review as they are similar to previous changes (1)
  • host/include/librmcs/agent/rmcs_board_pro.hpp

@gqsdjhh

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
core/include/librmcs/data/datas.hpp (1)

84-104: 建议为 slave_address 提供默认值以防未初始化读取

三个新增 view 结构体中的 slave_address 字段均未提供默认初始化器(其他字段都有),如果后续某处通过 I2cXxxView{}(空初始化列表)或仅填充部分字段的聚合初始化来构造,slave_address 将保留未定义值。当前 i2c_error_from_slave_address 使用的是指定初始化器覆盖了 slave_address,暂时无隐患,但保持字段初始化风格一致可避免未来改动时踩坑。

♻️ 建议的小调整
 struct I2cDataView {
- uint8_t slave_address;+ uint8_t slave_address = 0;
std::span<const std::byte> payload;
bool has_register = false;
uint8_t reg_address = 0;
};
struct I2cReadConfigView {
- uint8_t slave_address;+ uint8_t slave_address = 0;
uint16_t read_length = 0;
bool has_register = false;
uint8_t reg_address = 0;
};
struct I2cErrorView {
- uint8_t slave_address;+ uint8_t slave_address = 0;
uint16_t data_length = 0;
bool has_register = false;
uint8_t reg_address = 0;
bool is_read = false;
};
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@core/include/librmcs/data/datas.hpp` around lines 84 - 104, The three view
structs I2cDataView, I2cReadConfigView, and I2cErrorView have an uninitialized
slave_address member; add a default initializer (e.g., uint8_t slave_address =
0;) to each struct so aggregate or empty-list construction yields a defined
value, keeping initialization style consistent with other fields and preventing
future UB (references: I2cDataView, I2cReadConfigView, I2cErrorView; caller:
i2c_error_from_slave_address).
host/include/librmcs/agent/rmcs_board_pro.hpp (1)

154-168: 考虑移除与基类重复的便捷函数

i2c0_error_from_slave_address(uint8_t) 与基类 DataCallback::i2c_error_from_slave_address(DataId, uint8_t) 语义等价:后者会触发本类内 final 的 i2c_error_callback,最终仍派发到 i2c0_error_callback(I2cErrorView)。两份助手函数并存,容易让子类维护者不清楚该调用哪一个。可以考虑删掉这个派生类的助手,统一使用基类的版本;或者反过来把基类的助手删掉、让派生类保留面向具体通道的便捷函数。

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@host/include/librmcs/agent/rmcs_board_pro.hpp` around lines 154 - 168, This
class defines a channel-specific helper i2c0_error_from_slave_address(uint8_t)
which duplicates the base-class helper
DataCallback::i2c_error_from_slave_address(DataId, uint8_t) and creates
ambiguity for subclasses; remove the derived helper
(i2c0_error_from_slave_address) and update call sites to use the base-class
DataCallback::i2c_error_from_slave_address(data::DataId::kI2c0, slave_address)
so that the final i2c_error_callback dispatch still routes into this class's
i2c0_error_callback(const librmcs::data::I2cErrorView&), or alternatively remove
the base helper and keep the derived one—choose one approach and delete the
other to avoid duplicated helpers, ensuring i2c_error_callback and
i2c0_error_callback continue to be invoked as before.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@core/include/librmcs/data/datas.hpp`:
- Around line 84-104: The three view structs I2cDataView, I2cReadConfigView, and
I2cErrorView have an uninitialized slave_address member; add a default
initializer (e.g., uint8_t slave_address = 0;) to each struct so aggregate or
empty-list construction yields a defined value, keeping initialization style
consistent with other fields and preventing future UB (references: I2cDataView,
I2cReadConfigView, I2cErrorView; caller: i2c_error_from_slave_address).
In `@host/include/librmcs/agent/rmcs_board_pro.hpp`:
- Around line 154-168: This class defines a channel-specific helper
i2c0_error_from_slave_address(uint8_t) which duplicates the base-class helper
DataCallback::i2c_error_from_slave_address(DataId, uint8_t) and creates
ambiguity for subclasses; remove the derived helper
(i2c0_error_from_slave_address) and update call sites to use the base-class
DataCallback::i2c_error_from_slave_address(data::DataId::kI2c0, slave_address)
so that the final i2c_error_callback dispatch still routes into this class's
i2c0_error_callback(const librmcs::data::I2cErrorView&), or alternatively remove
the base helper and keep the derived one—choose one approach and delete the
other to avoid duplicated helpers, ensuring i2c_error_callback and
i2c0_error_callback continue to be invoked as before.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6fd98255-ac96-4b55-b898-fa17226b0fb7

📥 Commits

Reviewing files that changed from the base of the PR and between b7bb583 and 0d871db.

📒 Files selected for processing (4)
  • core/include/librmcs/data/datas.hpp
  • host/include/librmcs/agent/c_board.hpp
  • host/include/librmcs/agent/rmcs_board_lite.hpp
  • host/include/librmcs/agent/rmcs_board_pro.hpp
🚧 Files skipped from review as they are similar to previous changes (1)
  • host/include/librmcs/agent/c_board.hpp

@gqsdjhh

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@gqsdjhh

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
host/include/librmcs/agent/rmcs_board_lite.hpp (1)

133-154: 考虑将三个板级 agent 的 I2C0 派发样板抽到公共基类。

CBoardRmcsBoardProRmcsBoardLite 三个文件中的 i2c_receive_callback / i2c_error_callbackfinal 派发、i2c0_receive_callback / i2c0_error_callback 默认空实现、以及 i2c0_error_from_slave_address 转发完全一致。builder 侧的 i2c0_write / i2c0_read / kI2cMaxDataLength 也三处重复。建议抽到 agent/common.hpp 附近的一个 mixin/基类(或以 CRTP 复用 builder 片段),在后续新增逻辑 I2C 通道时减少 3 处同步修改成本。非阻塞,可延后处理。

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@host/include/librmcs/agent/rmcs_board_lite.hpp` around lines 133 - 154,
Extract the duplicated I2C0 dispatch and helpers into a shared base/mixin (e.g.,
near agent/common.hpp) and have CBoard, RmcsBoardPro, and RmcsBoardLite inherit
it: move the final i2c_receive_callback and i2c_error_callback dispatch logic,
the default no-op virtuals i2c0_receive_callback and i2c0_error_callback, and
the helper i2c0_error_from_slave_address into the new base; also consolidate
builder-side i2c0_write, i2c0_read and kI2cMaxDataLength into the same reusable
component (or a CRTP builder fragment) so each board class only overrides i2c0_*
methods as needed and the common dispatch/signature symbols remain unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@host/include/librmcs/agent/rmcs_board_lite.hpp`:
- Around line 133-154: Extract the duplicated I2C0 dispatch and helpers into a
shared base/mixin (e.g., near agent/common.hpp) and have CBoard, RmcsBoardPro,
and RmcsBoardLite inherit it: move the final i2c_receive_callback and
i2c_error_callback dispatch logic, the default no-op virtuals
i2c0_receive_callback and i2c0_error_callback, and the helper
i2c0_error_from_slave_address into the new base; also consolidate builder-side
i2c0_write, i2c0_read and kI2cMaxDataLength into the same reusable component (or
a CRTP builder fragment) so each board class only overrides i2c0_* methods as
needed and the common dispatch/signature symbols remain unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d1e17454-c4b2-465d-86e1-461c7681e0da

📥 Commits

Reviewing files that changed from the base of the PR and between b7bb583 and 9adf3b5.

📒 Files selected for processing (4)
  • core/include/librmcs/data/datas.hpp
  • host/include/librmcs/agent/c_board.hpp
  • host/include/librmcs/agent/rmcs_board_lite.hpp
  • host/include/librmcs/agent/rmcs_board_pro.hpp

@gqsdjhh

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@gqsdjhhgqsdjhh closed this Apr 18, 2026
@github-project-automationgithub-project-automationBot moved this from Todo to Done in RMCS Slave SDKApr 18, 2026
Sign up for freeto 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.

2 participants

@gqsdjhh@qzhhhi