版本管理机制
本文档介绍芯片模板中的版本管理体系,帮助您理解如何在多个芯片型号之间高效复用配置。
为什么需要版本管理
在芯片模板开发中,一个芯片厂商通常有多个芯片系列和型号。这些芯片的外设配置往往相似但不完全相同:
- 同一系列的芯片可能共享大部分外设配置
- 不同系列之间可能存在外设升级(如 I2C v1.0 → v2.0)
- 代码模板的优化不应影响已有的芯片配置
版本管理机制就是为了解决这些问题而设计的。
版本体系概览
芯片模板的版本管理分为两个维度:
┌─ Schema 版本(UI 配置)
│ ├── 1.0 — 基础界面
│ ├── 2.0 — 新增高级选项
│ └── 3.0 — 界面优化
│
└─ Code 版本(代码模板)
├── 1.0 — 基础代码生成
├── 2.0 — 优化代码结构
└── 3.0 — 新增 DMA 支持
目录结构中的版本
Schema 版本(UI 配置)
ips/{IP}/ui/
├── base.cjs # 基础配置(跨系列通用)
├── gd32f103.cjs # 特定系列配置(继承 base)
├── gd32f30x.cjs # 另一系列配置
└── at32f403.cjs # AT32 系列配置
Code 版本(代码模板)
ips/{IP}/code/
├── 1.0/ # 版本 1.0
│ ├── pre.cjs
│ ├── std.c.ejs
│ ├── hal.c.ejs
│ └── ll.c.ejs
├── 2.0/ # 版本 2.0
│ ├── pre.cjs
│ ├── std.c.ejs
│ ├── hal.c.ejs
│ └── ll.c.ejs
└── 3.0/ # 版本 3.0
└── ...
版本继承规则
三层优先级
配置的优先级遵循:芯片型号配置 > 特定版本配置 > 通用基础版本
芯片型号配置(最高优先级)
↓ 覆盖
特定系列版本(如 gd32f103.cjs)
↓ 覆盖
通用基础版本(如 gpio_base.cjs)
继承示例
// base.cjs — 通用基础配置
const baseFunctions = {
get_gpio_head: function() { /* 通用表头 */ },
getPinParameter: function() { /* 通用参数获取 */ }
}
// gd32f103.cjs — 特定系列继承基础配置
const { project, parameters, functions } = require('./gpio_base.cjs')
const ui = {
enable: true,
Parameter: {
label: 'Parameter',
type: 'table',
head: functions.get_gpio_head(), // 使用基础配置的通用表头
body: {}
},
NVIC: {
label: 'NVIC Settings',
// GD32F103 特有的 NVIC 面板
}
}
// 合并导出:系列特有配置覆盖基础配置
const export_functions = {
...functions,
// GD32F103 特有的函数覆盖
getDisableReson: function(alternate) {
if (!$root.isFreeByAlternate(alternate)) {
return `${alternate} is not free`
}
}
}
module.exports = Object.assign(ui, {
...project,
...export_functions
})
芯片型号的版本选择
每个芯片型号在 code.cjs 中为其外设选择对应的版本:
// chip/GD32F103XX/code.cjs
module.exports = {
ADC: {
ip_type: 'ADC',
version: '1.0' // 使用 ADC code 模板 1.0 版本
},
GPIO: {
ip_type: 'GPIO',
version: '1.0' // 使用 GPIO code 模板 1.0 版本
},
I2C: {
ip_type: 'I2C',
version: '2.0' // 使用 I2C code 模板 2.0 版本(新功能)
},
SPI: {
ip_type: 'SPI',
version: '1.0'
}
}
自由组合
不同芯片型号可以自由选择不同版本的 schema 和 code:
GD32F103ZET6:
I2C → schema v2.0, code v3.0 (高级功能 + 最新代码优化)
GD32F103C8T6:
I2C → schema v1.0, code v1.0 (基础功能,固件兼容性优先)
版本管理流程图
创建外设 I2C
│
├── schema (UI)
│ ├── 创建 v1.0 ──→ 基础参数界面
│ ├── 修改 → v2.0 ──→ 新增 DMA 面板
│ └── 修改 → v3.0 ──→ 新增错误检测面板
│
└── code (模板)
├── 创建 v1.0 ──→ 基础 HAL 代码
├── 修改 → v2.0 ──→ 新增 LL 支持
└── 修改 → v3.0 ──→ 优化代码生成逻辑
何时创建新版本 vs 修改现有版本
创建新版本(推荐)
- 新增了功能或面板
- 改变了代码生成逻辑(可能影响已有用户)
- 需要保持向后兼容性
- 固件 SDK 版本升级导致配置不兼容
修改现有版本
- 修复 Bug
- 调整默认值
- 优化注释或文档
- 不改变代码生成结果的调整
修改现有版本的风险
修改现有版本会影响所有使用该版本的芯片型号。如果是破坏性变更,必须创建新版本。
实际案例
案例:I2C 外设的版本演进
v1.0 — 基础版本
// 参数:速度模式、频率、寻址模式
v2.0 — 新增功能
// 新增:广播呼叫、时钟拉长、DMA 面板
v3.0 — 代码优化
// 优化:自动检测总线冲突、添加错误恢复逻辑
不同芯片的选择:
GD32F103 (基础系列) → I2C v1.0
GD32F30x (高级系列) → I2C v2.0
GD32E50x (最新系列) → I2C v3.0
版本命名建议
- 使用语义化版本:
1.0、1.1、2.0 - 或使用有意义的标识:
base、advanced、dma_support - 避免使用日期作为版本号
- 每个版本的变更应在文档中记录
最佳实践
- 先基础后特定:先创建通用 base 版本,再创建特定系列版本
- 向后兼容:新版本应兼容旧版本的配置(至少做到可迁移)
- 变更文档化:每个版本的变更应有清晰的文档说明
- 测试覆盖:新版本应在至少一个芯片型号上验证通过
- 渐进升级:鼓励芯片型号逐步升级到新版本,但不强制
