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

这篇具有很好参考价值的文章主要介绍了自己开发jlink烧录软件,烧录上位机, C#调用JLinkARM.dll实现软件烧录。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

1.命令行烧录

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

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

c# jlink ob,上位机研究,c#,开发语言,单片机

既然可以用这个命令行,那就可以用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();,程序成功执行,搞了好几天终于成功了,记录一下。文章来源地址https://www.toymoban.com/news/detail-848068.html

到了这里,关于自己开发jlink烧录软件,烧录上位机, C#调用JLinkARM.dll实现软件烧录的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • C# | 上位机开发新手指南(二)上位机通信

    C# | 上位机开发新手指南(二)上位机通信

    在上位机开发中,串口通信和TCP通信是两种常见的通信方式。串口通信是指通过串口将数据发送和接收到控制器或其他外设中,TCP通信则是通过网络将数据传输到远程设备中。下面介绍一下为什么学习串口通信和TCP通信在上位机开发中是很重要的。 在许多工业自动化控制系统

    2024年02月07日
    浏览(29)
  • C#上位机开发目录

    C#上位机序列1: 多线程(线程同步,事件触发,信号量,互斥锁,共享内存,消息队列) C#上位机序列2: 同步异步(async、await) C#上位机序列3: 流程控制(串行,并行,混合) C#上位机序列4: 动画效果(模拟PLC设备运行) C#上位机序列5: 三菱通信(FX-3U SerialOverTcp) C#上位机序列

    2024年02月09日
    浏览(10)
  • 对stm32程序(HEX)的读取和烧录(使用JLink和JFlash)

    对stm32程序(HEX)的读取和烧录(使用JLink和JFlash)

    本文主要讲解:使用J-LinK仿真器,借助于J-Flash软件,如何读取现有的stm32内部的程序(HEX文件),并烧录到另一台新的stm32中。 (前提是原stm32未进行加密处理) 先介绍下载器 J-LinK  和 软件 J-Flash : 上一篇介绍了 J-LinK-OB改造版 仿真/调试器 使用说明: J-LinK-OB改造版 仿真

    2024年02月05日
    浏览(78)
  • C# WPF上位机开发(键盘绘图控制)

    C# WPF上位机开发(键盘绘图控制)

    【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】         在软件开发中,如果存在canvas图像的话,一般有几种控制方法。一种是鼠标控制;一种是键盘控制;还有一种是定时器控制。定时器控制,多常见动画、游戏、3d视频当中。而鼠标控制

    2024年02月02日
    浏览(10)
  • C# | 上位机开发新手指南(一)概述

    C# | 上位机开发新手指南(一)概述

    C#,是微软主推的编程语言。它在工业控制、自动化、物联网等领域应用非常广泛。由于国内在工业控制领域技术发展路径的原因,早期的自动化控制面板由Window环境提供,大量的MFC、VB6控制应用被部署在了工厂车间。在用户习惯和界面环境的双料加持下,给C#在工业领域的推

    2024年02月03日
    浏览(13)
  • C# 三菱PLC上位机开发环境搭建

    C# 三菱PLC上位机开发环境搭建

    一、安装软件 用到两个三菱的软件: 1. MX Component(下载地址 也可以直接在官网上搜索,注意MX后面有空格) 用于连接PLC 2. GX Works2(下载地址 用GX Works3也行) 这个软件主要是电气做PLC编程,我们用来作为仿真,省去开发时摆弄真实PLC 序列号:117-570766844 二、配置软件 MX

    2023年04月18日
    浏览(11)
  • C# 上位机之海康相机开发(SDK)

    C# 上位机之海康相机开发(SDK)

    发现工作中好多计算机视觉上位机项目都用海康相机,为了能够更好的学习和工作,我自己依据同事的源码和网上的一些总结编写本博客。通过本次学习,让我明白一点,无论学习什么技术都要学会自己看技术文档,而不是第一时间上网找源码。以工业相机SDK使用说明.chm为例

    2024年02月03日
    浏览(10)
  • JLINK和STlink使用SWD接口时连接或烧录出现故障解决问题根源解决办法

    JLINK和STlink使用SWD接口时连接或烧录出现故障解决问题根源解决办法

    在使用stm32f103c8t6最小系统板时,我分别用了两款仿真器,jlink和stlink。我发现这两款仿真器使用时均出现了相似的问题: 1.我在使用jlink或者stlink时的接线方式是  在keil中发现能够识别到芯片,但是有时改变频率芯片就识别不到了,同样有时识别不到芯片,改变频率就能识别

    2024年02月12日
    浏览(13)
  • Odrive 学习系列二:将烧录工具从ST-Link V2修改为JLink

    Odrive 学习系列二:将烧录工具从ST-Link V2修改为JLink

    一、背景:         通过观察odrive解压后的内容,可以看到在下面配置文件及makefile文件中的配置设置的均为openOCD + stlink v2,例如makefile中: 但是考虑JLink具备调试窗口,因此个人还是更倾向于使用JLink。那么下面就来尝试修改这些配置文件,将烧录调试工具改为J-Link. 二

    2024年01月16日
    浏览(44)
  • C# WPF上位机开发(Web API联调)

    【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】         很多时候,客户需要开发的不仅仅是一个上位机系统,它还有其他很多配套的系统或设备,比如物流小车、立库、数字孪生等一整套系统。这个时候,上位机系统就需要和各个子系统

    2024年01月20日
    浏览(11)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包