开始使用

欢迎使用 Synex

Synex 是面向工程调试的一体化桌面工具,适合串口、UDP、TCP、J-Link RTT、J-Link HSS、CAN、MDF/MF4 等多类数据接入和分析场景。它的目标是让你在一个界面里完成设备连接、协议解析、实时观测、控制交互和测试复盘。

如果你正在做电机控制、传感器调试、车载总线分析或嵌入式上位机联调,可以优先从“第一次连接设备”和“连接方式”两节开始;希望复用固件已有字节流协议时,可继续阅读“J-Link RTT”;希望直接观测固件变量时,可继续阅读“J-Link HSS”。

Synex 主界面
Synex 主工作区:连接配置、实时曲线和可交互 Tile 可以放在同一个调试上下文中。

安装与下载

建议优先从首页下载区获取最新 Windows 发布包。若网络访问 Gitee 不稳定,可以使用百度网盘备用链接。

v3.0.4 开始,Synex 支持软件内自动升级。自动升级会检查当前版本和最新发布包,下载完成后按提示重启即可更新;低于 v3.0.4 的旧版本需要先手动下载新版安装包。

自动升级功能
图示:版本检查、更新提示、下载进度和重启升级入口。

第一次连接设备

推荐先用虚拟数据源确认绘图功能正常,再切换到真实设备。这样可以快速区分是软件配置问题,还是外部设备、协议或调试链路问题。

  1. 打开连接页,选择连接类型。
  2. 使用串口、UDP 或 TCP 时,选择 JustFloatFireWaterRawDataCustomBinary 等解析协议。
  3. 使用 J-Link RTT 时,选择目标设备、SWD/JTAG 和速度;Synex 通过 J-Link DLL 自动搜索 RTT 控制块并读取 Channel 0,仍按固件发送的原始字节流选择解析协议。
  4. 使用 J-Link HSS 时,选择与当前目标固件一致的 ELF/AXF,解析并选择需要采样的变量,不再选择字节流解析协议。
  5. 设置绘图周期和缓冲区大小。
  6. 点击连接开关,观察实时曲线是否开始刷新。

连接方式

Synex 覆盖常规字节流、调试探针、现场总线和离线文件等多类数据来源。串口、UDP、TCP 服务端、TCP 客户端、J-Link RTT、J-Link HSS 和虚拟数据由连接页统一切换;CAN/CAN FD 与 MDF/MF4 则分别使用专用工作区。

串口适合 MCU 初期 bring-up、USB CDC 和传统串行设备联调。
UDP使用本地和远程端口传输无连接数据报,适合低延迟局域网数据。
TCP 服务端监听本地端口并等待设备接入,适合由下位机主动连接上位机的场景。
TCP 客户端主动连接指定服务器地址和端口,适合设备或网关已经提供 TCP 服务的场景。
虚拟数据无需外部硬件即可验证实时绘图、页面布局和控件行为。
J-Link RTT通过 J-Link DLL 原生读取固件 RTT Channel 0,继续使用 JustFloat、RawData 等字节流协议。
J-Link HSS从 ELF/AXF 选择变量,通过 J-Link 直接采样和写入目标内存。
CAN / CAN FD配合 DBC 完成报文收发、信号解析、绘图和 MDF 录制。
MDF / MF4导入历史测量文件,在独立工作区完成离线回放和分析。
提示 串口、TCP、UDP 和 J-Link RTT 接收的是设备发送的字节流,需要配合解析协议;J-Link HSS 直接读取目标变量,是独立的数据源,不属于 JustFloat、FireWater 或 CustomBinary。

串口

串口模式适合直接连接 MCU UART、USB 转串口和 USB CDC 设备。打开连接页后选择端口、波特率、数据位、校验位和停止位,再按照固件发送格式选择解析协议;首次联调建议使用 RawData,确认原始数据持续到达后再切换到正式协议。

UDP

UDP 模式需要填写本地监听端口、远程地址和远程端口。它没有连接握手,点击连接后即开始接收发往本地端口的数据报;发送框会把完整字节帧作为一个 UDP 数据报发往远程端点。

TCP 服务端

TCP 服务端模式由 Synex 监听本地端口,等待设备或测试程序主动接入。连接成功后,接收、发送、协议解析和流量统计都针对当前客户端;客户端断开后可以继续等待下一次连接。

TCP 客户端

TCP 客户端模式由 Synex 主动连接指定服务器地址和端口,适合下位机、网关或测试服务已经监听 TCP 端口的场景。可选握手文本会在连接建立后发送一次,留空则直接开始普通数据收发。

虚拟数据

虚拟数据不依赖外部设备,用于快速验证绘图刷新、通道数量、采样周期、工作台布局和数据显示控件。配置生成周期、基础频率、幅值、通道数量及可选噪声后即可连接;切换到真实连接方式时,再按设备数据格式选择对应协议。

J-Link RTT 适合把固件已经组好的文本或二进制数据通过 SWD/JTAG 发送到电脑,不占用额外串口。Synex 直接使用 J-Link DLL 打开探针、自动搜索 RTT 控制块并轮询 Up Channel 0;收到的原始字节继续交给 JustFloat、FireWater、RawData 或 CustomBinary 解析,不需要启动 Commander、PowerShell 或本机 TCP 服务。

RTT 与 HSS 的区别 RTT 的变量数量、类型和帧格式由下位机固件决定,Synex 不读取 ELF/AXF,也不直接选择目标变量;HSS 则依据 ELF/AXF 直接采样目标内存。RTT 在 Synex 中仍按普通字节流使用。
  1. 打开连接页,把连接类型切换为“J-Link RTT”。
  2. 打开参数窗口,选择 USB 或 TCP/IP 探针、目标设备、SWD/JTAG 和速度;连接多个 USB J-Link 时填写探针序列号。
  3. JLink_x64.dll 路径通常保持为空,Synex 会根据 SEGGER 安装信息自动定位。目标暂停时默认自动继续运行,但不会主动执行复位或暂停。
  4. 按固件实际输出选择 JustFloatFireWaterRawDataCustomBinary。首次联调建议先选 RawData,确认持续收包后再切换到正式协议。
  5. 点击连接开关。Synex 会在内部等待最多 5 秒,自动搜索 RTT 控制块并校验 Up/Down Channel 0;普通连接不需要填写控制块地址或搜索参数。
连接后的行为 拔出 J-Link 或目标掉线后,Synex 会自动断开并复位连接开关。发送框写入 RTT Down Channel 0,下位机需要调用 SEGGER_RTT_Read(0, ...) 才能接收下行数据。

如果需要排除 Synex 配置问题,仍可暂时关闭 Synex RTT 连接并用 Commander 建立 19021 Telnet 转接。下面的命令仅用于独立诊断,不能与 Synex 原生 RTT 同时占用同一个探针。

& "C:\Program Files\SEGGER\JLink\JLink.exe" -device STM32G431RB -if SWD -speed 4000 -autoconnect 1 -RTTTelnetPort 19021

J-Link HSS 变量采样与调参

J-Link HSS 通过 SEGGER J-Link 探针读取目标内存,并依据 ELF/AXF 中的调试信息把原始字节还原为有名称、有类型的变量。对于具有确定内存地址的变量,可以不再为实时波形额外编写一套上报帧;采样结果仍进入 Synex 现有绘图、通道和工作台链路。

HSS 是数据接入方式 选择 J-Link HSS 后,采样通道由 ELF/AXF 变量方案决定,不使用连接页中的 JustFloat、FireWater、RawData 或 CustomBinary 解析配置。

使用前准备

Synex 不复制或分发 SEGGER 的运行库。切换到 J-Link HSS 时,软件会在后台预加载 JLink_x64.dll;自动定位失败时,可在“J-Link HSS 参数”的“DLL 文件”一行指定绝对路径。DLL 成功加载后会在当前进程内保持加载,修改路径后需要重启 Synex 才能使用新的 DLL。

配置并连接 HSS

  1. 在连接页将连接类型切换为“J-Link HSS”。
  2. 选择 ELF/AXF 文件,点击解析按钮打开采样信号选择窗口。
  3. 在“J-Link HSS 参数”中设置 USB 或 TCP/IP 探针、SWD/JTAG、调试速度、目标设备、采样周期和读取合并策略。
  4. 如有需要,先点击参数窗口左下角的测试按钮。测试只建立临时 J-Link 会话并查询 HSS 能力,不会开始正式采样。
  5. 保存参数并返回连接页,确认已经选择至少一个采样变量,再点击连接开关。

采样周期设为“最大速度”时,Synex 不把它固定解释为 1 ms;实际能力由 J-Link 版本、探针、调试接口速度、变量数量、读块数量和每帧字节数共同决定。固定周期低于当前探针能力时,连接会给出明确提示。

J-Link HSS 参数配置窗口
J-Link HSS 连接页与参数窗口:ELF/AXF、探针、目标设备、DLL、采样周期和读取合并配置。

选择 ELF/AXF 采样变量

采样信号窗口按编译单元和变量层级展示 ELF/AXF 内容。结构体和数组用于展开层级,具有确定地址且类型受支持的叶子变量可以加入采样列表;没有可选子项且自身不可采样的节点不会占用列表空间。

ELF/AXF 采样信号选择窗口
ELF/AXF 变量选择:搜索变量树、多选采样信号并调整最终通道顺序。

采样结果与通道

连接成功后,Synex 按已应用的采样方案解码 HSS 记录,并把所选变量依次转换为绘图通道。通道数量和变量名称会在同一次方案应用后同步到绘图页,避免数量尚未更新时出现名称错位。

通过 Tile 直接写目标内存

Slider、Toggle 和 ModeSelector 三类输入控件均可把“发送内容”切换为“HSS”,将控件值编码为目标变量的真实类型后交给当前 HSS worker 写入。写入变量使用单选窗口,可以选择未加入绘图采样通道的其它可写变量,不会为了写入而偷偷增加绘图通道。

  1. 打开 Slider、Toggle 或 ModeSelector 的配置窗口,将“发送内容”切换为“HSS”。
  2. 点击“选择变量”,在单选版 ELF/AXF 变量窗口中选择一个具有固定地址的可写标量。
  3. 确认只读显示的变量名称、数据类型和内存地址,并选择“不读回”或“写后读回校验”。
  4. 保存配置。选择变量后,控件名称会自动更新为变量显示名;后续值变化会像 ABC/HEX 模式一样立即触发发送。

“写后读回校验”会在写入完成后额外读取同一地址,并按变量类型比较返回值。它有助于确认单次调参是否生效,但会增加一次 J-Link 访问;连续拖动 Slider 或追求更低写入延迟时,建议使用默认的“不读回”。

写入前请确认目标 HSS 写入会直接改变目标内存。Synex 按 ELF 类型编码并校验当前文件指纹,但不会替用户判断某个变量在业务逻辑上是否允许修改;写入控制状态、指针或安全相关变量前,请先确认固件行为和调试环境。
Slider 控件通过 HSS 写入目标内存
输入控件的 HSS 发送内容:单选目标变量,只读显示类型与地址,并可选择写后读回校验。

固件重新编译后更新变量地址

重新编译固件后,即使变量名称没有变化,其地址、类型或 ELF 指纹也可能改变。连接页的旋转箭头按钮可以主动校验并更新当前采样变量以及所有 Tile 保存的 HSS 写变量。

协议解析

连接页的数据引擎决定收到的字节如何变成曲线、图片或控制台原始帧。调试早期优先用 FireWater 或 RawData 验证链路;高频波形用 JustFloat;量产项目或字段结构固定的设备建议发布 CustomBinary。

JustFloat小端 float32 + 帧尾,适合高频多通道曲线。
FireWater一行 CSV 一帧,适合串口助手和人工排查。
CustomBinary帧头、字段、校验、帧尾由协议编辑器配置。
RawData不生成曲线通道,只观察真实收包内容。

JustFloat 高速浮点协议

JustFloat 的普通波形帧由若干个小端 float32 顺序排列,最后追加 0x7F800000 作为帧尾。下面假设电流、转速等业务变量已经在你的控制代码里定义,这里只展示打包和周期发送。

#include <stdint.h>
#include <string.h>
#include "usart.h"

extern UART_HandleTypeDef huart2;
extern float g_synex_iq;
extern float g_synex_id;
extern float g_synex_speed_rpm;

// JustFloat 按 float32 小端顺序发送通道值,并在最后追加 0x7F800000 帧尾。
void Synex_UploadJustFloat(void)
{
    float frame[4];
    const uint32_t tail = 0x7F800000u;

    frame[0] = g_synex_iq;
    frame[1] = g_synex_id;
    frame[2] = g_synex_speed_rpm;
    memcpy(&frame[3], &tail, sizeof(tail));
    HAL_UART_Transmit_DMA(&huart2, (uint8_t *)frame, sizeof(frame));
}

// 在 1 ms 或更快的调度任务中调用,发送频率由你的控制周期决定。
void Synex_JustFloatTask1ms(void)
{
    Synex_UploadJustFloat();
}

FireWater 文本 CSV 协议

FireWater 每行文本是一帧,通道值用英文逗号分隔,行尾必须带 \n。实际工程里它最适合早期联调,直接用 printf 输出当前波形或性能监测值即可。

#include <stdio.h>

extern float g_synex_bus_voltage;
extern float g_synex_iq;
extern float g_synex_id;
extern float g_synex_speed_rpm;

// FireWater 发送一行 CSV;Synex 会按逗号拆成多通道曲线。
void Synex_UploadFireWater(void)
{
    printf("%.2f,%.2f,%.2f,%.1f\n", g_synex_bus_voltage, g_synex_iq, g_synex_id, g_synex_speed_rpm);
}

// FireWater 是文本协议,建议放在 1 ms 到 10 ms 的低速状态任务里。
void Synex_FireWaterTask10ms(void)
{
    Synex_UploadFireWater();
}

图片数据混合流

图片混合流不需要单独协议。设备端先发送一整帧图片包,再紧跟一帧普通波形数据即可;图片包里的 image_size 会告诉 Synex 精确取走多少图片字节,剩余字节会继续按当前协议解析。示例中的 27 表示 JPG,28 表示 PNG;串口 DMA 场景下,Synex_WriteBytes() 需要保证上一段发完再发下一段。

#include <stdint.h>
#include <stdio.h>

extern const uint8_t g_synex_jpg_bytes[];
extern const uint32_t g_synex_jpg_size;
extern float g_synex_iq;
extern float g_synex_id;
extern float g_synex_speed_rpm;
extern int Synex_WriteBytes(const uint8_t *data, uint32_t length);

// FireWater 图片包是 image 头行 + JPG/PNG 原始字节;后面可以继续追加普通 CSV 波形帧。
void Synex_UploadFireWaterImageAndWave(void)
{
    char image_header[48];
    char wave_line[64];
    int image_header_length = snprintf(image_header, sizeof(image_header), "\nimage:0,%lu,-1,-1,27\n", (unsigned long)g_synex_jpg_size);
    int wave_line_length = snprintf(wave_line, sizeof(wave_line), "%.3f,%.3f,%.1f\n", g_synex_iq, g_synex_id, g_synex_speed_rpm);

    if (image_header_length <= 0 || image_header_length >= (int)sizeof(image_header)) return;
    if (wave_line_length <= 0 || wave_line_length >= (int)sizeof(wave_line)) return;

    (void)Synex_WriteBytes((const uint8_t *)image_header, (uint32_t)image_header_length);
    (void)Synex_WriteBytes(g_synex_jpg_bytes, g_synex_jpg_size);
    (void)Synex_WriteBytes((const uint8_t *)wave_line, (uint32_t)wave_line_length);
}
#include <stdint.h>
#include <string.h>

extern const uint8_t g_synex_jpg_bytes[];
extern const uint32_t g_synex_jpg_size;
extern float g_synex_iq;
extern float g_synex_id;
extern float g_synex_speed_rpm;
extern int Synex_WriteBytes(const uint8_t *data, uint32_t length);

// JustFloat 图片头由同步帧尾、5 个 int32 参数和 2 个连续帧尾组成,随后紧跟图片字节。
void Synex_UploadJustFloatImageAndWave(void)
{
    const uint32_t tail = 0x7F800000u;
    uint32_t image_header[8];
    float wave_frame[4];

    image_header[0] = tail;
    image_header[1] = 0u;
    image_header[2] = g_synex_jpg_size;
    image_header[3] = 0xFFFFFFFFu;
    image_header[4] = 0xFFFFFFFFu;
    image_header[5] = 27u;
    image_header[6] = tail;
    image_header[7] = tail;

    wave_frame[0] = g_synex_iq;
    wave_frame[1] = g_synex_id;
    wave_frame[2] = g_synex_speed_rpm;
    memcpy(&wave_frame[3], &tail, sizeof(tail));

    (void)Synex_WriteBytes((const uint8_t *)image_header, sizeof(image_header));
    (void)Synex_WriteBytes(g_synex_jpg_bytes, g_synex_jpg_size);
    (void)Synex_WriteBytes((const uint8_t *)wave_frame, sizeof(wave_frame));
}

CustomBinary 自定义二进制协议

CustomBinary 按协议编辑器发布的字段顺序解析固定长度帧。Header、Tail、Checksum 和大小端都由协议编辑器配置;下位机端直接使用自动生成的 synex_protocol_sender.h / synex_protocol_sender.c。业务代码只填充 Payload,并把底层 UART DMA 发送函数作为回调传给生成的 send_frame

#include <stdint.h>
#include "synex_protocol_sender.h"
#include "usart.h"

extern UART_HandleTypeDef huart2;
extern float g_synex_phase_current;
extern float g_synex_bus_voltage;
extern float g_synex_motor_temp;
extern float g_synex_speed_rpm;

static SynexProtocolSenderFrame g_synex_protocol_frame;
static SynexProtocolSenderPayload g_synex_protocol_payload;

// 适配自动生成代码需要的底层发送回调;这里用 STM32 HAL UART DMA 举例。
int SynexProtocol_WriteBytes(const uint8_t *data, uint16_t length, void *user)
{
    UART_HandleTypeDef *huart = (UART_HandleTypeDef *)user;
    if (data == 0 || length == 0u || huart == 0) return -1;
    return (int)HAL_UART_Transmit_DMA(huart, (uint8_t *)data, length);
}

// 填充自动生成的 Payload,然后交给 send_frame 统一完成组帧、校验和发送。
void Synex_UploadCustomBinary(void)
{
    g_synex_protocol_payload.phase_current = g_synex_phase_current;
    g_synex_protocol_payload.bus_voltage = g_synex_bus_voltage;
    g_synex_protocol_payload.motor_temp = g_synex_motor_temp;
    g_synex_protocol_payload.speed_rpm = g_synex_speed_rpm;

    (void)synex_protocol_sender_send_frame(&g_synex_protocol_frame, &g_synex_protocol_payload, SynexProtocol_WriteBytes, &huart2);
}

// CustomBinary 适合固定字段的高速上报,可以放在 200 us 或 1 ms 调度任务里。
void Synex_CustomBinaryTask200us(void)
{
    Synex_UploadCustomBinary();
}

RawData 原始数据模式

RawData 适合确认线路、波特率、端口和真实输出内容。它不会生成多通道曲线,建议用短文本把关键状态打出来;等链路稳定后,再切换到 FireWater、JustFloat 或 CustomBinary。

#include <stdio.h>

extern float g_synex_iq;
extern float g_synex_id;
extern float g_synex_speed_rpm;

// RawData 只用于观察原始文本,不参与曲线解析。
void Synex_UploadRawDataDebug(void)
{
    printf("iq=%.3f, id=%.3f, speed=%.1f\n", g_synex_iq, g_synex_id, g_synex_speed_rpm);
}

// RawData 主要用于链路检查,周期不宜过高,避免文本日志刷屏。
void Synex_RawDataTask100ms(void)
{
    Synex_UploadRawDataDebug();
}

个人工作台

个人工作台用于把实时观察、控制指令和现场诊断放在同一个页面。你可以按调试对象自由组合绘图、数值、仪表、姿态、图片、串口控制台、滑条、开关和模式选择控件,形成专属于当前设备的联调面板。

个人工作台总览
个人工作台可以把曲线、命令、图片和状态控件放在同一个调试页面。

将页面拖出为独立窗口

按住个人工作台顶部的页签并拖到主窗口外,即可将整个页面变成独立窗口。浮动页面会继续接收实时数据,页面中的实时绘图、姿态、图片和控制控件都可以继续工作,删除、复制、粘贴等页面操作也保持可用。需要恢复原布局时,将页签拖回主窗口的页签栏即可重新停靠。

多窗口使用建议 主窗口可以保留连接、通道和指令配置,独立窗口用于显示实时曲线、设备姿态或图像画面。使用多显示器时,可以同时观察多个工作台页面,减少频繁切换页签。

添加、选择和删除控件

在个人工作台空白区域右键,可以从菜单中添加控件;新控件会优先出现在右键所在位置。单击控件可以激活它,按住 Ctrl 单击可以加入或移出多选,拖动空白区域可以框选多个控件。选中控件后按 Delete 删除,输入框、下拉框和数值编辑框正在编辑时不会触发删除。

复制控件时,先选中目标控件并按 Ctrl + C,再把鼠标移动到希望放置的位置并按 Ctrl + V。粘贴出的控件会保留原控件配置,并生成新的控件 ID。

添加、选择和删除控件
图示:空白区域右键菜单、多选状态、复制粘贴或删除控件的操作入口。

栅格布局与层级

个人工作台采用栅格化布局。当前页面按 12 列、8 行大栅格组织,每个大格再细分为 8 x 8 小格,因此控件既能保持整齐,也能做较细的尺寸调整。工作台允许控件重叠,最近操作的控件会移动到更靠前的层级。

布局建议 实时绘图和图片控件适合占用较大的网格区域;数值、开关、模式选择和滑条适合做成较小控件,放在曲线旁边形成“观察 + 操作”的闭环。
栅格布局与层级
图示:拖动或缩放控件时的网格吸附效果,以及多个控件重叠时的前后层级。

顶部工具栏

实时绘图控件

实时绘图控件用于观察一个或多个通道的高速波形。它支持 YT/XY 图、游标、区域数据统计、FFT、截图和右键菜单配置,适合把关键变量放在同一个视图里分析。

性能与通道

✨ 10 亿+ 点 / 秒绘制能力面向高采样率、多通道和长时间缓存场景,降低大量点刷新时的卡顿感。

✨ 长时间大数据观测保留大量历史采样点,配合降采样、动态 Y、局部缩放和游标读取,在趋势和细节之间快速切换。

✨ 区域数据统计直接框定时域范围,计算指定通道的均值、有效值、极值、峰峰值和标准差,并支持手动或实时刷新。

✨ 实时 FFT 分析时域波形和频域结果可以在同一个控件内联动观察,排查谐波、振动、噪声和控制周期问题更直接。

实时绘图控件外观
图示:通道选择框、曲线绘图区、坐标轴、游标、右上角状态信息和控件外框。

性能状态显示:绘图区域会显示 FPS、点数等渲染状态信息,用于观察当前刷新和绘制压力。高通道数、大缓冲区、高 FPS 或高 MSAA 都会增加 CPU/GPU 负载,必要时可以开启降采样来保持交互流畅。

通道选择:在绘图控件顶部选择需要显示的通道,曲线名称和颜色会跟随右侧通道配置。一个绘图控件可以同时显示多条曲线,适合把同一组相关变量放在同一坐标系里比较。

曲线选中:单击曲线可以选中它,单击绘图区空白会清除曲线的视觉选中状态。数据统计看板显示时,空白点击不会切换统计通道、更新看板或触发计算;再次明确选中曲线才会立即统计该通道。看板显示期间,左上角不再额外显示彩色通道名,通道名称由看板首行统一呈现。

坐标、视图与数据交互

时域 YT 图:默认模式是 YT 图,X 轴表示时间,Y 轴表示通道值。它适合观察电流、电压、速度、温度等随时间变化的信号。

XY 图:切换到 XY 图后,每条曲线可以选择一个 X 通道源,适合观察轨迹、相图、位置关系或两个变量之间的闭环关系。XY 图不参与时域 X 范围同步。

缩放和平移:在绘图区滚动鼠标滚轮会同时缩放 X/Y 方向;在 X 轴或 Y 轴刻度区域滚动时,只缩放对应轴。按住左键拖动可以平移当前视图。

X 光标:左键双击绘图区可以添加或移动 X 光标,用于读取某一时刻所有曲线的值。拖动 X 光标线可以调整位置。

Y 光标:按住 Ctrl 后左键双击可以添加或移动 Y 光标,用于标记目标值、阈值或对比某个固定幅值。

Tracer 标记:Tracer 用于在曲线上显示当前关注点和数值标签。右键菜单可以切换 Tracer 的标记样式,让它更适合不同密度和颜色的曲线。

自动 Y:顶部工具栏的自动 Y 会立即根据当前可见数据校准纵轴范围,适合数据范围突然变化后快速回到可读视图。

动态 Y:动态 Y 会持续跟随当前可见数据范围变化。它适合波形幅值变化较大但需要一直保持可读的场景,也可以在单个绘图控件的右键菜单里单独开关。

复位视图:复位视图会恢复当前绘图控件的完整 X 范围,并重新调整 Y 轴显示范围。视图被多次缩放、拖拽后,可以用它快速回到整体观察状态。

降采样:长时间运行或大缓冲区场景下,降采样可以减少实际绘制点数,降低显示压力。它不会改变原始缓存数据,只影响绘制负载。

X 光标同步:开启同步后,同一工作台内的 YT 绘图控件会同步 X 光标,适合多图排查同一时刻不同变量的状态。

截图复制:绘图控件支持复制当前主图截图。如果已经打开 FFT,也可以复制主图和 FFT 图的组合截图,便于粘贴到报告、聊天或问题记录中。

CSV 数据保存和加载:顶部工具栏可以保存当前绘图数据,也可以加载 CSV 数据进行离线查看。加载后可以复盘某次实验里的关键波形。

右键菜单与显示设置

右键菜单功能:绘图控件的右键菜单集中放置显示方式、交互方式和截图工具,常用于临时调整某一个绘图控件的行为。

  • 动态 Y 轴:选择“是”或“否”,控制当前绘图控件是否持续自动调整 Y 轴。
  • 坐标模式:YT图XY图 之间切换。
  • 数据统计:显示或隐藏统计选区和结果看板,并可通过“实时更新看板 > 是 / 否”控制周期刷新。
  • X 通道源:在 XY 图中为曲线选择 X 轴数据来源。
  • X 轴滚动条:控制主图 YT 模式下是否显示 X 轴浮动滚动条。
  • 绘图模式:可选择线图、点图或点线图。线图适合连续波形,点图适合离散采样,点线图适合同时观察趋势和采样点。
  • Tracer 标记:可选择十字形 + 水平、圆圈 + 斜线、菱形 + 斜线三种标记样式。
  • X 轴单位:可选择秒 s、毫秒 ms 或微秒 us
  • 滚轮速度:可在 5%~50% 范围内调整鼠标滚轮的单次缩放幅度。
  • 光标取值方式:可选择线性插值或最近点。线性插值适合平滑读取,最近点适合严格按采样点读取。
  • 隐藏顶部栏:隐藏当前绘图控件顶部的通道和 FFT 配置区域,让曲线区域获得更多空间。
  • 显示顶部栏:恢复被隐藏的顶部配置区域。
  • 复制截图:复制当前主图截图。
  • 复制所有截图:同时复制主图和 FFT 图截图。
实时绘图控件右键菜单
图示:右键菜单展开后的动态 Y、坐标模式、绘图模式、Tracer、单位、滚轮速度、光标取值和截图功能。

数据统计看板

数据统计看板用于分析某个通道在指定时域范围内的整体水平、波动幅度和离散程度。统计区域以蓝色半透明选区和竖向 STA 标签标识,结果显示在主图左上角。

显示与隐藏:在主图右键菜单中打开“数据统计”,点击“显示统计看板”即可同时显示默认统计选区和结果看板;菜单项随后变为“隐藏统计看板”。隐藏后会移除统计选区、标签和结果文字,并停止相关数据复制与计算。

统计通道:首次使用时自动选择第一个有效通道。单击另一条曲线会立即将其切换为统计通道并计算一次;单击绘图区空白只清除曲线的视觉选中状态,不会改变看板通道或触发计算。看板显示期间,左上角不再重复绘制原来的彩色通道名。

统计选区:按住 Shift + 鼠标左键,可在选区内部整体移动,或拖动左右边界单独调整范围。被拖动的边界越过固定边界时会自动交换左右角色;选区完全离开当前视图后,也可以在空白处将原宽度选区移动到指针附近。数据缓冲范围缩小时,选区会自动收回到当前有效数据范围内。

计算与刷新:点击顶部工具栏的统计刷新按钮可以按当前通道和范围手动计算;切换曲线或释放统计选区也会立即刷新。拖动期间保留上一次完整结果,释放后再一次性更新。通过“数据统计 > 实时更新看板 > 是”开启实时统计后,仅在收到新数据时刷新,数值最高约 5 Hz 变化;已有任务尚未完成时只保留最新一次待处理请求。

结果看板:看板显示实际通道名称和统计范围,并给出 MeanRMSMinMaxP-PStdDev。统计值跟随当前 Y 轴精度显示,并使用等宽字体动态补齐为两列;范围文字跟随当前 X 轴单位和精度。没有有效通道或选区内没有有效数据时,指标统一显示 NA

实时绘图控件数据统计看板
图示:当前统计通道、蓝色 STA 选区,以及 Mean、RMS、Min、Max、P-P 和 StdDev 结果看板。

FFT 与阶次分析

FFT 与阶次分析用于观察所选通道的频率成分、谐波幅值、相位和总谐波失真。FFT 区域以青绿色半透明选区和竖向 FFT 标签标识,分析结果显示在下方独立绘图区。

显示与隐藏:顶部工具栏的显示按钮用于打开或隐藏下方 FFT 绘图区,实时 FFT 按钮则单独控制是否跟随新数据计算。关闭实时 FFT 不会隐藏已有结果;隐藏 FFT 绘图区后会保留主图,并停止实时 FFT 调度。

FFT 通道与参数:顶部工具栏可以选择 FFT 通道,并设置起始时间 T、周期数 N 和基波频率 F0T 决定分析窗口起点,NF0 共同决定窗口长度;周期数支持小数,适合精确截取非整数周期范围。

FFT 选区:按住 Alt + 鼠标左键,可在选区内部整体移动,或拖动左右边界单独调整范围。整体移动会反向更新 T,边界缩放会同时更新 T/N;选区完全离开当前视图后,也可以在空白处将原宽度选区移动到指针附近。拖动期间暂停 FFT 计算,释放后将边界吸附到实际采样点并精确计算一次。

计算与刷新:点击计算按钮可以按当前参数执行一次精确 FFT。打开实时 FFT 后,仅在收到新数据时运行快速预览计算,频谱曲线或阶次柱状图最高约 25 Hz 刷新,结果看板文字最高约 5 Hz 更新;已有任务尚未完成时只保留最新请求。关闭实时 FFT 或停止数据流时会补充一次精确计算。

显示形式:在 FFT 绘图区右键打开“显示形式”,可以在“频谱曲线”和“阶次柱状图”之间切换。频谱曲线的 X 轴单位为 Hz,阶次柱状图的 X 轴单位为 Order;两种形式共用最近一次分析结果,切换时不需要重新计算。右键菜单还可以调整绘图模式、Tracer 标记、滚轮缩放幅度和截图方式。

结果看板:看板显示采样率 Fs、实际分析时间范围、FFT 点数 N_fft、直流分量、THD,以及各阶谐波的幅值、相位和频率;内容超过绘图区高度时可以滚动查看。谐波最多分析到 Nyquist 频率以内的 100 阶。

实时绘图控件 FFT 功能
图示:FFT 通道、T/N/F0 参数、青绿色分析选区、结果看板和阶次柱状图。

数值控件

数值控件用于突出显示单个通道的当前值,适合放置电流、电压、转速、温度等关键变量。它会跟随通道配置中的名称和颜色变化,便于和曲线颜色保持一致。

数值控件
图示:数值控件配置窗口和绑定后的显示效果。

仪表控件

仪表控件用于把单个通道显示为圆形表盘,适合转速、母线电压、温度、占空比等有明确范围的变量。配置时通常需要选择通道,并设置标题、最小值、最大值、单位和小数位。

仪表控件
图示:仪表控件显示效果、范围配置和单位配置。

姿态控件

姿态控件用于显示设备或机构的三维姿态,适合 IMU、云台、电机执行机构和机器人关节调试。它可以从欧拉角或四元数通道获取姿态,也可以配置模型文件、模型颜色、透明度、线框、坐标轴和校准参数。

姿态控件
图示:姿态控件、STL 或 glTF/GLB 模型显示、输入通道配置和模型外观配置。

图片控件

图片控件用于显示协议中的图片帧,适合摄像头、视觉算法、中间处理结果或设备截图。右键图片控件可以选择图片通道、填充方式、图片特效和名称显示方式。

图片控件
图示:图片控件右键菜单、填充方式、图片特效列表和不同特效的显示效果。

串口控制台控件

串口控制台控件用于查看和发送原始串口数据,适合协议 bring-up、异常排查和文本日志观察,可以在文本/HEX、时间戳、解码、ANSI、RX/TX 显示和日志记录之间切换。

✨ 高并发大吞吐显示大量 RX/TX 数据连续刷屏时依然保持流畅,适合高频日志和压力测试。

✨ 原始数据完整追踪按真实到达顺序显示输入和输出,便于回看每一段通信过程并定位偶发异常。

串口控制台控件
图示:RX/TX 区域、HEX/时间戳按钮和日志记录入口。

滑条控件

滑条控件用于把连续数值发送给设备,适合速度给定、电流给定、位置给定和占空比调节。配置时通常需要设置显示名称、数值范围、步进、初始值、命令模板和发送方式。

滑条控件
图示:滑条控件、范围配置和命令模板配置。

开关控件

开关控件用于发送双态控制命令,适合使能/失能、运行/停止、闭环/开环等场景。配置时可以设置开关名称、两种状态的显示文本、状态值、命令内容、校验方式和发送目标。

开关控件
图示:开关控件、状态文本、状态值、发送模板和命令绑定配置。

模式选择控件

模式选择控件用于在多个离散模式之间切换,适合控制模式、测试阶段、运行档位和算法分支选择。每个模式都可以配置显示名称、模式值和对应命令。

模式选择控件
图示:模式按钮组、模式文本、模式值、发送模板、同状态重发和命令绑定配置。

指令台

指令台用于维护可复用的设备控制指令。它不是临时输入框,而是一个可以长期保存、分组、排序、重复发送并和个人工作台控件绑定的指令库,适合把使能、停止、清故障、设置目标值、切换模式等现场操作集中管理。

统一维护控制动作 常用指令建议先放进指令台,再让滑条、开关、模式选择等控件绑定它。这样同一条指令的内容、校验和重发策略只需要维护一份。
指令台整体外观
图示:左侧指令台、指令组、单条指令、发送按钮和展开后的配置区域。

指令和指令组

指令台由指令和指令组组成。指令是一条具体发送内容,指令组用于把多条指令按顺序组织起来,例如“进入调试模式”“启动实验流程”“退出并复位”。

指令组和嵌套指令
图示:指令组、子指令组、拖动排序效果和组内顺序发送结构。

发送内容模板

每条指令都可以在 Abc 和 HEX 两种模式之间切换。Abc 适合文本指令和串口调试协议,HEX 适合二进制帧、寄存器写入和带参数的结构化指令。

单条指令配置
图示:指令名称、Abc/HEX 切换、发送内容、校验、重复次数和发送间隔。

校验和 CRC

指令台可以在发送内容中插入校验结果。你只需要在模板中写入 [crc],再选择校验类型和校验范围,Synex 会在发送前生成最终字节内容。

重复发送和顺序发送

单条指令和指令组都可以配置重复次数和发送间隔。单条指令用于重复发送同一个指令,指令组用于按顺序执行一组动作。

绑定个人工作台控件

滑条、开关和模式选择控件可以绑定指令台中的某条指令。绑定后,指令内容、校验、重发参数由指令台统一维护,控件只负责提供当前参数。

控件绑定指令
图示:滑条、开关或模式选择控件右键菜单中的绑定指令入口,以及绑定后的配置预览。

导入、导出和清空

指令台可以导出为 JSON,用于项目备份、团队共享或跨电脑迁移。导入 JSON 会替换当前指令台内容,清空全部指令也会删除当前所有指令和指令组,这两类操作都会在执行前提醒确认。

指令台导入导出
图示:导入、导出、清空全部入口,以及替换当前指令台的确认提示。

协议编辑器

协议编辑器用于设计和发布 CustomBinary 自定义二进制协议。你可以把一帧数据拆成帧头、数据、校验、帧尾等字段积木,逐项配置字节数、字节序、缩放、偏移和曲线输出;发布后,连接页即可选择这个协议解析真实设备数据。

从帧结构到可用协议 协议编辑器关注的是“这一帧长什么样”。字段顺序决定解析顺序,字段属性决定每段字节怎么解释,发布动作则把当前设计同步到连接页和解析器。
协议编辑器整体界面
图示:字段组件库、帧结构时间轴、字段属性面板、协议属性和顶部工具栏。

字段组件库

左侧字段组件库提供常用帧结构积木。点击字段即可追加到当前协议,之后可以在时间轴中选择并配置具体属性。

字段组件库
图示:Header、FrameId、Length、Data、Checksum、Tail、Skip 字段按钮。

帧结构时间轴

中间时间轴按字段顺序展示当前协议的完整帧布局。字段从左到右排列,顺序就是解析器读取字节的顺序;拖动字段可以调整同一协议内的字段顺序,拖动协议行可以调整多个协议在工作区中的排列。

帧结构时间轴
图示:一条包含 Header、多个 Data、Checksum、Tail 的完整帧结构,以及发布状态提示。

字段属性配置

右侧字段属性面板用于决定某段字节的含义。Data 字段通常最常用:你可以设置字段名、类型、字节数、大小端、缩放、偏移,并选择是否输出到曲线。

字段属性配置
图示:Data 字段的字段名、类型、字节序、缩放、偏移和输出到曲线选项。

协议属性与多协议工作区

协议属性用于配置协议名称和代码生成模式。协议编辑器允许在同一个工作区中加载多个协议,适合对比不同版本、临时修改旧协议,或把多个设备的协议放在一起维护。

发布与连接页使用

编辑完成后,需要点击发布,当前协议才会写入本地协议库并同步给连接页。连接页选择对应 CustomBinary 协议后,解析器会按已发布的字段顺序和字段属性处理收到的数据。

固件代码生成

协议编辑器可以根据当前协议生成下位机发送侧 .h / .c 代码。生成代码负责组帧、大小端处理和校验计算,业务代码只需要填充 Payload,并把底层 UART、USB CDC 或网络发送函数作为回调传入。

固件代码生成
图示:代码生成按钮、输出目录选择、生成的 .h/.c 文件和代码生成提示。

CAN 总线分析

CAN 模块面向 CAN/CAN FD 总线调试,采用和个人工作台一致的工作区形态。用户可以创建多个 CAN 工作区,并在每个工作区内自由添加、拖动和调整接收、发送、手动发送、绘图等控件,把总线监控、DBC 信号发送和实时分析放在同一个调试上下文里。CAN 工作区页签固定在主窗口中,仅用于切换页面,不支持拖出为独立窗口。

工作区式 CAN 调试 右键空白区域即可添加 CAN 接收、CAN 发送、CAN 手动发送和 CAN 绘图控件;控件可以按实验项目自由布局,适合把“报文观察、信号激励、波形分析、MDF 录制”组合成不同的调试页面。
CAN 工作区整体布局
图示:一个 CAN 工作区内同时放置接收、发送、绘图和手动发送控件。

支持的 CAN 硬件

当前 CAN 配置页支持 KvaserVectorPeak / PCAN创芯ZLG 设备,并提供 Classic CAN 与 CAN FD 两种模式选择。不同硬件的驱动、通道数量、波特率范围和 FD 能力不同,实际连接前建议先确认驱动已经安装并能被系统识别。

CAN 硬件配置
图示:设备类型、通道、Classic CAN / CAN FD、仲裁域和数据域参数配置。

DBC 加载与解析

CAN 页面支持加载 DBC 文件,也可以把 DBC 文件拖入页面解析。DBC 加载后,Synex 会按报文和信号定义解析接收到的总线数据,并把信号以树形结构展示出来,方便直接查看物理值、选择信号绘图,或在发送控件里按物理量编辑报文。

DBC 加载与解析
图示:DBC 文件加载、解析结果、报文与信号定义的基础信息。

CAN 接收控件

CAN 接收控件用于观察实时总线报文。加载 DBC 后,接收控件会把报文按照 DBC 结构展开,既可以看原始报文,也可以直接看解码后的信号值,适合做联调时的总线状态看板。

DBC 接收树
图示:DBC 文件名、接收报文树、信号物理值和单位显示。

CAN 发送控件

CAN 发送控件用于按 DBC 组织报文发送。用户选择要发送的 DBC 报文后,可以在信号级别编辑物理值,由 Synex 根据 DBC 自动打包为 CAN 数据帧,避免手工计算位域、大小端和缩放系数。

DBC 报文发送
图示:DBC 发送列表、信号编辑区、周期发送和触发方式配置。

发送信号生成器

信号生成器用于让某个发送信号按规则自动变化,适合做阶跃响应、扫值测试、边界测试和控制链路验证。配置完成后,CAN 发送控件会在发送任务运行时实时计算信号值,并按 DBC 打包到对应报文里。

CAN 手动发送控件

CAN 手动发送控件不依赖 DBC,适合快速验证硬件连接、发送临时原始帧,或调试还没有整理成 DBC 的私有协议。用户可以直接填写 ID、DLC 和数据字节,并选择单次、周期或按键触发发送。

CAN 手动发送控件
图示:ID、DLC、数据字节、单次发送和周期发送设置。

CAN 绘图控件

CAN 绘图控件用于把 DBC 信号直接送入实时绘图区。它适合观察控制目标、反馈量、状态量之间的动态关系,也可以把多个信号放在同一工作区中和接收、发送控件一起联动分析。

CAN 信号绘图
图示:多个 DBC 信号实时绘图、游标读取和暂停分析。

CAN 报文录制为 MDF

CAN 页面支持把总线数据录制为 MDF,适合把实车、台架或长时间联调过程保存下来,再进入 MDF 离线回放流程做复盘、截图和报告整理。录制前建议确认 DBC、硬件通道和目标保存路径,避免长时间测试结束后发现信号上下文不完整。

MDF 离线回放

MDF/MF4 模块用于离线分析标定和测试数据。你可以加载文件、选择信号、分组显示,并将关键波形截图用于报告。

AI 助手连接 / MCP

Synex 支持通过 MCP 让外部 AI 连接正在运行的应用。开启后,AI 会通过 SynexMcpServer.exe 连接本机 Synex,并访问当前 UI 中的真实指令面板、协议编辑器和个人工作台;关闭后,本机发现文件会被删除,外部 AI 无法继续连接。

安全边界 MCP 只在你手动开启顶部工具栏“AI 助手连接”后生效。当前桥接走本机 IPC,不开放网络端口;会修改界面的工具调用建议先让 AI 预览,再确认应用。

当前 MCP 能力

MCP 开启后,外部 AI 不是简单读取静态文件,而是连接正在运行的 Synex UI。它可以读取当前界面状态,也可以在你确认后修改真实工作区配置。

MCP 联动个人工作台
图示:AI 可以读取个人工作台页面、控件布局和控件配置,也可以按确认后的方案创建或调整调试页面。
MCP 联动协议编辑器
图示:AI 可以读取协议字段、校验配置和发布状态,并辅助生成协议草稿、示例帧和下位机参考代码。
MCP 联动指令台
图示:AI 可以读取指令组和单条指令,预览指令台修改内容,并在确认后应用到当前运行中的 Synex。

Claude Code 接入

如果使用 Claude Code,可以把发布包中的 SynexMcpServer.exe 注册为 stdio server。下面路径按安装目录举例,实际使用时替换为你本机的 Synex 安装路径。

claude mcp add --scope user --transport stdio synex -- "D:\Synex_v3.0.5\mcp\SynexMcpServer.exe"
claude mcp list
claude mcp get synex

如果后续不再需要让 Claude Code 连接 Synex,可以单独执行卸载命令。

claude mcp remove synex --scope user

Codex 接入

Codex CLI 和 Codex IDE 扩展共用 MCP 配置。你可以用命令行添加,也可以把同等配置写入 ~/.codex/config.toml 或项目内受信任的 .codex/config.toml

codex mcp add synex -- "D:\Synex_v3.0.5\mcp\SynexMcpServer.exe"
[mcp_servers.synex]
command = 'D:\Synex_v3.0.5\mcp\SynexMcpServer.exe'
startup_timeout_sec = 10
tool_timeout_sec = 60

如果使用 Codex 桌面端,验证时不需要再打开命令行。先重启 Codex 或刷新当前会话,让它重新读取 MCP 配置;然后在 Codex 的 MCP/工具列表里确认能看到 synex,最后让 Codex 调用 app_ping

1. 确认 Synex 顶部工具栏已经开启“AI 助手连接”。
2. 重启 Codex 桌面端,或刷新当前 Codex 会话。
3. 打开 Codex 的 MCP/工具列表,确认能看到 synex。
4. 对 Codex 说:请调用 Synex MCP 的 app_ping 检查连接。

VS Code Copilot 接入

VS Code 的 Copilot Agent 模式可以读取 MCP server。建议使用用户级配置:在命令面板运行 MCP: Open User Configuration,把下面内容写入 VS Code 打开的用户配置文件。

{
  "servers": {
    "synex": {
      "command": "D:\\Synex_v3.0.5\\mcp\\SynexMcpServer.exe"
    }
  }
}

验证 VS Code Copilot 是否安装成功时,先从命令面板查看 MCP server 状态,再在 Copilot Chat 的工具选择里确认 Synex 工具可用。最后同样调用 app_ping,用它确认当前运行中的 Synex 已经开启 AI 助手连接。

1. 打开命令面板,运行 MCP: List Servers。
2. 找到 synex,确认它可以启动且没有报错。
3. 打开 Copilot Chat 的 Agent 模式,进入 Configure Tools,确认能看到 synex 的工具。
4. 对 Copilot 说:请调用 Synex MCP 的 app_ping 检查连接。

配置完成后,先在 Synex 顶部工具栏开启“AI 助手连接”,再让外部 AI 调用 app_ping 检查连接。若 Synex 重启或重新开启连接,token 会重新生成;长期运行的 AI 客户端遇到连接失败时,重启 MCP server 通常即可恢复。

校验算法说明

Synex 中的指令台、连接页发送、协议编辑器和 CustomBinary 解析共用同一套校验算法。下位机如果需要解析 Synex 下发的指令,或者要手写与上位机一致的协议收发代码,可以按本节规则实现。

先确认校验范围 算法名称只决定怎么算;真正容易出错的是哪些字节参与计算、校验值写在什么位置、2 字节结果按小端还是大端写入。

支持的算法

名称 长度 计算规则
sum8 1 字节 参与字节逐字节相加,结果保留低 8 位。
sum16 2 字节 参与字节逐字节相加,结果保留低 16 位。
xor8 1 字节 初值 0x00,参与字节逐字节异或。
crc8 1 字节 CRC-8,非反射,高位先算,初值 0x00,多项式 0x07
crc8-maxim 1 字节 CRC-8/MAXIM,反射算法,初值 0x00,反射多项式 0x8C
crc16-modbus 2 字节 CRC-16/MODBUS,反射算法,初值 0xFFFF,反射多项式 0xA001
crc16-ccitt 2 字节 CRC-16/CCITT-FALSE 风格,非反射,高位先算,初值 0xFFFF,多项式 0x1021
crc16-xmodem 2 字节 CRC-16/XMODEM,非反射,高位先算,初值 0x0000,多项式 0x1021

参与校验的数据范围

校验结果写入方式

下位机 C 参考实现

下面的实现按 Synex 固件代码生成器中的算法整理。若你使用协议编辑器直接生成 CustomBinary 发送代码,生成文件里已经包含对应校验函数;只有在下位机需要手写解析 Synex 下发指令或自定义接收逻辑时,才需要复制这些函数。

#include <stdint.h>

static uint16_t Synex_CheckSum8(const uint8_t *data, uint16_t length)
{
    uint8_t sum = 0u;
    for (uint16_t index = 0u; index < length; ++index)
    {
        sum = (uint8_t)(sum + data[index]);
    }
    return sum;
}

static uint16_t Synex_CheckSum16(const uint8_t *data, uint16_t length)
{
    uint16_t sum = 0u;
    for (uint16_t index = 0u; index < length; ++index)
    {
        sum = (uint16_t)(sum + data[index]);
    }
    return sum;
}

static uint16_t Synex_CheckXor8(const uint8_t *data, uint16_t length)
{
    uint8_t value = 0u;
    for (uint16_t index = 0u; index < length; ++index)
    {
        value ^= data[index];
    }
    return value;
}

static uint16_t Synex_CheckCrc8(const uint8_t *data, uint16_t length)
{
    uint8_t crc = 0x00u;
    for (uint16_t index = 0u; index < length; ++index)
    {
        crc ^= data[index];
        for (uint8_t bit = 0u; bit < 8u; ++bit)
        {
            crc = (crc & 0x80u) ? (uint8_t)((crc << 1) ^ 0x07u) : (uint8_t)(crc << 1);
        }
    }
    return crc;
}

static uint16_t Synex_CheckCrc8Maxim(const uint8_t *data, uint16_t length)
{
    uint8_t crc = 0x00u;
    for (uint16_t index = 0u; index < length; ++index)
    {
        crc ^= data[index];
        for (uint8_t bit = 0u; bit < 8u; ++bit)
        {
            crc = (crc & 0x01u) ? (uint8_t)((crc >> 1) ^ 0x8Cu) : (uint8_t)(crc >> 1);
        }
    }
    return crc;
}

static uint16_t Synex_CheckCrc16Modbus(const uint8_t *data, uint16_t length)
{
    uint16_t crc = 0xFFFFu;
    for (uint16_t index = 0u; index < length; ++index)
    {
        crc ^= data[index];
        for (uint8_t bit = 0u; bit < 8u; ++bit)
        {
            crc = (crc & 0x0001u) ? (uint16_t)((crc >> 1) ^ 0xA001u) : (uint16_t)(crc >> 1);
        }
    }
    return crc;
}

static uint16_t Synex_CheckCrc16Ccitt(const uint8_t *data, uint16_t length)
{
    uint16_t crc = 0xFFFFu;
    for (uint16_t index = 0u; index < length; ++index)
    {
        crc ^= (uint16_t)(data[index] << 8);
        for (uint8_t bit = 0u; bit < 8u; ++bit)
        {
            crc = (crc & 0x8000u) ? (uint16_t)((crc << 1) ^ 0x1021u) : (uint16_t)(crc << 1);
        }
    }
    return crc;
}

static uint16_t Synex_CheckCrc16Xmodem(const uint8_t *data, uint16_t length)
{
    uint16_t crc = 0x0000u;
    for (uint16_t index = 0u; index < length; ++index)
    {
        crc ^= (uint16_t)(data[index] << 8);
        for (uint8_t bit = 0u; bit < 8u; ++bit)
        {
            crc = (crc & 0x8000u) ? (uint16_t)((crc << 1) ^ 0x1021u) : (uint16_t)(crc << 1);
        }
    }
    return crc;
}

static void Synex_WriteU16Le(uint8_t *dest, uint16_t value)
{
    dest[0] = (uint8_t)(value & 0x00FFu);
    dest[1] = (uint8_t)((value >> 8) & 0x00FFu);
}

static void Synex_WriteU16Be(uint8_t *dest, uint16_t value)
{
    dest[0] = (uint8_t)((value >> 8) & 0x00FFu);
    dest[1] = (uint8_t)(value & 0x00FFu);
}

常见问题

连接成功但没有数据显示

先确认设备确实在发送数据,再检查协议类型、波特率或网络端口。若协议不确定,可先切换到 RawData 观察原始数据。

波形刷新卡顿

降低绘图刷新频率、减少同时显示通道数,或开启更适合当前机器的降采样策略。高吞吐场景也建议使用二进制协议。

自定义协议解析失败

重点检查帧头帧尾、字节序、字段长度、缩放系数和校验算法。协议编辑完成后建议用固定样本帧先验证。

进入 J-Link HSS 后提示未检测到 DLL

先确认本机已经安装 64 位 SEGGER J-Link Software Pack。如果自动定位失败,请打开“J-Link HSS 参数”,在“DLL 文件”一行选择安装目录中的 JLink_x64.dll;如果此前已经成功加载过其它路径,保存后重启 Synex。

ELF/AXF 中能看到名称,但变量不能选择

该对象可能没有固定可读地址、类型不受支持、只存在于寄存器,或已经被编译器优化。优先选择具有明确地址的全局或静态标量;结构体和数组本身通常只用于展开,应选择其可采样叶子。

连接 HSS 时提示 ELF/AXF 已变化

这表示当前保存的变量绑定和磁盘上的 ELF/AXF 指纹不一致。选择更新后等待地址刷新完成,确认无法匹配变量的处理结果,再次点击连接;Synex 不会在更新后自动连接目标。

HSS 能采样但 Tile 无法写入

确认当前连接类型确实是 J-Link HSS、连接仍处于开启状态,并且控件选择的是当前 ELF/AXF 中可写的固定地址标量。若启用了“写后读回校验”,还需要目标地址能够被 J-Link 正常读回。

反馈与支持

如果你希望补充新的硬件适配、协议模板或示例工程,可以在项目页面提交反馈。反馈时请尽量附带软件版本、连接方式、协议配置和复现步骤;J-Link HSS 问题还建议附上 DLL 版本、目标设备名、接口类型、采样周期和 ELF/AXF 工具链。