厂商专用 API 放置策略

概述

本策略规定如何向 Zephyr 项目贡献、组织和开放厂商专用硬件功能,以保持公共 API 稳定,防止厂商扩展绕过标准 API 生命周期,并为潜在的跨厂商功能演进为通用驱动程序类别提供明确路径。

厂商专用 API 不得作为 Zephyr 公共接口开放,除非满足纳入正式 API 生命周期(实验性 → 稳定 → 弃用)的条件。本质上绑定单个 SoC 或厂商的功能,必须封装在该厂商的 SoC 目录中。

本策略为贡献者和维护者提供一致的决策模型。

指导原则

  • Zephyr 公共 API 不得包含厂商专用接口。

    放在 include/zephyr/ 下的接口应遵循标准 API 生命周期演进。无法满足这一要求的厂商专用接口,不得作为 Zephyr 公共 API 开放。

  • 优先采用通用方案,而非厂商专用方案。

    如果硬件功能适用于多个厂商,或未来可能如此,应将其实现为现有驱动程序类别的一部分,或创建新的跨厂商驱动程序类别。

  • 厂商专用功能必须封装。

    仅供单一厂商使用的机制应位于该厂商的平台命名空间内,例如 SoC、开发板等目录。

  • 必须保留演进空间。

    代码位置不得妨碍以后将厂商专用实现提升为可移植的 Zephyr 驱动程序类别。

决策流程

添加新的硬件功能或厂商专用行为时,贡献者必须按以下顺序遵循决策树:

  • 该功能在逻辑上是否扩展了现有驱动程序类别?

    如果是,扩展现有类别,不要创建厂商专用 API。

  • 该功能能否成为跨厂商驱动程序类别?

    如果硬件概念并非明显为某一家厂商所独有,或类似于可能出现在多种架构中的模式,应创建新的驱动程序类别。

  • 该功能是否明确为厂商专用,且不太可能通用化?

    此时,应将头文件和实现都放在以下位置:

    soc/<vendor>/..
    

    这样可以实现真正的封装,保证长期可维护性,并在移除 SoC 时干净地删除相关内容。

    厂商专用代码的头文件应位于 soc/<vendor>/include,实现代码应位于 soc/<vendor>/common 或 soc/<vendor>/<series>。

    这些接口属于厂商私有或内部接口,用于支持其特定硬件,并会受到严格审查,以避免形成厂商专属的功能孤岛。

    由于这些接口属于厂商内部或私有接口,使用它们的应用不应期待任何生命周期或向后兼容性保证。

允许的位置汇总

  1. 扩展现有驱动程序类别时

  • 位置:

    include/zephyr/drivers/<class>.h
    drivers/<class>/
    
  • 适用条件:

    功能符合或扩展了现有类别。

  1. 现有驱动程序类别的厂商专用扩展

  • 位置:

    include/zephyr/drivers/<class>/
    drivers/<class>/
    
  • 适用条件:

    该功能是现有类别的厂商专用扩展,但核心概念并非单一厂商独有,未来可能标准化。

  1. 创建新的驱动程序类别(跨厂商)

  • 位置:

    include/zephyr/drivers/<class>.h
    drivers/<class>/
    
  • 适用条件:

    该功能可以合理地适用于多个厂商,或演进为通用抽象。

  1. 厂商专用、SoC 本地代码(厂商独有功能的默认选择)

  • 位置:

    厂商专用代码的头文件应位于 soc/<vendor>/include,实现代码应位于 soc/<vendor>/common 或 soc/<vendor>/<series>。

  • 适用条件:

    该功能为厂商或 SoC 独有,不作为公共 API。