ARMmbed/DAPLink项目:如何添加新的目标芯片家族支持

ARMmbed/DAPLink项目:如何添加新的目标芯片家族支持

前言

在嵌入式开发中,调试探针(Debug Probe)扮演着至关重要的角色。ARMmbed/DAPLink作为一个开源的调试接口固件,支持多种微控制器家族的调试和编程功能。本文将详细介绍如何在DAPLink项目中添加对新目标芯片家族的支持。

准备工作

在开始之前,需要准备以下内容:

  1. 目标芯片的数据手册
  2. 了解芯片的调试接口(SWD/JTAG)特性
  3. 熟悉芯片的Flash编程算法
  4. 掌握基本的嵌入式开发知识

添加新目标家族的核心步骤

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需要满足以下要求:

  1. 必须是位置无关代码(PIC)
  2. 包含完整的Flash操作函数
  3. 能够在目标RAM中运行
  4. 提供明确的Flash扇区信息

3. 目标配置结构

target_cfg_t结构体定义了目标设备的关键信息:

  • Flash区域配置
  • RAM区域配置
  • Flash算法指针
  • 扇区信息

开发建议

  1. 逐步验证:先实现基本功能,再逐步添加高级特性
  2. 参考现有实现:查看类似芯片的实现可以节省时间
  3. 充分测试:特别是Flash编程和安全相关功能
  4. 文档记录:详细记录芯片的特殊配置要求

常见问题解决

  1. 调试连接失败

    • 检查target_before_init_debug实现
    • 验证SWD/JTAG接口配置
  2. Flash编程失败

    • 确认Flash算法blob正确性
    • 检查扇区信息配置
    • 验证编程缓冲区大小设置
  3. 设备初始化问题

    • 确保target_init_sequence正确处理安全位
    • 验证擦除序列的正确性

总结

为DAPLink添加新的目标芯片家族支持需要实现三个核心文件:target_reset.c、flash_blob.c和target.c。每个文件都有其特定的职责,共同构成了对新芯片家族的支持。通过理解芯片的调试接口特性和Flash编程要求,开发者可以有效地扩展DAPLink的兼容性,支持更多种类的微控制器。

在实现过程中,建议采用模块化开发方法,先确保基本调试功能正常工作,再逐步实现Flash编程等高级特性。同时,充分利用现有芯片家族的实现作为参考,可以大大提高开发效率。

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值