自己开发jlink烧录软件,烧录上位机, C#调用JLinkARM.dll实现软件烧录

最近需要写一个烧录软件,让工厂可以实现一键烧录。

1.命令行烧录

这里实现了运行一个bat文件进行一键烧录,不想看这部分的可以直接跳到第二部分,不受影响。

由于jlink的自带烧录软件JFlash.exe操作十分繁杂,需要自己开发一个简洁的烧录方法,一番操作发现,可以使用J-Link Commander 的命令行进行烧录,操作流程如下:

既然可以用这个命令行,那就可以用bat文件来执行,此间需要生成一个.jlink文件供命令行执行,总共需要两个文件,我这里是burn_hex.bat 和 burn_script.jlink,具体内容如下:

burn_hex.bat:

@echo off
set JLINK_PATH="C:\Program Files (x86)\SEGGER\JLink\JLink.exe"
set HEX_FILE_PATH="Programmer.hex"
set CHIP_MODEL=NRF52832

%JLINK_PATH% -device %CHIP_MODEL% -if SWD -speed 4000 -CommanderScript burn_script.jlink

burn_script.jlink:

connect
device NRF52832_XXAA
speed 4000
TIF SWD
loadfile D:\Programmer.hex
r
g
q

两个 文件放在同一目录下,将hex路径设置正确,点击bat文件即可进行烧录。

命令行衍生上位机

既然可以按如上的方式烧录,那用上位机生成*.jlink文件再执行bat即可实现上位机烧录,但是这种方式不够灵活。

2.C#调用JLinkARM.dll烧录

通过调查发现,jlink的烧录都有调用JLinkARM.dll里面的接口,那开发者也可以调用,但是SEGGER并未开源,需要花钱购买全部的接口。好在有大佬成功逆向了部分接口,原帖:c#的 JLINK API,自己用的 (amobbs.com 阿莫电子技术论坛)

稍全的接口如下(C++):

//arm.h,裡面的API list 如下
/*********************************************************************
*
*       API functions
*/
void         JLINKARM_Close(void);
void         JLINKARM_ClrBP(unsigned BPIndex);
void         JLINKARM_ClrError(void);
void         JLINKARM_EnableLog2File(void);
const char * JLINKARM_GetCompileDateTime(void);
U16          JLINKARM_GetEmbeddedFWVersion(void);
void         JLINKARM_GetHWStatus(JTAG_HW_STATUS * pStat);
U32          JLINKARM_GetId(void);
void         JLINKARM_GetIdData(JTAG_ID_DATA * pIdData);
U16          JLINKARM_GetSelDevice(void);
int          JLINKARM_GetVoltage(void);
U16          JLINKARM_GetSpeed(void);
void         JLINKARM_Go(void);
void         JLINKARM_GoIntDis(void);
char         JLINKARM_Halt(void);
char         JLINKARM_HaltNoSave(void);
char         JLINKARM_IsConnected(void);
char         JLINKARM_IsHalted(void);
const char * JLINKARM_Open(void);
int          JLINKARM_ReadDCC(U32 * pData, U32 NumItems, int TimeOut);
void         JLINKARM_ReadDCCFast(U32 * pData, U32 NumItems);
U32          JLINKARM_ReadICEReg(int RegIndex);
int          JLINKARM_ReadMem (U32 addr, U32 count, void * p);
void         JLINKARM_ReadMemU8 (U32 Addr, U32 NumItems, U8 * pData, U8* pStatus);
void         JLINKARM_ReadMemU16(U32 Addr, U32 NumItems, U16* pData, U8* pStatus);
void         JLINKARM_ReadMemU32(U32 Addr, U32 NumItems, U32* pData, U8* pStatus);
U32          JLINKARM_ReadReg (ARM_REG RegIndex);
void         JLINKARM_Reset(void);
void         JLINKARM_ResetPullsTRST (U8 OnOff);
void         JLINKARM_ResetPullsRESET(U8 OnOff);
void         JLINKARM_SelDevice(U16 DeviceIndex);
void         JLINKARM_SetBP(unsigned BPIndex, U32 Addr);
int          JLINKARM_SetEndian(int v);
int          JLINKARM_SetInitRegsOnReset(int v);
void         JLINKARM_SetMaxSpeed(void);
void         JLINKARM_SetResetDelay(int ms);
int          JLINKARM_SetResetPara(int Value);
void         JLINKARM_SetSpeed(int Speed);
char         JLINKARM_Step(void);
int          JLINKARM_Test(void);
U16          JLINKARM_UpdateFirmware(void);
U32          JLINKARM_UpdateFirmwareIfNewer(void);
int          JLINKARM_WaitDCCRead(int TimeOut);
int          JLINKARM_WriteDCC(const U32 * pData, U32 NumItems, int TimeOut);
void         JLINKARM_WriteDCCFast(const U32 * pData, U32 NumItems);
void         JLINKARM_WriteICEReg(int RegIndex, U32 Value, int AllowDelay);
char         JLINKARM_WriteReg(ARM_REG RegIndex, U32 Data);
void         JLINKARM_WriteMem(U32 addr, U32 count, const void * p);
void         JLINKARM_WriteMemDelayed(U32 Addr, U32 Count, const void * p);
void         JLINKARM_WriteU8 (U32 addr, U8 Data);
void         JLINKARM_WriteU16(U32 addr, U16 Data);
void         JLINKARM_WriteU32(U32 addr, U32 Data);

void          JLINKARM_EnableLogCom(void (*DebugFunc)(const char *));

 C#接口如下:


        /// <summary>
        /// 打开JLINK设备
        /// </summary>
        /// <remarks></remarks>
        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void JLINKARM_Open();


        /// <summary>
        /// 关闭JLINK设备
        /// </summary>
        /// <remarks></remarks>
        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void JLINKARM_Close();

        /// <summary>
        /// 连接设备
        /// </summary>
        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void JLINKARM_Connect();

        /// <summary>
        /// 开启RTT
        /// </summary>
        /// <param name="terminal"></param>
        /// <param name="size"></param>
        [DllImport("JLinkARM.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern UInt32 JLINK_RTTERMINAL_Control(UInt32 CMD, UInt32 size);

        /// <summary>
        /// 从RTT回读数据
        /// </summary>
        /// <param name="terminal"></param>
        /// <param name="rxBuffer"></param>
        /// <param name="len"></param>
        [DllImport("JLinkARM.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
        public static extern void JLINK_RTTERMINAL_Read(int terminal, [Out(), MarshalAs(UnmanagedType.LPArray)] byte[] rxBuffer, UInt32 size);


        static string gbk_ansi(string str)
        {
            string keyword;
            byte[] buffer = Encoding.GetEncoding("GB2312").GetBytes(str);
            keyword = Encoding.UTF8.GetString(buffer);
            return keyword;
        }

        public static string JLINKARM_ReadRTT_String()
        {
            try
            {
                byte[] aa = new byte[1000];
                JLINK_RTTERMINAL_Read(0, aa,1000);

               ASCIIEncoding kk = new ASCIIEncoding();
                //使用UTF-8编码
                UTF8Encoding uu = new UTF8Encoding();
                string ss = uu.GetString(aa);
                if(ss.Length>1)
                {
                    Console.Write(ss);
                }
                return ss;
            }
            catch(Exception ex)
            {

            }
            return String.Empty;

        }


        /// <summary>
        /// 写数据到RTT
        /// </summary>
        /// <param name="terminal"></param>
        /// <param name="txBuffer"></param>
        /// <param name="len"></param>
        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void JLINK_RTTERMINAL_Write(int terminal, [In(), MarshalAs(UnmanagedType.LPArray)] byte[] txBuffer, UInt32 size);




        /// <summary>
        /// 系统复位
        /// </summary>
        /// <remarks></remarks>
        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void JLINKARM_Reset();


        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void JLINKARM_GoAllowSim();


        /// <summary>
        /// 执行程序
        /// </summary>
        /// <remarks></remarks>
        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void JLINKARM_Go();


        /// <summary>
        /// 中断程序执行
        /// </summary>
        /// <returns></returns>
        /// <remarks></remarks>
        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern bool JLINKARM_Halt();

        /// <summary>
        /// 单步执行
        /// </summary>
        /// <returns></returns>
        /// <remarks></remarks>
        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern bool JLINKARM_Step();


        /// <summary>
        /// 清除错误信息
        /// </summary>
        /// <remarks></remarks>
        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void JLINKARM_ClrError();


        /// <summary>
        /// 设置JLINK接口速度
        /// </summary>
        /// <param name="speed"></param>
        /// <remarks>0为自动调整</remarks>
        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void JLINKARM_SetSpeed(int speed);


        /// <summary>
        /// 设置JTAG为最高速度
        /// </summary>
        /// <remarks></remarks>
        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void JLINKARM_SetMaxSpeed()
        ;

        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern UInt16 JLINKARM_GetSpeed()
       ;

        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern UInt32 JLINKARM_GetVoltage()
    ;

        /// <summary>
        /// 当前MCU是否处于停止状态
        /// </summary>
        /// <returns></returns>
        /// <remarks></remarks>
        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern bool JLINKARM_IsHalted()
        ;

        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern bool JLINKARM_IsConnected()
       ;

        /// <summary>
        /// JLINK是否已经可以操作了
        /// </summary>
        /// <returns></returns>
        /// <remarks></remarks>
        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern bool JLINKARM_IsOpen()
        ;

        /// <summary>
        /// 取消程序断点
        /// </summary>
        /// <param name="index">断点序号</param>
        /// <remarks>配合JLINKARM_SetBP()使用</remarks>
        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void JLINKARM_ClrBP(UInt32 index)
       ;

        /// <summary>
        /// 设置程序断点
        /// </summary>
        /// <param name="index">断点序号</param>
        /// <param name="addr">目标地址</param>
        /// <remarks>建议使用JLINKARM_SetBPEx()替代</remarks>
        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void JLINKARM_SetBP(UInt32 index, UInt32 addr)
        ;

        /// <summary>
        /// 设置程序断点
        /// </summary>
        /// <param name="addr">目标地址</param>
        /// <param name="mode">断点类型</param>
        /// <returns>Handle,提供给JLINKARM_ClrBPEx()使用</returns>
        /// <remarks></remarks>
        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern int JLINKARM_SetBPEx(UInt32 addr, BP_MODE mode)
      ;
        /// <summary>
        /// 取消程序断点
        /// </summary>
        /// <param name="handle"></param>
        /// <remarks>配合JLINKARM_SetBPEx()使用</remarks>
        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void JLINKARM_ClrBPEx(int handle)
        ;

        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        private static extern int JLINKARM_SetWP(UInt32 addr, UInt32 addrmark, UInt32 dat, UInt32 datmark, byte ctrl, byte ctrlmark)
        ;

        /// <summary>
        /// 取消数据断点
        /// </summary>
        /// <param name="handle"></param>
        /// <remarks>配合JLINKARM_SetWP()使用</remarks>
        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void JLINKARM_ClrWP(int handle)
        ;

        /// <summary>
        /// 设置寄存器
        /// </summary>
        /// <param name="index"></param>
        /// <param name="dat"></param>
        /// <remarks></remarks>
        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void JLINKARM_WriteReg(ARM_REG index, UInt32 dat)
       ;

        /// <summary>
        /// 读取寄存器
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern UInt32 JLINKARM_ReadReg(ARM_REG index)
        ;

        /// <summary>
        /// 写入一段数据
        /// </summary>
        /// <param name="addr"></param>
        /// <param name="size"></param>
        /// <param name="buf"></param>
        /// <remarks></remarks>
        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void JLINKARM_WriteMem(UInt32 addr, UInt32 size, byte[] buf)
        ;

        /// <summary>
        /// 读取一段数据
        /// </summary>
        /// <param name="addr"></param>
        /// <param name="size"></param>
        /// <param name="buf"></param>
        /// <remarks></remarks>
        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void JLINKARM_ReadMem(UInt32 addr, UInt32 size, [Out(), MarshalAs(UnmanagedType.LPArray)] byte[] buf)
        ;

        /// <summary>
        /// 从调试通道获取一串数据
        /// </summary>
        /// <param name="buf"></param>
        /// <param name="size">需要获取的数据长度</param>
        /// <remarks></remarks>
        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void JLINKARM_ReadDCCFast([Out(), MarshalAs(UnmanagedType.LPArray)] UInt32[] buf, UInt32 size)
       ;

        /// <summary>
        /// 从调试通道获取一串数据
        /// </summary>
        /// <param name="buf"></param>
        /// <param name="size">希望获取的数据长度</param>
        /// <param name="timeout"></param>
        /// <returns>实际获取的数据长度</returns>
        /// <remarks></remarks>
        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern UInt32 JLINKARM_ReadDCC([Out(), MarshalAs(UnmanagedType.LPArray)] UInt32[] buf, UInt32 size, int timeout)
        ;

        /// <summary>
        /// 向调试通道写入一串数据
        /// </summary>
        /// <param name="buf"></param>
        /// <param name="size">需要写入的数据长度</param>
        /// <remarks></remarks>
        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void JLINKARM_WriteDCCFast(UInt32[] buf, UInt32 size)
        ;

        /// <summary>
        /// 向调试通道写入一串数据
        /// </summary>
        /// <param name="buf"></param>
        /// <param name="size">希望写入的数据长度</param>
        /// <param name="timeout"></param>
        /// <returns>实际写入的数据长度</returns>
        /// <remarks></remarks>
        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern UInt32 JLINKARM_WriteDCC(UInt32[] buf, UInt32 size, int timeout)
        ;

        /// <summary>
        /// 获取JLINK的DLL版本号
        /// </summary>
        /// <returns></returns>
        /// <remarks>使用10进制数表示</remarks>
        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern UInt32 JLINKARM_GetDLLVersion()
       ;

        /// <summary>
        /// 执行命令
        /// </summary>
        /// <param name="oBuffer"></param>
        /// <param name="a"></param>
        /// <param name="b"></param>
        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void JLINKARM_ExecCommand([In(), MarshalAs(UnmanagedType.LPArray)] byte[] oBuffer,int a,int b);

        /// <summary>
        /// 选择接口,0是JTAG 1是SWD
        /// </summary>
        /// <param name="type"></param>
        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void JLINKARM_TIF_Select(int type);





        /// <summary>
        /// 获取JLINK的固件版本号
        /// </summary>
        /// <returns></returns>
        /// <remarks></remarks>
        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern UInt32 JLINKARM_GetHardwareVersion()
        ;
        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        private static extern void JLINKARM_GetFeatureString([Out(), MarshalAs(UnmanagedType.LPArray)] byte[] oBuffer)
       ;

        [DllImport("JLinkARM.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        private static extern void JLINKARM_GetOEMString([Out(), MarshalAs(UnmanagedType.LPArray)] byte[] oBuffer)
        ;

        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void JLINKARM_SetLogFile([In(), MarshalAs(UnmanagedType.LPArray)] byte[] oBuffer)
;


        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern StringBuilder JLINKARM_GetCompileDateTime()
        ;

        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern UInt32 JLINKARM_GetSN()
        ;

        /// <summary>
        /// 获取当前MCU的ID号
        /// </summary>
        /// <returns></returns>
        /// <remarks></remarks>
        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern UInt32 JLINKARM_GetId()
        ;

        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        private static extern void JLINKARM_ReadMemU32(UInt32 addr, UInt32 leng, ref UInt32 buf, ref byte status)
       ;

        /// <summary>
        /// 写入32位的数据
        /// </summary>
        /// <param name="addr"></param>
        /// <param name="dat"></param>
        /// <remarks></remarks>
        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void JLINKARM_WriteU32(UInt32 addr, UInt32 dat)
      ;

        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        private static extern void JLINKARM_ReadMemU16(UInt32 addr, UInt32 leng, ref UInt16 buf, ref byte status)
       ;
        /// <summary>
        /// 写入16位的数据
        /// </summary>
        /// <param name="addr"></param>
        /// <param name="dat"></param>
        /// <remarks></remarks>
        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void JLINKARM_WriteU16(UInt32 addr, UInt16 dat)
  ;

        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        private static extern void JLINKARM_ReadMemU8(UInt32 addr, UInt32 leng, ref byte buf, ref byte status)
;

        /// <summary>
        /// 写入8位的数据
        /// </summary>
        /// <param name="addr"></param>
        /// <param name="dat"></param>
        /// <remarks></remarks>
        [DllImport("JLinkARM.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void JLINKARM_WriteU8(UInt32 addr, byte dat)
       ;

有了这个接口便可以调用连接jlink了,例如:

            Console.WriteLine("Jlink操作演示");
            JLinkHandler.JLINKARM_SetLogFile(System.Text.Encoding.UTF8.GetBytes("this_log.txt"));
            JLinkHandler.JLINKARM_Open();
            var ver = JLinkHandler.JLINKARM_GetDLLVersion();
            Console.WriteLine("DLL 版本: "+ver);
            Console.WriteLine("SN:" + JLinkHandler.JLINKARM_GetSN());
            Console.WriteLine("硬件版本: " + JLinkHandler.JLINKARM_GetHardwareVersion());
            JLinkHandler.JLINKARM_ExecCommand(System.Text.Encoding.UTF8.GetBytes("device = STM32H743VI"), 0, 0);
            JLinkHandler.JLINKARM_TIF_Select(1);
            JLinkHandler.JLINKARM_SetSpeed(4000);
            Console.WriteLine("CPU ID: "+JLinkHandler.JLINKARM_GetId());

可惜的是,并没有直接下载hex文件的接口,这就需要先了解hex文件的结构,进行进一步解析,再调用接口写到对应的地址下。这里有参考文章:

STM32的烧录和Hex/bin烧录文件解析、烧录文件是被如何存储到MCU中的?_stm32 bin文件解析-CSDN博客

hex文件内含有地址和数据,软件解析地址并烧录数据,烧录完毕之后,调用:JLINKARM_Go();,程序成功执行,搞了好几天终于成功了,记录一下。

  • 10
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
### 回答1: jlink是一款常用的调试和烧录工具,同时也支持反汇编功能。使用jlink反汇编工具可以将目标设备中的代码转化为汇编语言,进而进行分析和调试。 jlink反汇编工具的使用需要jlink驱动支持,其中jlinkarm.dll是jlink驱动中的关键组件之一。为了实现更多的功能,有些开发者甚至对jlinkarm.dll进行了修改,从而增加更多的自定义功能和定制化操作。 自定义的jlinkarm.dll驱动文件可以用于不同的环境和需求,例如用于自动化测试、用于处理特殊类型的程序等等。不过,在使用自定义的驱动文件时需要注意一些安全问题,避免对目标设备的损害和意外发生。 总之,jlink反汇编工具及其修改后的jlinkarm.dll驱动文件是开发者日常工作中不可或缺的工具,能够帮助开发者更好地理解和处理目标设备中的代码,提高工作效率和开发质量。 ### 回答2: JLink反汇编工具是一款功能强大的反汇编软件,可用于分析和修改ARM芯片的代码。它能够读取和解析各种格式的ELF、COFF、S-record和Intel HEX文件。此外,它还支持标准的ARM和Thumb指令集,允许用户以汇编语言形式查看CPU的指令执行过程。 在使用JLink反汇编工具时,需要注意几点。首先,软件需要与JLink调试器配合使用,才能实现调试和烧录操作。其次,用户需要了解ARM芯片的指令集和寄存器结构,才能正确地解析和分析反汇编结果。最后,用户需谨慎使用修改功能,以免导致系统故障或数据损失。 针对JLink反汇编工具的修改,主要是对其驱动文件jlinkarm.dll进行优化和定制。通过修改驱动文件,用户可以增加或修改JLink调试器的功能,例如支持新的芯片型号、优化烧录速度、增加调试接口等。要修改驱动文件,需要具备一定的编程能力和相关知识,同时必须遵守软件使用和代码保护规定。 总之,JLink反汇编工具及其修改后的jlinkarm.dll驱动文件是ARM芯片开发和调试过程中的重要工具,用户可以根据需要选择合适的版本和配置,以提高工作效率和代码质量。 ### 回答3: jlink是基于ARM架构的仿真器,可以用于调试和开发处理器相关的程序。而反汇编工具是一种将二进制代码转化为汇编代码的工具。jlink反汇编工具就是针对jlink仿真器设计的反汇编工具。 jlink可以运行不同的固件,针对不同的处理器,而jlinkarm.dll驱动文件是jlink仿真器的驱动文件之一,用于加载不同的固件。这个驱动文件是可修改的,可以根据需要进行适当的更改。例如,可以修改驱动文件以支持新的处理器或新的调试接口,也可以修改驱动文件以添加一些调试功能。 但是需要指出的是,修改驱动文件可能会带来风险和不稳定性,可能会导致调试错误或设备故障。因此,建议只有在有经验并且遵循相关的安全措施的情况下,才尝试修改jlinkarm.dll驱动文件。 总的来说,jlink反汇编工具及其修改后的jlinkarm.dll驱动文件是对于ARM架构开发者非常有用的工具,在开发、调试、优化处理器相关的程序时,可以大大提高效率和准确性。但是,需要注意的是,使用这些工具需谨慎,尤其是在修改驱动文件时,需要谨慎操作,以避免不必要的风险。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值