在嵌入式开发过程中用的比较多的是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() # 进入消息循环
本文介绍了在嵌入式开发中如何利用Python控制JLink工具读取STM32芯片内部数据,通过指定地址实现数据的便捷获取。
875

被折叠的 条评论
为什么被折叠?



