新闻详情

新闻详情

首页 / 资讯中心 / 详情

轻松学习Zephyr BSP: 40-公司 BSP 的完整生命周期

发布时间:2026/9/25 18:36:55来源:尧图网络
轻松学习Zephyr BSP: 40-公司 BSP 的完整生命周期
摘要:本文是 Zephyr BSP 系列(第 20~40 篇)的收束篇,系统梳理一个公司 SoC 从芯片定义到 BSP 可交付的完整生命周期。全文按 18 个阶段展开:从 SoC 规格、Company HAL、Zephyr SoC Port、Startup、中断控制器、时钟/复位,到 Devicetree、Binding、驱动、Kconfig、CMake、Linker、Board、Flash/Debug、Validation、SoC Family、Release 直至 CI 落地。核心观点是:BSP 不是"一个 boards/xxx/ 目录",而是一条从 Silicon 到 Application 的软件供应链。文章最后给出公司 BSP 需要维护的"四条线"(硬件线、软件抽象线、构建线、验证线),帮助读者建立从"学 Zephyr"到"交付可维护 BSP"的工程视角。公司 BSP 的完整生命周期到第 39 篇,我们已经把SoC Family Architecture讲清楚了。现在进入一个非常重要的收束篇:一个公司 SoC,从"芯片刚出来"到"Zephyr BSP 真正可交付",整个生命周期到底是什么?这篇不再只讲某一个文件,而是把前面20~39 篇全部串起来。一、先建立一个总模型一个真正的公司 BSP,不是:写几个 driver ↓ 能跑 blinky ↓ 结束而应该是:SoC Silicon ↓ Company HAL ↓ Zephyr SoC Port ↓ Devicetree / Binding ↓ Kconfig ↓ Drivers ↓ Board ↓ Build System ↓ Linker / Memory ↓ Flash / Debug / Runner ↓ BSP Validation ↓ Release / Maintenance再进一步:┌──────────────────────┐ │ SoC Silicon │ └──────────┬───────────┘ ↓ ┌──────────────────────┐ │ Company HAL │ │ Clock / IRQ / GPIO │ │ UART / SPI / I2C... │ └──────────┬───────────┘ ↓ ┌──────────────────────┐ │ Zephyr SoC Port │ │ startup / soc.c │ │ CMake / Kconfig │ └──────────┬───────────┘ ↓ ┌──────────────────────┐ │ Devicetree + DT │ │ hardware description │ └──────────┬───────────┘ ↓ ┌──────────────────────┐ │ Zephyr Drivers │ │ UART GPIO SPI I2C... │ └──────────┬───────────┘ ↓ ┌──────────────────────┐ │ Board │ │ pins / LEDs / buttons│ └──────────┬───────────┘ ↓ ┌──────────────────────┐ │ Build / Link / Flash │ └──────────┬───────────┘ ↓ ┌──────────────────────┐ │ BSP Validation │ └──────────────────────┘这就是公司 BSP 的完整生命周期。二、第一阶段:SoC 还没出来这是很多 BSP 工程师容易忽略的一个阶段。芯片甚至还没有回来。但是 BSP 工作已经可以开始。例如公司决定做:Company SoC X1 ├── Cortex-M4 ├──512KB Flash ├──128KB SRAM ├── UART ×3├── SPI ×2├── I2C ×2├── GPIO ├── Timer ├── DMA └── Interrupt Controller此时首先需要建立:SoC specification ↓ memory map ↓ interrupt map ↓ peripheral map ↓ clock tree ↓ reset tree ↓ pinmux也就是说:BSP 的第一份「代码」往往不是 C 代码,而是硬件规格。三、第二阶段:Company HAL 出现芯片团队通常会先提供自己的 HAL。例如:company-hal/ ├── include/ │ ├── company_uart.h │ ├── company_gpio.h │ ├── company_clock.h │ └── company_irq.h │ ├── src/ │ ├── company_uart.c │ ├── company_gpio.c │ ├── company_clock.c │ └── company_irq.c │ └── startup/ └── startup_company.SHAL 负责:寄存器 ↓ Company API例如:company_uart_init();company_uart_write();company_uart_read();这层通常不应该知道:struct device DEVICE_DT_DEFINE()DT_INST_FOREACH_STATUS_OKAY()因为这些是 Zephyr 的概念。所以我们之前第 37 篇讲的边界非常重要:┌─────────────────────────┐ │ Zephyr │ │ │ │ struct device │ │ driver API │ │ devicetree │ │ Kconfig │ └────────────┬────────────┘ │ │ adapter ↓ ┌─────────────────────────┐ │ Company HAL │ │ │ │ company_uart_xxx()│ │ company_clock_xxx()│ │ company_gpio_xxx()│ └────────────┬────────────┘ │ ↓ ┌─────────────────────────┐ │ Registers │ └─────────────────────────┘四、第三阶段:建立 Zephyr SoC Port接下来正式进入 Zephyr。目录可能开始变成:soc/ └── company/ └── cx1/ ├── CMakeLists.txt ├── Kconfig ├── Kconfig.soc ├── soc.c ├── soc.h └──...这时候还不是 Board。而是:告诉 Zephyr:「这个 CPU + SoC 是什么。」例如:Company CX1 ↓ Cortex-M4 ↓ clock ↓ interrupt controller ↓ memory ↓ SoC peripherals这里对应我们之前:21SoC Port Skeleton 下面是一个完整的`soc.c`示例,它把 SoC 初始化、时钟配置和中断控制器初始化串在一起: ```c /* * soc.c - Company CX1 SoC 初始化 * * 该文件是 Zephyr SoC Port 的核心,负责在 Zephyr 内核启动前 * 完成最基本的硬件初始化,让 CPU 具备运行内核的条件。 */#include zephyr/kernel.h#include zephyr/init.h#include soc.h/* 引入 Company HAL 提供的底层接口 */#include company_clock.h#include company_irq.h/* ------------------------------------------------------------------ *1. 时钟配置 * * 目标:把 SoC 的时钟树配置到稳定状态。 * 顺序很重要:先配 PLL,再配总线分频,最后使能外设时钟。 * 如果时钟没配好,后面所有外设(UART/SPI/I2C)都无法工作。 * ------------------------------------------------------------------ */ static void soc_clock_init(void){/*1.1配置系统 PLL:输入8MHz 晶振,倍频到96MHz 主频 */ company_clock_pll_config(COMPANY_PLL_SRC_HSE,8,96);/*1.2配置总线分频:HCLK=96MHz,PCLK1=48MHz,PCLK2=96MHz */ company_clock_bus_config(COMPANY_BUS_HCLK,96);company_clock_bus_config(COMPANY_BUS_PCLK1,48);company_clock_bus_config(COMPANY_BUS_PCLK2,96);/*1.3使能基础外设时钟:GPIO、UART0、SPI0 */ company_clock_enable(COMPANY_CLOCK_GPIO);company_clock_enable(COMPANY_CLOCK_UART0);company_clock_enable(COMPANY_CLOCK_SPI0);}/* ------------------------------------------------------------------ *2. 中断控制器初始化 * * 目标:让 Zephyr 能够正确接收并分发 SoC 的中断。 * 这里只做最基础的 NVIC 配置,具体外设的 IRQ 由各 driver 自行注册。 * ------------------------------------------------------------------ */ static void soc_irq_init(void){/*2.1关闭所有外设中断,保证启动阶段处于干净状态 */ company_irq_disable_all();/*2.2设置中断优先级分组:4 位抢占优先级 +0位子优先级 */ company_irq_set_priority_group(COMPANY_IRQ_PRIO_GROUP_4);/*2.3使能全局中断(由 Zephyr 内核在启动后期统一打开, * 这里只做控制器层面的准备) */ company_irq_global_enable();}/* ------------------------------------------------------------------ *3. SoC 总初始化入口 * * 这是 Zephyr 在启动早期(PRE_KERNEL_1)调用的函数, * 必须在内核调度器运行之前完成所有基础硬件配置。 * ------------------------------------------------------------------ */ static int soc_init(void){/*3.1先配时钟:一切外设工作的前提 */ soc_clock_init();/*3.2再配中断控制器:保证后续 driver 能注册 ISR */ soc_irq_init();/*3.3最后做 SoC 级杂项初始化(如 memory protection 等) */ company_soc_lowlevel_init();return0;}/* 注册为 PRE_KERNEL_1 阶段初始化,优先级0(最早执行) */ SYS_INIT(soc_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);关键点说明:soc_clock_init():先配 PLL 再配分频,最后使能外设时钟,顺序不能颠倒;soc_irq_init():先关中断、再设优先级分组,保证启动阶段干净;SYS_INIT(..., PRE_KERNEL_1, ...):让 Zephyr 在内核启动前自动调用soc_init(),这是 SoC Port 与内核的正式接缝。22 CPU / Architecture23 Startup24 Interrupt Controller25 Clock / Reset下面是一个完整的 Devicetree 节点示例,它把 uart0、gpio0、spi0 等外设统一描述出来: ```dts / { soc { /* UART0:串口控制器,基地址 0x40000000,IRQ 5 */ uart0: uart@40000000 { compatible = "company,cx1-uart"; reg = 0x40000000 0x1000; interrupts = 5; clocks = clk 0; status = "okay"; }; /* GPIO0:通用输入输出控制器,基地址 0x40020000,IRQ 6 */ gpio0: gpio@40020000 { compatible = "company,cx1-gpio"; reg = 0x40020000 0x1000; interrupts = 6; clocks = clk 1; status = "okay"; }; /* SPI0:串行外设接口,基地址 0x40040000,IRQ 7 */ spi0: spi@40040000 { compatible = "company,cx1-spi"; reg = 0x40040000 0x1000; interrupts = 7; clocks = clk 2; status = "okay"; }; }; };对应的 binding YAML 文件内容如下:# dts/bindings/serial/company,cx1-uart.yamldescription:Company
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

论文精读与复现:用 TaoToken 统一 Key 跑通 Attention is all you need(上) 2026/9/25 19:24:00

论文精读与复现:用 TaoToken 统一 Key 跑通 Attention is all you need(上)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
Java开发MCP服务器:用TaoToken统一Key打通工具调用链路 2026/9/25 19:23:54

Java开发MCP服务器:用TaoToken统一Key打通工具调用链路

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
多协议API网关协议转换实战:Chat、Responses与Messages互转 2026/9/25 19:23:41

多协议API网关协议转换实战:Chat、Responses与Messages互转

1. 协议转换到底在解决什么问题第一次接触 micro-one-api 的协议转换功能,是因为一个很具体的报错:unexpected status 502 bad gateway: unknown error, url: http://127.0.0.1:15721/v1/responses。当时我在本地跑一个聚合网关,前端用的是 C…

阅读更多 →
Agent开发核心技术学习路线(适配大厂招聘+小白入门) 2026/9/25 19:23:41

Agent开发核心技术学习路线(适配大厂招聘+小白入门)

结合本人实际Agent开发工作经验,以及汇总整理的数十家大厂Agent开发岗位面经、招聘需求,我梳理出这份可直接落地的核心技术学习路线,帮大家避开“盲目学、学无用”的坑。 这份路线遵循“由浅入深、循序渐进”的逻辑,基本覆盖当前大…

阅读更多 →
Cline v3.1 配 TaoToken:VS Code 里替代 Cursor 和 Windsurf 的性价比之选 2026/9/25 19:23:41

Cline v3.1 配 TaoToken:VS Code 里替代 Cursor 和 Windsurf 的性价比之选

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
粮食收购管理系统落地指南:从解压部署到结算对账的避坑手册 2026/9/25 19:22:44

粮食收购管理系统落地指南:从解压部署到结算对账的避坑手册

简介:《粮食收购管理系统》是一款面向中小型粮食收购站的人工智能信息管理系统,围绕收购业务提供库存监控、采购记录、销售统计等核心功能,并通过智能预测与图像识别辅助定价决策和质量检验,帮助基层粮站实现业务流程现代化与自动…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉