ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Zephyr BSP: 47-BSP Customer SDK

Zephyr BSP: 47-BSP Customer SDK BSP 是公司内部平台基础设施,Customer SDK 才是客户开发产品的入口。SDK 通过「稳定接口边界」把内部实现与客户代码解耦,客户只依赖受版本承诺保护的 Public API。一个完整 SDK 包含 Toolchain、Zephyr/BSP、Board Support、SDK API、Samples、Docs 与 Build/Flash/Debug 工具,并经过「开发 → CI → 打包 → SBOM → 发布 → 交付」的完整流程。版本演进遵循语义化版本号,配合 Deprecated 标记与迁移指南,让客户升级不被打断。**BSP Customer SDK:把 BSP 变成"客户真正能用的产品"**BSP 做出来以后,公司客户到底拿什么东西来开发产品?答案通常不是让客户直接面对几十万个 Zephyr 源文件,而是提供一层:BSP Customer SDK可以把整个体系理解成:Company BSP │ ┌─────────────┴─────────────┐ │ │ BSP Internal Customer SDK │ │ HAL/Drivers/SoC Headers Devicetree/Board Libraries Build System Samples CI/Tests Toolchain Security/SBOM Flash/Debug │ │ └─────────────┬───────────────┘ │ Customer │ ┌──────────┼──────────┐ │ │ │ App1App2App3核心思想是:BSP 是公司的产品基础设施,Customer SDK 是客户使用 BSP 的产品开发接口。下面这张图把 Customer SDK 的完整架构分层展开,标注每一层包含的内容、层与层之间的依赖关系,以及客户与 BSP 内部之间的稳定接口边界:┌──────────────────────────────────────────────────────────────┐ │ Customer Application │ │(客户自己的 app/boards/prj.conf)│ └───────────────────────────┬──────────────────────────────────┘ │ ┌─────────────▼─────────────┐ │ Stable Interface │ ← 稳定接口边界 │(Zephyr API+SDK API)│ └─────────────┬─────────────┘ │ ┌───────────────────────────▼──────────────────────────────────┐ │ Customer SDK │ │ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │ │ │ Toolchain │ │ Zephyr/BSP │ │ Board Support │ │ │ │ GCC/CMake │──▶│ Zephyr OS │──▶│ Board Catalog │ │ │ │ Python/west │ │ Company BSP │ │ SoC/RAM/Flash │ │ │ └──────────────┘ └──────────────┘ │ UART/GPIO/SPI │ │ │ └──────────────────┘ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │ │ │ SDK API │ │ Samples │ │ Documentation │ │ │ │ Public API │──▶│ hello_world │ │ Getting Started │ │ │ │ Private API │ │ blinky/gpio │ │ Migration Guide │ │ │ └──────────────┘ └──────────────┘ └──────────────────┘ │ │ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │ │ │ Build Tools │ │ Flash Tools │ │ Debug Tools │ │ │ │ west build │ │ west flash │ │ GDB/OpenOCD │ │ │ └──────────────┘ └──────────────┘ └──────────────────┘ │ │ │ │ ┌────────────────────────────────────────────────────────┐ │ │ │ Release Metadata │ │ │ │ SDK version/Zephyr version/BSP version/SBOM │ │ │ └────────────────────────────────────────────────────────┘ │ └───────────────────────────┬──────────────────────────────────┘ │ ┌─────────────▼─────────────┐ │ Stable Interface │ ← 稳定接口边界 │(Zephyr API+SDK API)│ └─────────────┬─────────────┘ │ ┌───────────────────────────▼──────────────────────────────────┐ │ BSP Internal │ │ HAL/SoC/Drivers/Devicetree/Kconfig/Linker │ │ CI/Tests/Security/SBOM │ └──────────────────────────────────────────────────────────────┘各层之间的依赖关系与边界说明:Toolchain → Zephyr/BSP:工具链负责把应用与 BSP 源码编译成可执行镜像,SDK 必须锁定经过验证的 GCC/CMake/Python/west 版本组合;Zephyr/BSP → Board Support:BSP 提供 SoC 与驱动实现,Board Support 在其之上定义客户可见的板卡目录(如company_devkit)与资源清单;SDK API → Samples → Documentation:Samples 演示 SDK API 的用法,Documentation 解释 API 语义与迁移路径,三者共同构成客户的学习入口;Build/Flash/Debug Tools:统一封装west build/west flash/company debug,屏蔽底层 OpenOCD、J-Link、ST-Link 等差异;Release Metadata:把 SDK、Zephyr、BSP、HAL、Toolchain 的版本关系与 SBOM 固定下来,形成可交付的软件物料清单;上下两条「稳定接口边界」:客户只接触 Zephyr API 与 SDK Public API,BSP 内部实现细节被完全隔离在边界之下,公司可以自由演进内部实现而不破坏客户代码。1. 为什么 BSP 和 Customer SDK 不是一回事?很多公司最开始会直接把 BSP Git repository 给客户。例如:company-bsp/├── zephyr/├── modules/├── soc/├── boards/├── drivers/├── dts/├── samples/├── scripts/└── tools/客户然后:west build-b company_board app看起来很好。但很快就会出现问题。客户开始依赖:soc/drivers/dts/Kconfig CMakeLists.txt 内部 HAL 内部 scripts 内部 CI 内部测试代码于是客户实际上不是在使用:BSP API而是在使用:BSP 内部实现细节。这会导致一个严重问题:BSP v1.0│ ├── 客户 A 依赖内部文件 A ├── 客户 B 依赖内部 Kconfig ├── 客户 C patch driver └── 客户 D 修改 linker script │ ▼ BSP v2.0│ ┌─────┼─────┐ ▼ ▼ ▼ A崩 B崩 C崩所以成熟的 BSP 必须建立:下面从几个关键维度对比「直接给 BSP 仓库」与「提供 Customer SDK」两种交付方式的差异:|维度|直接给 BSP 仓库|提供 Customer SDK||---|---|---||**客户接触面**|客户直接面对 `soc/`、`drivers/`、`dts/`、`Kconfig`、内部 HAL 等实现细节|客户只接触 Zephyr API+SDK Public API,内部实现被「稳定接口边界」隔离||**依赖稳定性**|客户会逐渐依赖内部文件、内部 Kconfig、甚至 patch 驱动/修改 linker script|客户依赖的是稳定、受支持的 Public API,内部实现可自由演进||**升级影响**|BSP 升级时,依赖内部实现的客户 A/B/C 逐个崩溃,升级成本极高|只要 Public API 兼容,客户代码无需改动,升级平滑||**支持成本**|每个客户都 fork 一份 BSP,公司需要为每个分支单独维护,成本爆炸|所有客户共享同一份稳定 SDK,支持成本集中在 SDK 本身||**学习门槛**|客户需要理解 BSP 内部结构才能上手,10分钟跑不起来|通过 samples/docs/tools 让客户10分钟内跑起来||**可交付性**|只是源码包,缺少工具链、文档、烧录调试工具、版本锁定|是经过验证的完整开发环境(含 toolchain/samples/docs/manifest/SBOM)|**简要说明**:两种方式的本质区别在于「客户依赖什么」。直接给 BSP 仓库时,客户被迫依赖 BSP 的内部实现细节,这些细节不属于稳定接口,一旦 BSP 演进就会破坏客户代码,且每个客户各自 fork 导致维护成本失控。而 Customer SDK 通过「稳定接口边界」把内部实现与客户代码解耦,客户只依赖受版本承诺保护的 Public API,公司可以自由重构内部实现而不惊动客户,同时 SDK 作为完整交付物(工具链、示例、文档、版本锁定、SBOM)显著降低了客户的上手门槛与公司的支持成本。 Internal BSP │ │ Stable Interface ▼ Customer SDK │ ▼ Customer Application2. Customer SDK 到底包含什么?一个完整的 SDK 通常包括:Customer SDK │ ├── Toolchain │ ├── Zephyr/BSP │ ├── Board Support │ ├── Device Drivers │ ├── SDK Headers │ ├── SDK Libraries │ ├── Samples │ ├── Documentation │ ├── Build Tools │ ├── Flash Tools │ ├── Debug Tools │ ├── Test Framework │ └── Release Metadata但这里要注意:不是所有 BSP 内部文件都应该暴露给客户。下面是一个完整的 Customer SDK 顶层目录树示例。我们用注释标注每个目录的用途,并用[客户可见]/[内部保留]明确哪些目录客户可以直接使用、哪些仅供公司内部维护:company-sdk/│ ├── toolchain/#[客户可见]经过验证的工具链(GCC/CMake/Python/west) │ ├── bin/# 编译器与工具可执行文件 │ ├── lib/# 运行时库 │ └── include/# 编译器内置头文件 │ ├── zephyr/#[客户可见]Zephyr 内核+Company BSP 源码 │ ├── kernel/# Zephyr 内核实现 │ ├── drivers/# 驱动框架与 Company 驱动 │ ├── dts/# Devicetree 源文件 │ ├── soc/# SoC 支持 │ └── boards/# 板级定义(见下方 boards/) │ ├── boards/#[客户可见]Board Catalog,客户用-b 指定 │ ├── company_devkit/# 开发板定义(dts、Kconfig、defconfig) │ ├── company_devkit_pro/│ ├── company_eval/│ └── company_reference/│ ├── include/#[客户可见]SDK Public API 头文件 │ └── company/│ ├── version.h # 版本信息 │ ├── power.h # 电源管理 API │ ├── security.h # 安全 API │ └── device_info.h # 设备信息 API │ ├── lib/#[客户可见]SDK 预编译库/源码库 │ └── company/# Company 提供的静态/动态库 │ ├── samples/#[客户可见]示例工程,客户学习入口 │ ├── hello_world/# 最小串口打印 │ ├── blinky/# GPIO 输出 │ ├── gpio/# GPIO 输入/中断 │ ├── uart/# UART 通信 │ ├── i2c/# I2C 外设 │ ├── spi/# SPI 外设 │ ├── adc/# ADC 采样 │ ├── pwm/# PWM 输出 │ ├── timer/# 定时器 │ ├── usb/# USB 设备 │ └── power_management/# 低功耗管理 │ ├── docs/#[客户可见]SDK 文档 │ ├── getting_started/# 快速上手 │ ├── installation/# 安装指南 │ ├── supported_boards/# 支持的板卡列表 │ ├── migration_guide/# 迁移指南(SDK1.x →2.x) │ └── release_notes/# 版本发布说明 │ ├── scripts/#[内部保留]构建/打包/发布脚本 │ ├── build/# 内部构建脚本 │ ├── package/# 打包脚本 │ └── release/# 发布流水线脚本 │ ├── tools/#[客户可见]客户使用的辅助工具 │ ├── flash/# west flash 封装/company flash │ ├── debug/# company debug(GDB+OpenOCD/J-Link) │ └── create/# company-sdk create 工程模板工具 │ ├── manifest/#[客户可见]west manifest,锁定版本组合 │ └── west.yml # Zephyr/HAL/BSP/三方模块版本 │ ├── modules/#[内部保留]内部模块(不直接暴露给客户) │ ├── hal_company/# Company HAL 源码 │ └── company_sdk/# SDK 内部实现 │ ├── tests/#[内部保留]内部测试与 CI │ ├── unit/# 单元测试 │ ├── regression/# 回归测试 │ └── hil/# 硬件在环测试 │ ├── licenses/#[客户可见]许可证文件 │ └── LICENSE-company.txt # Company 许可证 │ ├── sbom/#[客户可见]软件物料清单 │ └── company-sdk-2.1.0.spdx # SPDX 格式 SBOM │ ├── VERSION #[客户可见]SDK 版本号 └── README.md #[客户可见]SDK 总览与快速开始目录可见性小结目录客户可见用途toolchain/✅经过验证的工具链组合zephyr/✅Zephyr 内核 + Company BSPboards/✅板卡目录,-b company_devkit指定include/✅SDK Public API 头文件lib/✅SDK 库samples/✅示例工程,学习入口docs/✅文档与迁移指南tools/✅flash / debug / create 工具manifest/✅west manifest,锁定版本licenses/✅许可证sbom/✅软件物料清单scripts/❌内部构建/发布脚本modules/❌内部 HAL 与 SDK 实现tests/❌内部测试与 CI2.1 Customer SDK 的发布与交付流程上一节从目录层面看清了 SDK 的组成。这一节我们把视角切换到「时间轴」:一个 SDK 版本从 BSP 内部开发到客户真正拿到手,中间要经过哪些环节,每个环节又设置了怎样的质量门禁。下面是完整的发布与交付流程:
返回列表