emXCP 目标机库集成

本文档说明如何在目标机(MCU)应用程序中集成 emXCP 库,实现与 EmeyeStudio 的 XCP 通信。


一、核心原则

emXCP 库专为裸机/轻量级 RTOS 嵌入式平台设计,采用静态内存架构:

  • 库不内部分配任何内存:所有运行时缓冲区由用户外部提供
  • 用户传入缓冲区,库自动适配:通过 emeye_xcp_init(pBuffer, size) 传入内存
  • 不支持动态内存分配:不可使用 malloc/free

二、集成步骤

步骤 1:分配内存

根据 MCU 的内存映射,分配一段连续的物理内存(RAM)用于 emXCP 库的 Recorder 缓冲区:

// 根据 MCU 内存映射分配
#define EMXCP_BUFFER_ADDR    0x20002000   // 符合 MCU RAM 地址范围
#define EMXCP_BUFFER_SIZE    (16 * 1024)  // 16KB,可根据 RAM 余量调整

注意:地址必须在 MCU 合法地址空间内,需按 4 字节对齐。

步骤 2:初始化 emXCP

在程序初始化阶段,调用 emeye_xcp_init

#include "emXcp.h"

void user_init(void)
{
    // 传入缓冲区地址和大小
    emeye_xcp_init((char*)EMXCP_BUFFER_ADDR, EMXCP_BUFFER_SIZE);

    // 设置中断周期(影响采样点数计算)
    emeye_xcp_set_irq(1, 0);  // 1ms 中断周期
}

步骤 3:周期调用中断处理

在定时器中断或主循环中,周期调用 emeye_xcp_irq_handler

// 在 1ms 定时器中断中调用
void timer_isr(void)
{
    emeye_xcp_irq_handler();
}

emeye_xcp_irq_handler 内部按优先级处理三种模式:

  1. Recorder 模式(最高优先级):启用时独占 IRQ
  2. Power-on Recorder 模式:仅在 RECORDING/UPLOAD 活跃状态时独占 IRQ
  3. Scope 模式:处理 Channel 0 的 DAQ 采样和发送

三、缓冲区大小与自适应模式

emXCP 库根据用户传入的缓冲区大小,自动选择采集模式:

缓冲区大小 自适应模式 批量发送帧数 适用场景
≥ 64KB 大容量模式 16 高频采集、多通道数据
8KB ~ 64KB 中等模式 8 平衡采集频率和数据量
< 8KB(最小 512 字节) 最小模式 4 低频率、小数据量采集

用户无需关心模式选择,只需根据 RAM 余量分配尽可能大的缓冲区即可。


四、缓冲区大小估算

缓冲区大小 ≈ (预触发点数 + 后触发点数) × 单次采样字节数

其中:
- 单次采样字节数 = 所有变量大小之和(如 8 个 uint32 变量 = 32 字节)
- 预触发点数 = 预触发时长(ms) × 采样率(Hz) / 1000
- 后触发点数 = 后触发时长(ms) × 采样率(Hz) / 1000

示例计算

8 个 uint32 变量,1ms 采样周期,录制 200ms(前 50ms + 后 150ms):

  • 单次采样 = 32 字节
  • 预触发 = 50 × 1000 / 1000 = 50 点
  • 后触发 = 150 × 1000 / 1000 = 150 点
  • 缓冲区 ≈ (50 + 150) × 32 = 6400 字节 ≈ 6.4KB

五、内存要求

  • 缓冲区必须是物理连续内存,不可分散分配
  • 地址必须在 MCU 合法地址空间内
  • 地址需按 4 字节对齐(避免内存访问异常)
  • 缓冲区必须在整个程序运行期间保持有效
  • emXCP 库不支持动态内存分配,不可使用 malloc/free

六、支持的内存类型

emXCP 库不区分存储介质,只要是合法物理地址即可:

  • RAM:推荐用于运行时高速采集(读写速度快)
  • FLASH:适合离线记录、掉电保存日志(需用户提供 FLASH 读写驱动)

七、注意事项

  1. 不传入缓冲区:如果 emeye_xcp_init(NULL, 0) 不传入缓冲区,Recorder 功能不可用,但 Scope/Watch 等其他 XCP 功能仍正常工作

  2. 多线程/中断场景:需保证 Recorder 相关接口的调用互斥,避免内存访问冲突

  3. 地址翻译:上位机解析 ELF 文件获取的变量地址即为 MCU 真实物理地址,无需翻译


八、API 参考

初始化 API

API 说明
emeye_xcp_init(pBuffer, size) 初始化 emXCP 库,传入 Recorder 缓冲区
emeye_xcp_set_irq(ms, us) 设置中断周期
emeye_xcp_irq_handler() 中断处理函数,需周期调用

缓冲区参数建议

参数 最小值 推荐值 说明
缓冲区大小 512 字节 8KB ~ 512KB 根据 RAM 余量和录制需求调整
缓冲区对齐 4 字节 32 字节 避免内存访问异常,Cache 友好

九、完整集成示例

#include "emXcp.h"

// 1. 根据 MCU 内存映射分配缓冲区
#define EMXCP_BUFFER_ADDR    0x20002000
#define EMXCP_BUFFER_SIZE    (16 * 1024)  // 16KB

void user_init(void)
{
    // 2. 初始化 emXCP,传入缓冲区
    emeye_xcp_init((char*)EMXCP_BUFFER_ADDR, EMXCP_BUFFER_SIZE);

    // 3. 设置中断周期(1ms)
    emeye_xcp_set_irq(1, 0);
}

// 在 1ms 定时器中断中调用
void timer_1ms_isr(void)
{
    emeye_xcp_irq_handler();
}

十、相关文档