You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

嵌入式系统开发中函数错误码的返回实现方案该如何选择?

结论

方案1是当前场景下的最优选择,也是工业界通用HAL层的主流设计规范


各方案对比

方案1的优势

  • 符合嵌入式开发的普遍心智习惯:ST HAL、NXP MCUXpresso、瑞萨FSP等主流厂商的外设读写接口,全部采用「返回值传错误码,输出数据放指针入参」的设计,开发者不需要额外适配就能上手,基本不会用错。
  • 错误处理逻辑严谨:调用时必须先判断返回值是否为I2C_ERR_OK,确认成功后再读取data指向的内容,从编码逻辑上避免了错误场景下误用无效数据的问题,示例调用代码如下:
uint8_t recv_data;
i2c_err_t err = I2C_read(&hi2c1, TARGET_DEV_ADDR, TARGET_REG_ADDR, &recv_data);
if (err != I2C_ERR_OK) {
    // 按需处理NACK、总线超时、总线忙等错误
    return err;
}
// 正常使用recv_data
  • 扩展性极强:后续如果要扩展读多字节的I2C_read_bytes接口,仅需要新增一个长度入参即可,接口风格和单字节读取完全统一,不会出现设计分裂的问题。

方案2的缺陷

  • 错误容易被忽略:很多开发者会直接使用函数返回的uint8_t值,忘记检查err指针指向的错误码,错误场景下拿到的无效数据会引发后续逻辑异常,排查成本极高。
  • 扩展性差:如果后续要实现读多字节的接口,无法复用「返回值传数据」的设计,会导致整个I2C模块的接口风格不统一。
  • 额外增加边界处理逻辑:你需要在函数内部额外判断err指针是否为NULL,避免用户传空指针触发崩溃,增加了不必要的代码分支。

原始int32_t返回值方案的隐患

虽然该方案逻辑上可以跑,但存在两个致命问题:

  • 容易出现截断错误:如果开发者没注意返回值类型,直接把返回值赋值给uint8_t变量,负值错误码会被截断为0xFF,和正常读取到的0xFF字节完全无法区分,排查难度极大。
  • 扩展性不足:后续如果要实现读16位寄存器的接口,该设计直接失效,需要整体重构。

其他实现思路

你提到的结构体封装方案确实属于过度设计,单字节和多字节场景都不需要用到,反而会增加调用复杂度。如果需要兼顾易用性和调试需求,可以额外加一个可选的I2C_get_last_err()辅助接口,给需要细粒度查错的场景使用,核心接口还是保留方案1的设计即可。


内容的提问来源于stack exchange,提问作者moonraccoon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 03:36:01