McuStudioMcuStudio
指南
开发者
组件
API
  • 版本发布
指南
开发者
组件
API
  • 版本发布
  • 概述
  • 快速开始
  • 添加厂商的芯片到平台
  • 芯片模板教程

    • 芯片模板开发教程
    • 创建引脚封装
    • 配置时钟树
    • 配置 GPIO 外设
    • 配置 ADC 外设
    • 配置通信外设
    • 配置 TIM 外设
  • 开发参考

    • 框架与规则
    • 芯片包结构
    • 芯片描述
    • 芯片包配置
    • 引脚配置详解
    • 外设配置详解
    • 外设元素参考
    • GPIO 开发参考
    • ADC 开发参考
    • TIM 开发参考
    • 固件库开发指南
    • 版本管理机制
    • Define 映射指南
    • 多语言(i18n)

版本管理机制

本文档介绍芯片模板中的版本管理体系,帮助您理解如何在多个芯片型号之间高效复用配置。

为什么需要版本管理

在芯片模板开发中,一个芯片厂商通常有多个芯片系列和型号。这些芯片的外设配置往往相似但不完全相同:

  • 同一系列的芯片可能共享大部分外设配置
  • 不同系列之间可能存在外设升级(如 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
  • 避免使用日期作为版本号
  • 每个版本的变更应在文档中记录

最佳实践

  1. 先基础后特定:先创建通用 base 版本,再创建特定系列版本
  2. 向后兼容:新版本应兼容旧版本的配置(至少做到可迁移)
  3. 变更文档化:每个版本的变更应有清晰的文档说明
  4. 测试覆盖:新版本应在至少一个芯片型号上验证通过
  5. 渐进升级:鼓励芯片型号逐步升级到新版本,但不强制
Prev
固件库开发指南
Next
Define 映射指南