3、python获取jlink数据显示

本文介绍了在嵌入式开发中如何利用Python控制JLink工具读取STM32芯片内部数据,通过指定地址实现数据的便捷获取。

在嵌入式开发过程中用的比较多的是jlink烧写程序,有时需要通过jlink直接读取芯片内的数据
因此借用python工具去获取,并可以抓取任何想要的数据,就是直接读取地址就可以获取到。
电脑安装的jlink可以直接打开用
在这里插入图片描述
在这里插入图片描述
通过对应的命令既可以控制jlink读写数据
在这里插入图片描述

import pylink
import re, threading,time
from tkinter import filedialog  # 路径选择
from tkinter import *
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
from matplotlib.figure import Figure
import numpy as np
import tkinter
import os
from tkinter.messagebox import *
pwd = os.getcwd()
main_path=pwd + '\\save_wave\\'#文件保存路径,如果不存在就会被重建
if  not os.path.exists(main_path):#如果路径不存在
    os.makedirs(main_path)
'''参数'''
print('参数解析')

if 1:
    filepath = r'param.log'
    logfile = open(filepath, 'r',encoding="utf-8")
    line = logfile.readline()
    print(line)
    SN = re.findall(r"SN:([0-9]+)", line)[0]
    line = logfile.readline()
    print(line)
    dev_id = re.findall(r"DEV:([-a-zA-Z0-9_]+)", line)[0]
    line = logfile.readline()
    print(line)
    show_num = int(re.findall(r"SHOWNUM:([0-9]+)", line)[0])
    line = logfile.readline()
    print(line)
    addr_32 = int(re.findall(r"ADDR_32:([a-zA-Z0-9]+)", line)[0],16)
    line = logfile.readline()
    print(line)
    up_limit = int(re.findall(r"UP:([-0-9]+)", line)[0])
    line = logfile.readline()
    print(line)
    down_limit = int(re.findall(r"DOWN:([-0-9]+)", line)[0])
    line = logfile.readline()
    print(line)
    judge_32 = int(re.findall(r"JUDGE_32:([a-zA-Z0-9]+)", line)[0],16)
    line = logfile.readline()
    print(line)
    judge_cmd = re.findall(r"JUDGE_CMD:(.+)", line)[0]
    print("SN {} DEV {} shownum = {} addr32 = {} judge_32 {} up_limit {}  down_limit {} judge_cmd {}".format(SN,dev_id,show_num,addr_32,judge_32,up_limit,down_limit,judge_cmd))
    logfile.close()

root = Tk()  # 创建窗口对象的背景色
root.title("JlinkCapture")
root.geometry('700x500')
# root.iconbitmap('Jlink.ico')
 #按钮
# button = Button(root,text='选择文件',bg='lightblue',width=10,command=get_xl)
# button.place(x=400,y=1)

'''jlink'''
myJLINK = pylink.JLink()
'''59800879     59701276    4294967295'''
# myJLINK.open('59800879')
myJLINK.open(SN)
myJLINK.set_tif(pylink.enums.JLinkInterfaces.SWD)
myJLINK.connect(dev_id)

f = Figure(figsize=(1, 1), dpi=100)
fig1=f.add_subplot(211)
fig2=f.add_subplot(212)

canvas = FigureCanvasTkAgg(f, master=root)

canvas.get_tk_widget().pack(side=tkinter.BOTTOM, # 上对齐
fill=tkinter.BOTH, # 填充方式
expand=tkinter.YES) # 随窗口大小调整而调整

toolbar = NavigationToolbar2Tk(canvas, root)
toolbar.update()
canvas._tkcanvas.pack(side=tkinter.TOP, # get_tk_widget()得到的就是_tkcanvas
fill=tkinter.BOTH,
expand=tkinter.YES)
flag_start = True
show_data = []
show_data2 = []
t = []
time_record = []
max_show_num = 1000000
lock = threading.Lock()  # 申请一把锁
def is_number(s):
    try:
        float(s)
        return True
    except ValueError:
        pass
    try:
        import unicodedata
        unicodedata.numeric(s)
        return True
    except (TypeError, ValueError):
        pass
    try:
        int(s,16)
        return True
    except (TypeError, ValueError):
        pass
    return False


'''实时刷新显示波形数据'''
def show_plot():

    global show_data,t,fig1,canvas,flag_start,show_data2
    if flag_start:
        with lock:  # with模块自动加锁及解锁
            show_data_thd = show_data
            show_data_thd2 = show_data2
            t_thd = t
        if t_thd != []:
            fig1.clear()
            fig2.clear()
            fig1.plot(t_thd, show_data_thd,label='first_data',color='red')
            fig2.plot(t_thd, show_data_thd2,label='two_data',color='blue')
            fig1.grid(linestyle='-.')
            fig2.grid(linestyle='-.')

            fig1.text(t_thd[len(t_thd) - 1], show_data_thd[len(t_thd) - 1], show_data_thd[len(t_thd) - 1],
                      ha='center', va='bottom', fontsize=10)
            fig1.axhline(y=show_data_thd[len(t_thd) - 1], ls=":", c="yellow")  # 添加水平直线

            fig1.text((t_thd[int(len(t_thd)/2)]), show_data_thd[int(len(t_thd)/2)], show_data_thd[int(len(t_thd)/2)],
                      ha='center', va='bottom', fontsize=10)
            fig1.axhline(y=show_data_thd[int(len(t_thd)/2)], ls=":", c="green")  # 添加水平直线

            fig1.text( t_thd[0], show_data_thd[0], show_data_thd[0],
                      ha='center', va='bottom', fontsize=10)
            fig1.axhline(y=show_data_thd[0], ls=":", c="red")  # 添加水平直线




            fig2.text(t_thd[len(t_thd) - 1], show_data_thd2[len(t_thd) - 1], show_data_thd2[len(t_thd) - 1],
                      ha='center', va='bottom', fontsize=10)
            fig2.axhline(y=show_data_thd2[len(t_thd) - 1], ls=":", c="yellow")  # 添加水平直线

            fig2.text((t_thd[int(len(t_thd) / 2)]), show_data_thd2[int(len(t_thd) / 2)],
                      show_data_thd2[int(len(t_thd) / 2)],
                      ha='center', va='bottom', fontsize=10)
            fig2.axhline(y=show_data_thd2[int(len(t_thd) / 2)], ls=":", c="green")  # 添加水平直线

            fig2.text(t_thd[0], show_data_thd2[0], show_data_thd2[0],
                      ha='center', va='bottom', fontsize=10)
            fig2.axhline(y=show_data_thd2[0], ls=":", c="red")  # 添加水平直线


            fig1.legend()
            fig2.legend()
            # fig1.set_xlabel("t")
            # fig1.set_ylabel("tag")
            fig1.set_title('JlinkSN: ' + SN)
    canvas.draw()
    global afterHandler
    afterHandler = root.after(10, show_plot)

def flush_show():
    # toolbar.update()
    root.update()
    global afterHandler1
    afterHandler1 = root.after(1000, flush_show)

flush_show()
err_flag = 0
real_time = ''
def set_err():
    global err_flag
    err_flag = 1
'''实时获取数据'''
def get_data(n):
    i = 0
    j = 0
    protect_max_time = 0
    global show_data, t,myJLINK,show_num,flag_start,judge_cmd,err_flag,code,show_data2,max_show_num,time_record,real_time
    while 1:
        if flag_start:
            data = myJLINK.memory_read32(addr_32, 1)
            judge_data = myJLINK.memory_read32(judge_32, 1)
            result = judge_data[0]

            # if data[0] > protect_max_time :
            #     protect_max_time = data[0]
            #     print('protect_max_time = ',protect_max_time)

            with lock:  # with模块自动加锁及解锁
                show_data.append(data[0])
                show_data2.append(judge_data[0])
                t.append(i)
                time_record.append(real_time)
                i += 1
                if( len(t) >=show_num ):
                    for n in range(len(t)-show_num):
                        t.pop(0)
                        show_data.pop(0)
                        show_data2.pop(0)
                        time_record.pop(0)
                if( i > max_show_num ):
                    temp = t[0]
                    for n in range(len(t)):
                        t[n] -= temp
                    # print(t)
                    i = show_num

                if show_data[len(show_data)-1] > up_limit or show_data[len(show_data)-1] < down_limit :
                    err_flag = 1

                code = 'if(' + judge_cmd + '):set_err()'

                # print(result,  code , err_flag)
                try:
                    exec(code)
                except ValueError:
                    judge_cmd = '0'
                    showerror('错误', '判断语句不规则!')
                    pass
                if err_flag == 1:
                    j += 1
                    if j >= show_num / 2:
                        j = 0
                        err_flag = 0

                        on_key_event()
        else:
            i = 0
            j = 0
            time.sleep(1)

show_plot()
t2 = threading.Thread(target=get_data, args=("t2",))
t2.setDaemon(True)  # 把子进程设置为守护线程,必须在start()之前设置
t2.start()
filename = ''
'''键盘事件处理'''
def on_key_event():
    print('你按了')
    global flag_start,show_data,SN,button,filename,t,err_flag,show_data2,time_record
    flag_start = not flag_start
    if not flag_start :
        now = time.strftime("%Y-%m-%d_%H_%M_%S")
        print(now)
        filename = main_path+'SN_'+SN+'_'+now+'.txt'
        print(filename)
        entry_file.set(filename)
        file = open(filename, 'w')
        file.write('时间                      序号             数据地址数据           判断地址数据\n')
        for i in range(len(show_data)):
            file.write(time_record[i]+'             '+str(t[i])+'             '+str(show_data[i])+'             '+str(show_data2[i])+'\n')
        file.close()
        entry_var2.set('启动')
    else:
        show_data = []
        show_data2 = []
        t = []
        time_record = []
        entry_var2.set('停止')

    root.update()
    # t1 = threading.Thread(target=show_plot, args=("t1",))
    # t1.setDaemon(True)  # 把子进程设置为守护线程,必须在start()之前设置
    # t1.start()
def open_file():
    global filename
    if filename == '':
        return
    os.startfile(filename)
def get_time(n):
    '''显示当前时间'''
    global entry_time,real_time
    while 1:
        with lock:
            real_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
        entry_time.set(real_time)
        time.sleep(0.5)



def key_num():

    global show_num,entry_var,down_limit,up_limit,addr_32,judge_32,judge_cmd,code,max_show_num
    var = entry_var.get()  # 调用get()方法,将Entry中的内容获取出来
    var_up = entry_up.get()  # 调用get()方法,将Entry中的内容获取出来
    var_down = entry_down.get()  # 调用get()方法,将Entry中的内容获取出来
    var_addr = entry_addr.get()  # 调用get()方法,将Entry中的内容获取出来
    var_addr_judge = entry_judge.get()  # 调用get()方法,将Entry中的内容获取出来
    var_addr_judge_cmd = entry_cmd.get()
    print(var)
    print('修改显示的数据量:')
    if is_number(var):
        print('show_num = ', var)
        with lock:
            show_num = int(var)
            if max_show_num < show_num:
                show_num = max_show_num
                # showwarning('警告', '明日有大雨')
                # showwarning('警告', '显示点数最大为'+ str(max_show_num))
    else:
        entry_var.set('输入错误!请输入数字')
        print('输入错误!')

    if is_number(var_up):
        print('up_limit = ', var_up)
        with lock:
            up_limit = int(var_up)
    else:
        entry_up.set('输入错误!请输入数字')
        print('输入错误!')

    if is_number(var_down):
        print('down_limit = ', var_down)
        with lock:
            down_limit = int(var_down)
    else:
        entry_down.set('输入错误!请输入数字')
        print('输入错误!')

    if is_number(var_addr):
        print('addr_32 = ', var_addr)
        with lock:
            addr_32 = int(var_addr,16)
    else:
        entry_addr.set('输入错误!请输入数字')
        print('输入错误!')

    if is_number(var_addr_judge):
        print('judge_32 = ', var_addr_judge)
        with lock:
            judge_32 = int(var_addr_judge, 16)
    else:
        entry_judge.set('输入错误!请输入数字')
        print('输入错误!')


    print(re.findall(r"(result)", var_addr_judge_cmd))
    if re.findall(r"(result)", var_addr_judge_cmd) != '' or var_addr_judge_cmd == '0':
        print('judge_cmd = ', var_addr_judge_cmd)
        with lock:
            judge_cmd = var_addr_judge_cmd
    else:
        entry_cmd.set('输入错误!请按格式输入')
        print('输入错误!')

frame_1 = Frame(root)
frame_1.pack(fill=X)
width = 29
label_1 = Label(frame_1,text='显示数量:').grid(row=0,column=0)

entry_var = tkinter.StringVar()
entry  = tkinter.Entry(master=frame_1,width=width,textvariable=entry_var).grid(row=0,column=1)
entry_var.set(show_num)

label_2 = Label(frame_1,text='报警上限:').grid(row=0,column=2)

entry_up = tkinter.StringVar()
entry2  = tkinter.Entry(master=frame_1,width=width,textvariable=entry_up).grid(row=0,column=3)
entry_up.set(up_limit)

label_5 = Label(frame_1,text='数据地址:').grid(row=1,column=0)

entry_addr = tkinter.StringVar()
entry5  = tkinter.Entry(master=frame_1,width=width,textvariable=entry_addr).grid(row=1,column=1)
entry_addr.set(hex(addr_32))


label_3 = Label(frame_1,text='报警下限:').grid(row=1,column=2)

entry_down = tkinter.StringVar()
entry3  = tkinter.Entry(master=frame_1,width=width,textvariable=entry_down).grid(row=1,column=3)
entry_down.set(down_limit)


label_6 = Label(frame_1,text='判断地址:').grid(row=2,column=0)

entry_judge = tkinter.StringVar()
entry6  = tkinter.Entry(master=frame_1,width=width,textvariable=entry_judge).grid(row=2,column=1)
entry_judge.set(hex(judge_32))

label_7 = Label(frame_1,text='判断条件:').grid(row=2,column=2)

entry_cmd = tkinter.StringVar()
entry7  = tkinter.Entry(master=frame_1,width=width,textvariable=entry_cmd).grid(row=2,column=3)
entry_cmd.set(judge_cmd)



button_num = tkinter.Button(master=frame_1, text='设置参数', command=key_num).grid(row=0,column=4,rowspan=3, sticky=W+E+N+S, padx=5, pady=5)


# frame_2 = Frame(root)
# frame_2.pack(fill=X)

label_4 = Label(frame_1,text='数据路径:').grid(row=3,column=0)
entry_file = tkinter.StringVar()
entry4  = tkinter.Entry(master=frame_1,width=67,textvariable=entry_file,justify = 'right').grid(row=3,column=1,columnspan=3)
entry_file.set('')


button_open = tkinter.Button(master=frame_1, text='打开文件', command=open_file).grid(row=3,column=4)



entry_time = tkinter.StringVar()
label_time = Label(frame_1,textvariable=entry_time).grid(row=4,column=0,columnspan=2)
entry_time.set(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) )

label_ver = Label(frame_1,text='wql20210716').grid(row=4,column=2)

entry_var2 = tkinter.StringVar()
button = tkinter.Button(master=frame_1, textvariable=entry_var2,width=20, command=on_key_event).grid(row=4,column=3,columnspan=2)
entry_var2.set('停止')

time_thread = threading.Thread(target=get_time, args=("time_thread",))
time_thread.setDaemon(True)  # 把子进程设置为守护线程,必须在start()之前设置
time_thread.start()
root.mainloop()  # 进入消息循环

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿Q学长

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值