Arm DS自定义组件XML配置与调试技巧
1. 自定义组件XML文件在Arm DS配置数据库中的应用场景
在嵌入式开发过程中,我们经常会遇到Arm Development Studio调试器无法自动识别目标板上某些自定义组件的情况。这种情况特别常见于使用定制化CoreSight组件或修改版处理器核心的项目中。当标准组件库中没有包含我们使用的特定硬件时,调试器就无法正确建立调试会话,这会给开发工作带来很大困扰。
我曾经在一个基于Cortex-M7的项目中就遇到过类似问题。客户使用了一个经过深度定制的性能监测单元(PMU),调试器始终无法识别这个组件。通过创建自定义components.xml文件并添加到配置数据库中,我们成功解决了这个问题。这种方法不仅适用于PMU,对于任何CoreSight组件、处理器核心或自定义外设都同样有效。
2. 准备工作与组件信息收集
2.1 获取组件的拓扑信息
在开始创建自定义组件定义前,必须从组件的技术参考手册(TRM)或用户指南中收集以下关键信息:
- 组件ID(part_id):包括PID(Part ID)和DEVTYPE(Device Type)等识别码
- 组件名称和描述信息
- 组件使用的模板(如果有)
- 设备特性列表(如支持的跟踪功能、版本号等)
- 拓扑连接信息(ATB、CTI等接口配置)
以CoreSight ETM(嵌入式跟踪宏单元)为例,我们需要记录它的版本号、支持的跟踪功能、上下文ID支持情况等。这些信息通常可以在"Debug and Trace"章节的寄存器描述部分找到。
2.2 理解components.xml文件结构
Arm Development Studio提供的components_v1.1.xsd模式文件定义了components.xml的结构。这个模式文件非常重要,它规定了哪些元素是必需的,哪些是可选的,以及它们之间的关系。在开始编写前,建议先仔细阅读这个模式文件。
关键元素包括:
<part>:定义一个组件<part_id>:包含组件的识别信息<name>和<description>:组件的名称和描述<uses_template>:指定组件基于的模板<device_info_list>:列出组件的特性和能力<topology_info>:定义组件在CoreSight拓扑中的连接方式
3. 创建和添加自定义组件XML文件
3.1 建立组件目录结构
在现有的自定义配置数据库目录中,需要创建一个新的Components目录。这个目录必须与Boards目录位于同一层级。例如:
MyCustomDatabase/ ├── Boards/ ├── Components/ │ └── components.xml └── ...这种目录结构是Arm Development Studio的硬性要求,不遵循这个结构会导致数据库重建失败。
3.2 编写components.xml文件
创建一个新的components.xml文件并添加到Components目录中。文件的基本结构如下:
<?xml version="1.0" encoding="UTF-8"?> <components xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="components_v1.1.xsd"> <!-- 在这里添加你的组件定义 --> </components>在文件中添加你的自定义组件定义。可以参考随附的sample_components_xml_file.xml示例文件,它包含了多种组件的定义方式。
3.3 组件定义示例解析
3.3.1 定义一个新的CoreSight PMU
<part> <part_id> <pid>0x9D7</pid> <devtype>0x16</devtype> </part_id> <name>CSPMU</name> <description>New CoreSight PMU</description> </part>这个例子定义了一个新的CoreSight性能监测单元(PMU)。<pid>和<devtype>必须与硬件实际使用的ID匹配,否则调试器无法识别。
3.3.2 基于现有模板创建新组件
<part> <part_id> <pid>0x999</pid> <devtype>0x16</devtype> </part_id> <name>MyNewPart</name> <description>New part based on PMU</description> <uses_template>CSPMU</uses_template> </part>这个组件基于之前定义的CSPMU模板创建,通过<uses_template>元素指定。这种方式适合创建与现有组件功能相似但ID不同的变体。
3.3.3 定义一个新的处理器核心
<core> <part_id> <pid>0xD00</pid> <devarch>0x8A15</devarch> <devtype>0x15</devtype> </part_id> <name>MyNewCore</name> <description>New Core Type</description> <uses_template>V8-Generic</uses_template> <core_definition>MyNewCoreDefinition</core_definition> <architecture>ARMv8-A</architecture> <mp supported="true"/> </core>处理器核心的定义使用<core>元素而非<part>,并且包含架构和多核支持等特定信息。
4. 配置数据库的更新与使用
4.1 更新配置数据库
创建好components.xml文件后,需要在Development Studio中更新配置数据库:
- 打开配置数据库对话框:Windows → Preferences → Arm DS → Configuration Database
- 确保你的自定义配置数据库已列出并被选中
- 点击"Rebuild Database"按钮重建数据库
- 点击"Apply and Close"保存更改
重建过程会解析所有组件定义并更新内部数据库。如果components.xml中有语法错误,重建会失败并显示错误信息。
4.2 使用自定义组件进行自动检测
如果自定义组件基于标准定义并包含正确的<part_id>信息,它可以被自动检测到:
- 打开平台配置编辑器(PCE):File → New → Other → Configuration Database → Platform Configuration
- 选择"Advanced platform detection or manual creation"
- 选择连接到平台的调试探头
- 调试器会自动检测平台和所有组件
- 选择保存平台并开始调试会话或进一步检查
4.3 手动添加自定义组件
对于不基于标准定义的组件,需要手动添加到平台:
- 创建一个新的平台配置
- 在平台配置编辑器中打开新建的.sdf文件
- 在Devices面板中找到你的自定义组件
- 将其拖放到主面板中
- 保存更改(CTRL+S)
5. 高级组件定义技巧
5.1 定义复杂的CoreSight组件
对于像ETM这样的复杂CoreSight组件,需要详细定义其特性和拓扑连接:
<part> <part_id> <pid>0x9B6</pid> <devtype>0x13</devtype> </part_id> <name>CSETM</name> <description>My CoreSight Embedded Trace Macrocell</description> <device_info_list> <device_info name="VERSION" description="ETM Version" type="string" value="4.0"> <option>3.3</option> <option>3.4</option> <option>3.5</option> <option>4.0</option> <option>4.1</option> <option>4.2</option> <option>4.3</option> <option>4.4</option> <option>4.5</option> </device_info> <!-- 其他特性定义 --> </device_info_list> <topology_info> <atb_link position="master" minSlaves="1" numMasterInterfaces="1"/> <core_trace_link position="slave" minMasters="1" maxMasters="1"/> <cti_link position="master" minSlaves="0" maxSlaves="1" devices="CSCTI"/> </topology_info> </part><device_info_list>定义了组件的各种能力,而<topology_info>则描述了它如何连接到CoreSight拓扑中。
5.2 使用模板继承功能
通过<uses_template>元素,可以基于现有组件创建新组件,继承其大部分特性:
<part> <part_id> <pid>0x9A1</pid> <devtype>0x16</devtype> </part_id> <name>MyEnhancedPMU</name> <description>Enhanced PMU with additional features</description> <uses_template>CSPMU</uses_template> <device_info_list> <device_info name="EXTRA_FEATURE" description="Additional feature" type="bool" value="True"/> </device_info_list> </part>这种方式可以减少重复定义,只需指定与模板不同的部分。
6. 常见问题与解决方案
6.1 组件无法被识别
问题现象:自定义组件已定义但调试器无法识别。
可能原因及解决方案:
<part_id>不匹配:检查硬件实际使用的PID和DEVTYPE,确保与定义一致- 数据库未重建:在修改components.xml后必须重建数据库
- 文件位置错误:确保components.xml位于正确的Components目录中
- XML语法错误:使用XML验证工具检查文件格式
6.2 数据库重建失败
问题现象:点击"Rebuild Database"时出现错误。
排查步骤:
- 检查Development Studio的错误日志
- 验证components.xml是否符合提供的schema
- 确保所有引用的模板都存在
- 检查XML中的特殊字符是否正确转义
6.3 平台配置编辑器不显示自定义组件
解决方案:
- 确认组件定义在正确的配置数据库中
- 检查平台配置使用的数据库是否正确
- 尝试完全关闭并重新打开Development Studio
7. 实际应用经验分享
在实际项目中,我发现以下几点特别值得注意:
版本控制:将components.xml和整个配置数据库纳入版本控制系统。这样可以在团队成员间共享自定义组件定义,并跟踪变更历史。
模块化组织:对于包含大量自定义组件的项目,可以考虑将组件定义拆分到多个XML文件中,然后使用XML包含机制组合它们。
文档注释:在XML中添加详细的注释,说明每个组件的来源、用途和特殊注意事项。这在几个月后需要修改时会非常有帮助。
测试策略:创建一个小型测试平台配置,专门用于验证新定义的组件。这样可以快速迭代而不影响主项目。
性能考虑:当定义大量组件时,数据库重建可能变慢。在这种情况下,可以考虑维护一个开发数据库和一个精简的生产数据库。
