Uh oh!
There was an error while loading. Please reload this page.
Conversation
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
🚧 Files skipped from review as they are similar to previous changes (2)
Walkthrough新增 I2C 支持:协议常量与位域、数据视图与回调、序列化/反序列化扩展、主机封装与接收分派、STM32/HPM 固件驱动与板级初始化、USB 下/上行集成及若干工具/配置与 .gitignore 调整。 Changes
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: 上行数据发送到主机
Estimated code review effort🎯 4 (复杂) | ⏱️ ~45 分钟 Possibly related PRs
诗
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
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不是kSuccess、kBadAlloc或kInvalidArgument时,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
📒 Files selected for processing (38)
.codex.devcontainer/devcontainer.json.gitignorecore/include/librmcs/data/datas.hppcore/src/protocol/deserializer.cppcore/src/protocol/deserializer.hppcore/src/protocol/protocol.hppcore/src/protocol/serializer.hppfirmware/c_board/app/src/app.cppfirmware/c_board/app/src/i2c/i2c.cppfirmware/c_board/app/src/i2c/i2c.hppfirmware/c_board/app/src/usb/interrupt_safe_buffer.hppfirmware/c_board/app/src/usb/vendor.hppfirmware/c_board/bsp/cubemx/Core/Inc/i2c.hfirmware/c_board/bsp/cubemx/Core/Inc/stm32f4xx_hal_conf.hfirmware/c_board/bsp/cubemx/Core/Inc/stm32f4xx_it.hfirmware/c_board/bsp/cubemx/Core/Src/dma.cfirmware/c_board/bsp/cubemx/Core/Src/gpio.cfirmware/c_board/bsp/cubemx/Core/Src/i2c.cfirmware/c_board/bsp/cubemx/Core/Src/main.cfirmware/c_board/bsp/cubemx/Core/Src/stm32f4xx_it.cfirmware/c_board/bsp/cubemx/cmake/stm32cubemx/CMakeLists.txtfirmware/c_board/bsp/cubemx/rmcs_slave.iocfirmware/rmcs_board/app/CMakeLists.txtfirmware/rmcs_board/app/src/app.cppfirmware/rmcs_board/app/src/i2c/i2c.cppfirmware/rmcs_board/app/src/i2c/i2c.hppfirmware/rmcs_board/app/src/usb/interrupt_safe_buffer.hppfirmware/rmcs_board/app/src/usb/vendor.hppfirmware/rmcs_board/boards/lite/board.cfirmware/rmcs_board/boards/lite/board.hfirmware/rmcs_board/boards/pro/board.cfirmware/rmcs_board/boards/pro/board.hhost/include/librmcs/agent/c_board.hpphost/include/librmcs/agent/rmcs_board_lite.hpphost/include/librmcs/agent/rmcs_board_pro.hpphost/include/librmcs/protocol/handler.hpphost/src/protocol/handler.cpp
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
🧹 Nitpick comments (1)
host/include/librmcs/agent/rmcs_board_pro.hpp (1)
73-89:[[unlikely]]属性使用不一致。
RmcsBoardLite的i2c0_write和i2c0_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
📒 Files selected for processing (9)
core/include/librmcs/data/datas.hppcore/include/librmcs/protocol/i2c.hppcore/src/protocol/protocol.hppcore/src/protocol/serializer.hppfirmware/c_board/app/src/i2c/i2c.hppfirmware/rmcs_board/app/src/i2c/i2c.hpphost/include/librmcs/agent/c_board.hpphost/include/librmcs/agent/rmcs_board_lite.hpphost/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
commented
Apr 17, 2026
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
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
📒 Files selected for processing (1)
host/include/librmcs/agent/rmcs_board_pro.hpp
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
🧹 Nitpick comments (3)
host/include/librmcs/agent/c_board.hpp (2)
158-160: 便捷重载会被派生类名称隐藏。一旦用户派生类
override了i2c0_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.hpp、rmcs_board_lite.hpp(以及 PR 中提到的rmcs_board_pro.hpp)的i2c0_write/i2c0_read校验条件完全一致,后续如果要改动上界或放宽从机地址规则,需要三处同步修改。可考虑在agent/common.hpp或protocol/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
📒 Files selected for processing (4)
core/include/librmcs/data/datas.hpphost/include/librmcs/agent/c_board.hpphost/include/librmcs/agent/rmcs_board_lite.hpphost/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
commented
Apr 17, 2026
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
🧹 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
📒 Files selected for processing (4)
core/include/librmcs/data/datas.hpphost/include/librmcs/agent/c_board.hpphost/include/librmcs/agent/rmcs_board_lite.hpphost/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
commented
Apr 17, 2026
@coderabbitai review |
✅ Actions performedReview triggered.
|
gqsdjhh
commented
Apr 17, 2026
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
🧹 Nitpick comments (1)
host/include/librmcs/agent/rmcs_board_lite.hpp (1)
133-154: 考虑将三个板级 agent 的 I2C0 派发样板抽到公共基类。
CBoard、RmcsBoardPro、RmcsBoardLite三个文件中的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
📒 Files selected for processing (4)
core/include/librmcs/data/datas.hpphost/include/librmcs/agent/c_board.hpphost/include/librmcs/agent/rmcs_board_lite.hpphost/include/librmcs/agent/rmcs_board_pro.hpp
gqsdjhh
commented
Apr 18, 2026
@coderabbitai review |
✅ Actions performedReview triggered.
|
功能与架构概述
为
c_board与rmcs_board引入统一的I2C0协议通路,并补齐 host agent、固件驱动和协议层支持。rmcs_board使用基于 HPM SDK 的非阻塞 DMA I2C 实现,c_board将逻辑I2C0映射到 STM32I2C2,同时围绕 USB背压、超时恢复、错误上报和非法请求处理做了系统性加固。
主要变更要点
I2C0字段的序列化与反序列化,区分 write、read request、read result 和 error,并拒绝空 I2C 传输。CBoard、RmcsBoardPro和RmcsBoardLite增加i2c0_write()/i2c0_read()接口,以及对应的接收与错误回调入口。rmcs_board固件新增I2C0驱动、DMA completion callback 和 main-loop update 流程,启用 HPM I2C 组件,并在 Pro/Lite 板级层补充 I2C 引脚、时钟和总线恢复初始化。c_board固件新增逻辑I2C0通道,使用 STM32I2C2+ DMA 实现读写,并补充 HAL 回调、中断路由、CubeMX 配置和超时恢复。read result或error在缓冲区拥塞时静默丢失。c_board的 I2C IRQ 优先级以减少与 USB 的冲突,并明确逻辑I2C0与物理I2C2的映射关系。rmcs_board使用的 HPM SDK 以恢复hpm5300evk相关板定义。影响与兼容性
CBoard、RmcsBoardPro和RmcsBoardLite新增I2C0主机接口与回调入口。c_board的逻辑I2C0实际由 STM32I2C2承载,但 host/firmware 对外名称保持不变。I2C0 跨板传输与传输恢复增强(含若干配套改动)
概述
本 PR 在主机、协议及两类板级固件(c_board / rmcs_board)间引入统一的逻辑 I2C0 传输通道,并强化传输的错误/超时恢复与上行缓冲策略。实现涵盖协议、主机 API、c_board(STM32 + DMA)与 rmcs_board(HPM + DMA)端的端到端支持,以及若干与构建、USB、中断相关的配套调整。修正了主机端 I2C 回调分发以避免覆盖/隐藏错误回调。
协议与数据结构
序列化/反序列化与主机协议处理
主机 API 与代理类改动
c_board 固件(STM32)实现要点
rmcs_board 固件(HPM)实现要点
错误与流控细节(关键行为)
构建与应用层变更
其他配套与非功能性变更
兼容性与注意事项