ARMmbed/DAPLink项目:如何添加新的目标芯片家族支持
前言
在嵌入式开发中,调试探针(Debug Probe)扮演着至关重要的角色。ARMmbed/DAPLink作为一个开源的调试接口固件,支持多种微控制器家族的调试和编程功能。本文将详细介绍如何在DAPLink项目中添加对新目标芯片家族的支持。
准备工作
在开始之前,需要准备以下内容:
- 目标芯片的数据手册
- 了解芯片的调试接口(SWD/JTAG)特性
- 熟悉芯片的Flash编程算法
- 掌握基本的嵌入式开发知识
添加新目标家族的核心步骤
1. 创建目标家族目录结构
在DAPLink项目中,每个目标芯片家族都有自己独立的目录结构,通常位于:
source/family/<制造商>/<目标芯片名>
2. 实现目标重置功能(target_reset.c)
这是必须实现的核心文件之一,主要包含以下关键功能:
#include "target_reset.h"
#include "swd_host.h"
#include "target_family.h"
// 调试初始化前的准备工作
static void target_before_init_debug(void)
{
// 可在此处添加JTAG/SWD连接前的特定序列
}
// 设备初始化序列
static uint8_t target_init_sequence(void)
{
// 实现Flash安全擦除逻辑
return 1; // 返回1表示成功
}
// 设置目标状态
static uint8_t target_set_state(TARGET_RESET_STATE state)
{
// 自定义状态机实现
return 1;
}
// 检查安全位设置
static uint8_t security_bits_set(uint32_t addr, uint8_t *data, uint32_t size)
{
// 检查编程数据是否设置了安全位
return 0; // 返回0表示未设置安全位
}
// 目标家族描述符
const target_family_descriptor_t g_target_family = {
.version = kTargetFamilyVersion,
.family_id = myFamilyID, // 自定义家族ID
.default_reset_type = kHardwareReset,
.target_before_init_debug = target_before_init_debug,
.target_init_sequence = target_init_sequence,
.target_set_state = target_set_state,
.security_bits_set = security_bits_set,
};
3. 创建Flash算法blob(flash_blob.c)
Flash算法是用于编程目标MCU内部(或外部)Flash存储器的关键组件。它包含位置无关的函数,用于擦除、读取和写入Flash控制器。
#include "flash_blob.h"
// Flash算法二进制数据
static const uint32_t targetname_blob[] = {
0xE00ABE00, /* ... */, 0x00000000,
};
// Flash扇区信息
static const sector_info_t sectors_info[] = {
{0x00000000, 0x00001000}, // 起始地址和扇区大小
};
// 编程目标结构体
static const program_target_t flash = {
0x200000B5, // Init函数地址
0x2000029D, // UnInit函数地址
0x20000029, // EraseChip函数地址
0x20000061, // EraseSector函数地址
0x20000121, // ProgramPage函数地址
// 调试相关指针
{
0x20000000 + 0x00000001, // BKPT
0x20000000 + 0x00000020 + 0x00000290, // RSB
0x20000800 // RSP
},
0x20000000 + 0x00000A00, // 内存缓冲区位置
0x20000000, // 在目标RAM中写入prog_blob的位置
sizeof(targetname_blob), // prog_blob大小
targetname_blob, // prog_blob地址
0x00000200 // 最大编程页面大小
};
4. 实现目标MCU描述文件(target.c)
此文件包含关于ROM大小、RAM大小以及在拖放编程期间需要对目标MCU执行的扇区操作的信息。
#include "target_config.h"
#include "flash_blob.c" // 注意:flash_blob.c只应在target.c中包含
// 目标设备配置
target_cfg_t target_device = {
.version = kTargetConfigVersion,
.sectors_info = sectors_info,
.sector_info_length = (sizeof(sectors_info))/(sizeof(sector_info_t)),
.flash_regions[0].start = 0x00000000, // Flash起始地址
.flash_regions[0].end = 0x00200000, // Flash结束地址
.flash_regions[0].flags = kRegionIsDefault,
.flash_regions[0].flash_algo = (program_target_t *) &flash,
.ram_regions[0].start = 0x1fff0000, // RAM起始地址
.ram_regions[0].end = 0x20030000, // RAM结束地址
};
关键概念解析
1. 目标家族ID
目标家族ID是制造商ID和递增ID的组合。DAPLink提供了一些预定义的家族ID存根,可用于通用重置类型:
- kStub_HWReset_FamilyID:硬件重置
- kStub_SWVectReset_FamilyID:软件向量重置
- kStub_SWSysReset_FamilyID:软件系统重置
2. Flash算法blob
Flash算法blob需要满足以下要求:
- 必须是位置无关代码(PIC)
- 包含完整的Flash操作函数
- 能够在目标RAM中运行
- 提供明确的Flash扇区信息
3. 目标配置结构
target_cfg_t结构体定义了目标设备的关键信息:
- Flash区域配置
- RAM区域配置
- Flash算法指针
- 扇区信息
开发建议
- 逐步验证:先实现基本功能,再逐步添加高级特性
- 参考现有实现:查看类似芯片的实现可以节省时间
- 充分测试:特别是Flash编程和安全相关功能
- 文档记录:详细记录芯片的特殊配置要求
常见问题解决
-
调试连接失败:
- 检查target_before_init_debug实现
- 验证SWD/JTAG接口配置
-
Flash编程失败:
- 确认Flash算法blob正确性
- 检查扇区信息配置
- 验证编程缓冲区大小设置
-
设备初始化问题:
- 确保target_init_sequence正确处理安全位
- 验证擦除序列的正确性
总结
为DAPLink添加新的目标芯片家族支持需要实现三个核心文件:target_reset.c、flash_blob.c和target.c。每个文件都有其特定的职责,共同构成了对新芯片家族的支持。通过理解芯片的调试接口特性和Flash编程要求,开发者可以有效地扩展DAPLink的兼容性,支持更多种类的微控制器。
在实现过程中,建议采用模块化开发方法,先确保基本调试功能正常工作,再逐步实现Flash编程等高级特性。同时,充分利用现有芯片家族的实现作为参考,可以大大提高开发效率。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



