# PySVDAssistant **Repository Path**: thostones/py-svdassistant ## Basic Information - **Project Name**: PySVDAssistant - **Description**: PySVDAssistant 是一个处理 XLSX 文件并生成Keil SVD 字符串的 Python 脚本,该字符串随后将保存到指定的输出文件中。该脚本可以处理单个 XLSX 文件以及包含多个 XLSX 文件的目录。 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 3 - **Forks**: 0 - **Created**: 2024-08-05 - **Last Updated**: 2025-10-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # PySVDAssistant ## 说明 `PySVDAssistant` 是一个根据.xlsx文件内容并生成.svd文件的工具。该脚本可以处理单个.xlsx文件以及包含多个.xlsx文件的目录。 ## PySVDAssistant 使用说明 ### 使用方法 ```cmd PySVDAssistant Version:0.3.0 py Usage: python PySVDAssistant.py [Options] [input xlsx paths or files...] exe Usage: PySVDAssistant.exe [Options] [input xlsx paths or files...] Options: -SVDOut=SVDOutPutDirPath Specify the output dir path of SVD file (default: ./) -RTLOut=RTLOutPutDirPath Specify the output dir path of RTL file (default: ./) -DisableSVD Disable SVD Conversion -DisableRTL Disable RTL Conversion ``` ### 注意事项 - 该脚本至少需要一个输入路径才能正常工作。如果未提供输入路径,将默认使用当前目录。 - 脚本会检查指定路径中是否存在 XLSX 文件。如果未找到 XLSX 文件,将显示错误信息,并且脚本将退出。 ### 错误处理 该脚本包括以下场景的错误检查: 1. 未指定输入路径。 2. 在指定路径中未找到 XLSX 文件。 3. 从 Excel 文件中提取信息失败。 4. 生成 SVD 字符串失败。 如果发生错误,将显示适当的错误信息,脚本将以非零状态码退出。 ### 退出代码 - `0` : 执行成功 - `1` : 未指定输入路径 - `2` : 获取 SVD 信息失败 - `3` : 生成 SVD 字符串失败 ### 文件夹结构 1. Install, python脚本运行的准备工作 2. SVDClasses, SVD数据结构类的定义 3. ExcelAPI, 从excel读取数据和转化的API 4. Docs, 用于保存Readme中需要的文件 5. Test, 用于测试 ## python环境准备 如直接运行exe请忽略本节。 ### 在线安装 直接运行 ```cmd pip install -r ./Install/packagelist.cfg ``` ### 离线安装 #### 下载 通常所需的 Python 包已经下载并保存在 `./Install/package` 文件夹中。 如果没有,您可以进入 `./Install` 文件夹并运行下载脚本,这将重新下载必要的包到 `./Install/package` 文件夹中。 具体命令如下: ```cmd cd Install python download.py ``` #### 安装 一旦确认包已经准备好,或者 `download.py` 的执行已成功完成,您可以使用以下命令进行安装: ```cmd python install.py ``` ## 脚本执行前的准备工作 ### 一个文件夹 这个文件夹用于存放所有的xlxs文件。这个文件夹的路径会被作为工具脚本运行的唯一输入参数。 ### Excel文件和Sheets 这个工具脚本被设计用于从后缀为xlsx的excel文件中读取数据,并转化为Keil package的SVD文件。其它格式没有被格式过。 它主要依赖Sheet的名称和内容,并不要求sheets必须在同一个excel文件中,这样可以方便团队协作,分散撰写不同的sheet。 外设以外的Sheets固定包括"DEVICE","CPU","PERIPHERALS"。 ### 注意:xlsx文件所有内容不要有全角字符不要有汉字,否则SVDCovn会出错。 如果生成或安装PACK包时报错,大概率是SVD文件中包含非法字符,请检查生成的SVD文件,根据SVD文件问题修改xlsx文件 #### "DEVICE" Sheet Sheet名称必须是"DEVICE”,用于保存SVD中Device的属性信息,表头必须和下面一致: | name | description | version | addressUnitBits | width | size | resetValue | resetMask | | ---- | ----------- | ------- | --------------- | ----- | ---- | ---------- | --------- | 其中,各属性名称和SVD文件的字段要求一致,需要进一步了解请参考SVD文件说明,这里不进行赘述。第二行是对应属性的值。 #### "CPU" Sheet Sheet名称必须是"CPU,用于保存SVD中CPU的属性信息,表头必须和下面一致: | name | revision | endian | mpuPresent | fpuPresent | nvicPrioBits | vendorSystickConfig | | ---- | -------- | ------ | ---------- | ---------- | ------------ | ------------------- | 其中,各属性名称和SVD文件的字段要求一致,需要进一步了解请参考SVD文件说明,这里不进行赘述。第二行是对应属性的值。 #### "PERIPHERALS" Sheet Sheet名称必须是"PERIPHERALS",用于保存SVD中外设的属性信息,表头必须为: ***name, groupName, sheetName, headerStructName, baseAddress, offset, size , description, interrupt, int_name, int_description*** 表格的内容只是示例: | name | groupName | sheetName | headerStructName | baseAddress | offset | size | description | interrupt | int_name | int_description | | ---- | --------- | --------- | ---------------- | ----------- | ------ | ------ | ----------- | --------- | ---------- | --------------- | | TIM0 | Timer | TIMER0 | TIM16 | 0x40007000 | 0x0 | 0x1000 | 16bit Timer | 7 | | | | TIM1 | Timer | TIMER1 | TIM16 | 0x40008000 | 0x0 | 0x1000 | 16bit Timer | 8 | | | | TIM2 | Timer | TIMER2 | TIM32 | 0x40009000 | 0x0 | 0x1000 | 32bit Timer | 9 | | | | DMA | DMA | DMA | DMA | 0x4000A000 | 0x0 | 0x1000 | DMA | 10 | DMA_finish | | | DMA | | | | | | | | 11 | | half finish | | | | | | | | | | 12 | | | 其中,第二行是对应属性的值。 表头里name、groupName、headerStructName、baseAddress、offset、size、description等和SVD文件的字段要求一致,需要进一步了解请参考SVD文件说明,这里不进行赘述。 其它sheet说明: **sheetName**:对应外设Sheet名称中这个外设的名称,相当于是一个别名。在上面的例子里面,工具认为sheet名称中包含“TIMER0”的sheet是用来描述TIM0的,以此类推。 **headerStructName**:属性意义和SVD相关要求一致。这里要说明的是,工具会把所有具有同一headerStructName的外设信息进行排列,在第一位的外设会进行详细描述并不会具有headerStructName这个属性,后面的外设会具有headerStructName,以及具有个性化的一些属性比如bassAddress等,其它共性的属性并不会被详细描述比如Registers等。 **interrupt, int_name, nt_description**:对应SVD文件中Inerrupt block中的中断信息。上表中DMA的中断信息SVD为: ```xml DMA_finish 10 DMA_2 11 DMA_3 12 half finish ``` 注意,需要录入多中断的外设(name),第一次出现这个外设的信息必须是完整的,后续再出现这个外设中断信息之外的信息是不会被录入的;连续登记中断信息的行,“interrupt”字段是必须的;如果“name”字段为空,则认为当前中断信息要注册在刚被识别到的外设信息中。 #### 外设Sheet 单个外设的信息需要由两个Sheet(**MAP**和**DETAL**)组成,分别是**外设名称_MAP**和**外设名称_DETAL**,比如***TIMER0_MAP***和***TIMER0_DETAIL***。 ##### MAP MAP sheet保存的是外设的概要信息。Sheet名称必须是外设的名称(*PERIPHERALS* Sheet中*sheetName*列中的名称)+"MAP",用于保存SVD中外设的属性信息,表头必须和下面一致: | addressOffset | name | resetValue | description | dim | dimIncrement | dimIndex | | ------------- | ---- | ---------- | ----------- | --- | ------------ | -------- | 其中,各属性名称和SVD文件的字段要求一致,需要进一步了解请参考SVD文件说明,这里不进行赘述。 以下各行是对应外设的信息。 ##### DETAIL DETAIL sheet保存的是外设的寄存器的详细信息。Sheet名称必须是外设的名称(*PERIPHERALS* Sheet中*sheetName*列中的名称)+"DETAL",用于保存SVD中外设的属性信息,表头必须和下面一致: | regname | name | msb | lsb | access | description | headerEnumName | enumValueName | enumValue | enumDescription | modifiedWriteValues | writeConstraint | readAction | | ------- | ---- | --- | --- | ------ | ----------- | -------------- | ------------- | --------- | --------------- | ------------------- | --------------- | ---------- | 其中,"name"、“msb”、“lsb”、"access"、"description"、"modifiedWriteValues"、"readAction"名称和SVD文件中Field各字段要求一致,需要进一步了解请参考SVD文件说明,这里不进行赘述。参考链接: 以下字段需要注意: ##### regname Field所属的寄存器名称,需要与MAP页面一致。 ##### access"字段 大小写不敏感。目前只接受这些字段"RO","read-only","WO":"write-only","RW"(或“RW”):"read-write"。其中"RO"是"read-only"的缩写,"WO"是"write-only"的缩写,"RW"是"read-write"的缩写。若识别到其它值,脚本运行时会报错。 ##### headerEnumName,enumValueName,enumValue,enumDescription 有以下字段用于描述枚举类型: **headerEnumName**:枚举C语言struct类型名称 **enumValueName**:枚举值名称 **enumValue**:枚举值 **enumDescription**:枚举值的描述 如果一个Field中不包含枚举类型,则"headerEnumName"需要不填写,其后的"enumValueName"、"enumValue"、"enumDescription"填写也会被忽略。 如果一个Field中包含枚举类型需要,那么用连续多行进行说明,每一行通过"enumValueName"、"enumValue"、"enumDescription"描述一个enumValue。 对这样的连续多行: 1. 其中第一行的"name"、"access"、"description"、"enumValue"应该进行详细描述。 2. 其余行的"name"字段可以为空或和第一行保持一致。 3. 其余行的"access"、"description"、"headerEnumName"等这些部分都以第一行为准,不再读取其余行的相关内容。 举例如下: | name | access | description | headerEnumName | enumValueName | enumValue | enumDescription | | ----------- | ------ | ------------------------------------------ | -------------- | ------------- | --------- | --------------- | | GreatStatus | RW | Overflow interrupt enables the controller. | Great | NoGreat | 0 | | | | | | | Normal | 1 | | | | | | | Great | 2 | | | | | | | SuperGreat | 3 | | | BadStatus | RO | Overflow interrupt flag. | Bad | NoBad | 0 | | | BadStatus | RO | Overflow interrupt flag. | Bad | Bad | 1 | | | BadStatus | RO | Overflow interrupt flag. | Bad | SuperBad | 3 | | ##### writeConstraint 允许输入“enumDescription”,“writeAsRead”和“range[A-B]”,如需输入多类约束,需要用','连接如:“enumDescription,writeAsRead,range[1-5]” 参考链接: ###### enumDescription 转化为 ```xml ... true ... ``` ###### writeAsRead 转化为 ```xml ... true ... ``` ###### range[A-B] 转化为 ```xml ... A B ... ```