VC Windows上位机实现J-Link RTT Viewer功能
1.J-Link 工具下载
Software Development Tools by SEGGER – The Embedded Experts
下载这个
安装好后,打开JLinkRTTViewer.exe,按照嵌入式工程师给的连接方法,测试指令
2.调用JLinkARM.dll中的函数来写对应代码
参考:【Jlink & C#】通过C#实现Jlink RTT上位机的功能-CSDN博客
JLinkARM.dll和JLinkRTTViewer.exe在同一个文件夹,直接拿来用
这里也有一个英文原版的JLinkARM.dll SDK供参考
https://files.cnblogs.com/files/ckrgd/UM08002_JLinkDLL.zip?t=1699510820&download=true
静态调用,直接上代码
//JLinkARM.dll 要用的函数加载 //JLINK TIF #define JLINKARM_TIF_JTAG 0 #define JLINKARM_TIF_SWD 1 const UINT32 LINKARM_RTTERMINAL_CMD_START = 0; const UINT32 JLINKARM_RTTERMINAL_CMD_STOP = 1; const UINT32 JLINKARM_RTTERMINAL_CMD_GETDESC = 2; const UINT32 LINKARM_RTTERMINAL_CMD_GETNUMBUF = 3; typedef char*(*JLINKARM_Open_Func)(void); typedef char(*JLINKARM_IsOpen_Func)(void); typedef void(*JLINKARM_Close_Func)(void); typedef int(*JLINKARM_ExecCommand_Func)(const char* sIn, char* sError, int BufferSize); typedef int(*JLINKARM_TIF_Select_Func)(int); typedef void(*JLINKARM_SetSpeed_Func)(UINT32); typedef int(*JLINKARM_Connect_Func)(void); typedef BOOL(*JLINKARM_IsConnected_Func)(void); typedef void(*JLINKARM_SetLogFile_Func)(const char* sFilename); typedef int(WINAPI*JLINK_RTTERMINAL_Read_Func_Ptr)(UINT32 BufferIndex, char* sBuffer, UINT32 BufferSize); typedef int(WINAPI*JLINK_RTTERMINAL_Write_Func_Ptr)(UINT32 BufferIndex, const char* sBuffer, UINT32 BufferSize); typedef int(WINAPI*JLINK_RTTERMINAL_Control_Func_Ptr)(UINT32 Cmd, void* p); JLINKARM_Open_Func JLINKARMOpen = NULL; //打开设备 JLINKARM_IsOpen_Func JLINKARMIsOpen = NULL; //是否已经打开 JLINKARM_Close_Func JLINKARMClose = NULL; //关闭设备 JLINKARM_ExecCommand_Func JLINKARMExecCommand = NULL; //连接设备参数 JLINKARM_TIF_Select_Func JLINKARMTIFSelect = NULL; //选择设备 JLINKARM_SetSpeed_Func JLINKARMSetSpeed = NULL; //设置JLINK接口速度 0为自动调整 JLINKARM_Connect_Func JLINKARMConnect = NULL; JLINKARM_IsConnected_Func JLINKARMIsConnected = NULL; JLINKARM_SetLogFile_Func JLINKARMSetLogFile = NULL; JLINK_RTTERMINAL_Read_Func_Ptr JLINKRTTErminalRead = NULL; JLINK_RTTERMINAL_Write_Func_Ptr JLINKRTTErminalWrite = NULL; JLINK_RTTERMINAL_Control_Func_Ptr JLINKRTTErminalControl = NULL; //加载JLinkARM.dll函数 void LoadJLinkARMLibrary() { HMODULE hModule; hModule = LoadLibrary(_T("JLinkARM.dll")); JLINKARMOpen = (JLINKARM_Open_Func)GetProcAddress(hModule, "JLINKARM_Open"); JLINKARMIsOpen = (JLINKARM_IsOpen_Func)GetProcAddress(hModule, "JLINKARM_IsOpen"); JLINKARMClose = (JLINKARM_Close_Func)GetProcAddress(hModule, "JLINKARM_Close"); JLINKARMExecCommand = (JLINKARM_ExecCommand_Func)GetProcAddress(hModule, "JLINKARM_ExecCommand"); JLINKARMTIFSelect = (JLINKARM_TIF_Select_Func)GetProcAddress(hModule, "JLINKARM_TIF_Select"); JLINKARMSetSpeed = (JLINKARM_SetSpeed_Func)GetProcAddress(hModule, "JLINKARM_SetSpeed"); JLINKARMConnect = (JLINKARM_Connect_Func)GetProcAddress(hModule, "JLINKARM_Connect"); JLINKARMIsConnected = (JLINKARM_IsConnected_Func)GetProcAddress(hModule, "JLINKARM_IsConnected"); JLINKARMSetLogFile = (JLINKARM_SetLogFile_Func)GetProcAddress(hModule, "JLINKARM_SetLogFile"); JLINKRTTErminalRead = (JLINK_RTTERMINAL_Read_Func_Ptr)GetProcAddress(hModule, "JLINK_RTTERMINAL_Read"); JLINKRTTErminalWrite = (JLINK_RTTERMINAL_Write_Func_Ptr)GetProcAddress(hModule, "JLINK_RTTERMINAL_Write"); JLINKRTTErminalControl = (JLINK_RTTERMINAL_Control_Func_Ptr)GetProcAddress(hModule, "JLINK_RTTERMINAL_Control"); }
//打开jlink设备并连接芯片,并执行读前需要的特殊函数 BOOL JLinkConnectDevice(CString &strError) { char cIsopen = JLINKARMIsOpen(); if (cIsopen == 1) { return TRUE; } char* cpOpenRet; cpOpenRet = JLINKARMOpen(); if (cpOpenRet == NULL) {//成功 char cError[128]; JLINKARMExecCommand("device = GD32F407VE", cError, 128);//第一个参数是由硬件工程师指定的 if (cError[0] == 0) {//成功 JLINKARMTIFSelect(JLINKARM_TIF_SWD); JLINKARMSetSpeed(4000); //设置下载速度 int iConnectret = JLINKARMConnect(); if (iConnectret) { strError = "JLINKARMConnect 失败"; return FALSE; } else { JLINKARMSetLogFile("JLinkLog.log"); //读结果前要执行特殊函数????? JLINKRTTErminalControl(LINKARM_RTTERMINAL_CMD_START, 0); return TRUE; } } else { strError = cpOpenRet; strError += ",JLINKARMExecCommand 失败"; return FALSE; } return TRUE; } else { strError = cpOpenRet; strError += ",JLINKARMOpen 失败"; return FALSE; } } //指令编号 指令字符串, 返回结果, 错误信息 BOOL JLinkExecuteEnter(int iCmdCode, CString strCmd, CString &strRet, CString &strError) { CLog mLog; //param_set+product_key=ue6g80ksaodivatn 1 param_set+product_key success //param_read+product_key 2 param_read+product_key=ue6g80ksaodivat //param_set+device_uuid=uuid2893ffc9b6fd3c9b 3 param_set+device_uuid success //param_read+device_uuid 4 param_read+device_uuid=uuid2893ffc9b6fd3c9b //param_set+device_authkey=pd3tnj3lLZT2azTIj2yuuSy6alSJMzKF 5 param_set+device_authkey success //param_read+device_authkey 6 param_read+device_authkey=pd3tnj3lLZT2azTIj2yuuSy6alSJMzKF //先发指令 char cWrite[128] = { 0 }; sprintf(cWrite, strCmd); int len = strlen(cWrite); mLog.WriteLog("发送指令:%s", strCmd); int ret = JLINKRTTErminalWrite(0, cWrite, len + 1); if (ret < 0) { strError = "JLINKRTTErminalWrite 失败"; return FALSE; } //这个时间决定读到返回值的概率 Sleep(100); char cRead[512] = { 0 }; CString strRead; ret = JLINKRTTErminalRead(0, cRead, 512); if (ret > 0) { strRead = cRead; mLog.WriteLog("收到返回:%s", strRead); } else { strError = "JLINKRTTErminalRead 未读到结果"; return FALSE; } }
//执行完指令后关闭 JLINKRTTErminalControl(JLINKARM_RTTERMINAL_CMD_STOP, 0); JLINKARMClose();