模板
芯片模板目录结构
├── chip/ # 芯片配置
│ └── {系列}/ # 如 GD32F103XX
│ ├── code.cjs # IP 类型到模板版本映射
│ ├── define.cjs # 系列级寄存器宏定义
│ ├── ide.cjs # IDE 平台配置
│ └── {型号}/ # 如 GD32F103ZET6
│ ├── info.cjs # 芯片元数据(Flash/RAM/IO/外设列表)
│ ├── pins.cjs # 引脚复用功能映射
│ ├── nvic.cjs # 中断向量表定义
│ ├── dma.cjs # DMA 通道映射
│ └── ui.cjs # 图形化配置 UI
├── ips/ # 外设模板
│ └── {IP}/ # 如 GPIO、ADC、SPI
│ ├── ui/ # UI 配置
│ │ ├── base.cjs # 基础配置(project/parameters/modes/signals/functions)
│ │ └── {系列}.cjs # 系列特定配置(继承 base)
│ └── code/ # 代码模板
│ └── {版本}/ # 如 1.0
│ ├── pre.cjs # 数据预处理(代码生成入口)
│ ├── std.c.ejs # Standard 固件 C 代码模板
│ ├── hal.c.ejs # HAL 固件 C 代码模板
│ └── ll.c.ejs # LL 固件 C 代码模板
├── common/ # 通用模板
│ ├── define.cjs # 全局寄存器宏映射
│ ├── gpio/ # GPIO 通用模板
│ ├── dma/ # DMA 通用模板
│ └── nvic/ # NVIC 通用模板
└── package.json
芯片配置
系列级(chip/{系列}/)
code.cjs — IP 版本映射
指定该系列各个外设使用的代码模板版本:
module.exports = {
ADC: { ip_type: 'ADC', version: '1.0' },
GPIO: { ip_type: 'GPIO', version: '1.0' },
SPI: { ip_type: 'SPI', version: '1.0' },
TIM: { ip_type: 'TIM', version: '1.0' }
}
ip_type:外设类型,对应ips/目录名version:使用的 code 模板版本,对应ips/{IP}/code/{version}/
ide.cjs — IDE 配置
module.exports = {
keil: { device: 'GD32F103ZE', cpu: 'Cortex-M3' },
iar: { device: 'GD32F103ZE', cpu: 'Cortex-M3' },
cmake: { toolchain: 'arm-none-eabi-gcc' }
}
define.cjs — 系列寄存器宏
module.exports = {
// 系列特有的寄存器宏映射,覆盖 common/define.cjs
}
型号级(chip/{系列}/{型号}/)
info.cjs — 芯片元数据
module.exports = {
name: 'GD32F103ZET6',
series: 'GD32F103XX',
flash: 512, // KB
ram: 64, // KB
io: 112, // IO 口数量
package: 'LQFP144',
ips: [ // 外设实例列表
{ name: 'ADC', max: 3 },
{ name: 'GPIO', max: 1 },
{ name: 'SPI', max: 3 },
{ name: 'TIM', max: 8 },
{ name: 'USART', max: 5 }
]
}
pins.cjs — 引脚定义
module.exports = [
{
name: 'PA0',
port: 'GPIOA',
pin: 'GPIO_PIN_0',
af: [
{ name: 'USART1_TX', value: 'GPIO_ALTERNATE_USART1_TX' },
{ name: 'TIM2_CH1', value: 'GPIO_REMAP_TIM2_CH1' }
]
}
]
nvic.cjs — 中断定义
module.exports = {
USART0_IRQn: {
label: 'USART0 global interrupt',
ip_names: ['USART0'] // 关联 info.cjs 中的外设实例
},
ADC0_1_IRQn: {
label: 'ADC0 and ADC1 interrupt',
ip_names: ['ADC0', 'ADC1'] // 多个 IP 共享一个中断
}
}
dma.cjs — DMA 通道
module.exports = {
USART0_TX: {},
USART0_RX: {},
ADC0: {},
SPI0_TX: {}
}
外设模板
外设模板位于 ips/{IP}/,分为 UI 配置和代码模板两部分。
UI 配置(ips/{IP}/ui/)
UI 配置文件导出以下节点:
project — 项目配置
project: {
generate_code: { value: true, fixed: false },
rank: { value: 2, fixed: true },
function_name: { value: 'Studio_GPIO_Init' },
firmware: {
value: 'std',
options: [
{ label: 'Standard', value: 'std' },
{ label: 'HAL', value: 'hal' },
{ label: 'LL', value: 'll' }
]
},
file_name: 'gpio',
ip_type: 'GPIO'
}
| 属性 | 说明 |
|---|---|
generate_code | 是否生成代码 |
rank | 初始化顺序(数值越小越先初始化) |
function_name | 生成的初始化函数名 |
firmware | 支持的固件类型 |
file_name | 生成的文件名(不含扩展名) |
ip_type | 外设类型 |
parameters — 参数配置
定义外设的可配置参数:
parameters: {
BaudRate: {
label: 'Baud Rate',
type: 'input',
value: '115200'
},
Mode: {
label: 'Mode',
type: 'select',
value: 'asynchronous',
options: [
{ label: 'Asynchronous', value: 'asynchronous',
signals: ['TX', 'RX'] }
]
}
}
modes — 工作模式
Mode 参数定义在外设的 modes 节点中(而非 parameters)。每个选项通过 signals 数组声明所需引脚,disable 表示禁用:
modes: {
Mode: {
value: 'disable',
options: [
{ label: 'Disable', value: 'disable' },
{ label: 'Asynchronous', value: 'asynchronous',
signals: ['TX', 'RX'] },
{ label: 'Synchronous', value: 'synchronous',
signals: ['TX', 'RX', 'CK'] },
{ label: 'Single Wire', value: 'single_wire',
signals: ['TX'] }
]
}
}
signals — 引脚信号定义
signals: {
TX: { mode: 'AF_PP', pull: 'NOPULL', speed: 'High', level: 'NA' },
RX: { mode: 'AF_PP', pull: 'NOPULL', speed: 'High', level: 'NA' },
CK: { mode: 'AF_PP', pull: 'NOPULL', speed: 'High', level: 'NA' }
}
系统根据 Mode 选项的 signals 数组自动查找并分配对应引脚。
functions — 功能函数
functions: {
// 外设使能判断(Mode !== 'disable' 时可用)
enabled: () => {
return $root.Mode.value !== 'disable'
},
// 配置项变化回调
on__change: (params) => {
// params.id — 变化的节点 key
// params.value — 变化后的值
// params.path — 元素路径(如 'USART1.Parameter.BaudRate')
}
}
代码模板(ips/{IP}/code/{版本}/)
pre.cjs — 数据预处理入口
module.exports = ({ ip, ide, locals }) => {
// ip — 当前外设的配置数据
// locals — 全局上下文(defineMap 等)
// 在此处理数据,准备传递给 EJS 模板
}
EJS 模板(*.ejs)
根据固件类型分为:
std.c.ejs— Standard 固件代码模板hal.c.ejs— HAL 固件代码模板ll.c.ejs— LL 固件代码模板
void <%= ip.function_name.value %>(void) {
// 模板引擎将变量替换为实际值
}
