├── .gitignore
├── .idea
├── .gitignore
├── inspectionProfiles
│ └── profiles_settings.xml
├── misc.xml
├── modules.xml
├── rtt-py.iml
└── vcs.xml
├── JLinkARM.dll
├── LICENSE
├── README.md
├── __pycache__
├── main.cpython-38.pyc
├── main.cpython-39.pyc
└── qpt.cpython-39.pyc
├── apple.ico
├── apple.png
├── config.json
├── image
├── 1.gif
├── 2.gif
└── 3.png
├── main.py
├── main.spec
├── rtt-t.log
└── windows icon update.bat
/.gitignore:
--------------------------------------------------------------------------------
1 | dist
2 | build
3 | rtt-t.log
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/rtt-py.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/JLinkARM.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liuhao1946/RTT-T-Project/08b1b2f055ce7fc9f203bd6ea5917707e494e71e/JLinkARM.dll
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 bds123
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # RTT(Real Time Transfer) Tool(RTT-T)
2 | ---
3 |
4 | [RTT-T下载地址(windows平台)](https://github.com/liuhao1946/RTT-T-Project/releases)
5 |
6 | ### 描述
7 | 这是一个**J-Llink RTT**软件,用来接收由MCU通过SEGGER RTT发送的数据。相比官方J-Llink RTT Viewer软件,该软件有以下特点:
8 | * 使用python基于**PySampleGUI**编写
9 |
10 | * 接收RTT信息后能附带时间戳
11 | * 不会自动清除数据框中的数据,是否清除以及什么时候清除将由自己决定
12 | * 支持一键保存数据框中的所有数据
13 | * 支持实时记录数据到文件
14 | * 向上滚动鼠标滚动轮就能停止在当前界面。向下将滚动条滚到最低端就能实时看到当前接收到的数据
15 | * 每次连接J-Link都会复位MCU
16 | * 同步电脑时间到MCU
17 | * 通过RTT-T发送自定义数据到MCU
18 |
19 | ---
20 | ### 软件更新说明
21 | 当前最新版本为v1.5,相比v1.3版本,有以下不同
22 | * 修补了v1.3版本的bug
23 |
24 | * 当软件内部出现异常时,能够将详细的异常信息输出到rtt-t.log中
25 |
26 | 
27 |
28 | ---
29 | ### RTT-T功能演示
30 |
31 | 
32 |
33 | ---
34 | ### RTT-T的使用说明
35 | * RTT-T自身打印出来的信息是开头带有LOG:xxx的字符串
36 |
37 | * RTT-T使用的是**0数据通道**,这意味着MCU也必须使用SEGGER RTT的**0数据通道**
38 |
39 | ```c
40 | SEGGER_RTT_printf(0,"test\n");
41 | ```
42 |
43 | * 如果MCU端要获得到RTT-T的数据,有两个地方需要留意
44 | 1. 将MCU中RTT模块的接收缓存设置到合适的长度
45 |
46 | 2. MCU在程序中做如下轮训调用,以查询RTT发送过来的数据:
47 | ```c
48 | #include "string.h"
49 |
50 | uint8_t rtt_rx_data[33];
51 |
52 | void str_to_int(char *p, int32_t *pv)
53 | {
54 | uint8_t sign;
55 | char c;
56 |
57 | sign = *p;
58 | if (p[0] == '-' || p[0] == '+')
59 | {
60 | p++;
61 | }
62 | *pv = 0;
63 | while (*p >= '0' && *p <= '9')
64 | {
65 | c = *p++;
66 | *pv = *pv * 10 + (c-'0');
67 | }
68 |
69 | *pv = (sign != '-') ? *pv: -(*pv);
70 | }
71 |
72 | void timer_10ms(void )
73 | {
74 | uint8_t len;
75 |
76 | len = SEGGER_RTT_Read(0, rtt_rx_data, 32);
77 | rtt_rx_data[len] = 0;
78 |
79 | if(len > 0)
80 | {
81 | char *p;
82 | char temp[6];
83 | uint8_t time[6];
84 | int32_t temp_dt;
85 |
86 | p = strstr(rtt_rx_data, "time syn:");
87 | //time syn:2022-01-16-16-27-30
88 | if(p != 0)
89 | {
90 | uint8_t i;
91 |
92 | p = p + 11;
93 | memset(temp,0,6);
94 | //字符串时间转换为整形,结果保存在time中
95 | for(i = 0; i < 6; i++)
96 | {
97 | memcpy(temp,p,2);
98 | str_to_int(temp, &temp_dt);
99 | time[i] = temp_dt;
100 | p += 3;
101 | }
102 |
103 | }
104 |
105 | }
106 | }
107 | ```
108 |
109 | * 如果需要同步电脑时间到MCU
110 | 1. 连接J-Llink
111 |
112 | 2. 在Text Data输入框中输入字符串指令"cmd:time syn"(软件默认)
113 |
114 | 3. 点击Send按钮,RTT-T会将如下字符串格式的电脑时间发送到MCU
115 |
116 | "time syn:2022-01-16-15-08-05"
117 |
118 | * 打开**实时数据保存**或者**保存数据框中的全部数据**时,RTT-T会自动在应用程序所在目录创建文件
119 |
120 | 实时数据保存的文件名称:real_time_log_xxx(xxx为年月日时分秒)
121 |
122 | 保存数据框中的全部数据文件名称:log_xxx(xxx为年月日时分秒)
123 |
124 | * Rx Timeout参数的说明
125 | 这个参数的含义是在RTT-T每次接收到一笔数据(≥1)后,RTT-T都会等待Rx Timeout(ms)。在Rx Timeout内接收到的数据RTT-T认为是一包数据。当超过Rx Timeout后,RTT-T就会为这包数据打上一个时间戳(如果时间戳打开的话)。这可以更好的辅助RTT-T在合适的数据位置打上时间戳。
126 |
127 | 如果Rx Timeout = 0,表示RTT-T不使用超时机制,这可能造成的一个问题是时间戳的位置打的不准。
128 |
129 | **注:**
130 | **如果设置Rx Timeout,该值应该至少≥2(ms),推荐≥10(ms)**
131 |
132 | * 如果需要源码,这里需要提醒一下
133 |
134 | 1. 软件依赖的主要的第三方库为:
135 |
136 | [PySimpleGUI](https://github.com/PySimpleGUI/PySimpleGUI)
137 |
138 | [pylink-square](https://github.com/square/pylink)
139 |
140 | 2. 源码中使用的PySimpleGUI版本为4.51.1。我在该版本中增加了获得数据框滚动条相对位置的函数(官方没有提供这个接口),因此你在安装了PySimpleGUI后,还需要在PySimpleGUI.py中增加下面代码(就放在set_vscroll_position()函数后面,这个函数是PySimpleGUI中存在的)
141 | ```python
142 | def get_vscroll_position(self):
143 | """
144 | Get the relative position of the scrollbar
145 |
146 | :return: (y1,y2)
147 | :rtype: tuple
148 | """
149 | try:
150 | return self.Widget.yview()
151 | except Exception as e:
152 | print('Warning get the vertical scroll (yview failed)')
153 | print(e)
154 | return None
155 | ```
156 | ---
157 |
158 | ### RTT-T的配置
159 |
160 | 由于配置选项一般不会变动,所以软件相关的可配置选项全部放在了**应用程序所在目录**下的**config.json**中。如需要修改配置,通过修改这个文件中相应的参数即可。具体如下:
161 |
162 | **增加芯片型号**
163 | * 打开官方J-Link RTT Viewer软件,找到你需要的芯片型号(比如,需要增加**nRF52840_xxAA**)
164 |
165 | * 打开config.json文件,将芯片型号添加到"chip model"中
166 |
167 | 
168 |
169 | **更换数据框中的字体**
170 |
171 | 打开config.json文件,将需要的字体放在"font"列表的第一项(类似添加nRF52840_xxAA)
172 |
173 | **更换数据框中的字体大小**
174 |
175 | 打开config.json文件,修改"font size"中的数字,数字越大,字体越大
176 |
177 | **修改软件启动时数据框的宽度,以兼容不同电脑屏幕尺寸**
178 |
179 | 打开config.json文件,修改"data window width",默认是83,可以在此基础上增大或者减少
180 |
181 | **注:修改config.json文件后保存,然后重启软件,新修改的参数才会生效**
182 |
183 |
184 |
185 |
186 |
--------------------------------------------------------------------------------
/__pycache__/main.cpython-38.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liuhao1946/RTT-T-Project/08b1b2f055ce7fc9f203bd6ea5917707e494e71e/__pycache__/main.cpython-38.pyc
--------------------------------------------------------------------------------
/__pycache__/main.cpython-39.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liuhao1946/RTT-T-Project/08b1b2f055ce7fc9f203bd6ea5917707e494e71e/__pycache__/main.cpython-39.pyc
--------------------------------------------------------------------------------
/__pycache__/qpt.cpython-39.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liuhao1946/RTT-T-Project/08b1b2f055ce7fc9f203bd6ea5917707e494e71e/__pycache__/qpt.cpython-39.pyc
--------------------------------------------------------------------------------
/apple.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liuhao1946/RTT-T-Project/08b1b2f055ce7fc9f203bd6ea5917707e494e71e/apple.ico
--------------------------------------------------------------------------------
/apple.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liuhao1946/RTT-T-Project/08b1b2f055ce7fc9f203bd6ea5917707e494e71e/apple.png
--------------------------------------------------------------------------------
/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "chip model" : [
3 | "nRF52840_xxAA",
4 | "nRF52832_xxAA",
5 | "nRF52832_xxAB",
6 | "STM32F1034C8"
7 | ],
8 | "jlink interface" : ["SWD"],
9 | "Rx Timeout": "0",
10 | "Speed" : "4000",
11 | "SN" : "",
12 | "font" : [
13 | "Consolas",
14 | "Calibri"
15 | ],
16 | "font size" :"13",
17 | "data window width" : "83"
18 | }
--------------------------------------------------------------------------------
/image/1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liuhao1946/RTT-T-Project/08b1b2f055ce7fc9f203bd6ea5917707e494e71e/image/1.gif
--------------------------------------------------------------------------------
/image/2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liuhao1946/RTT-T-Project/08b1b2f055ce7fc9f203bd6ea5917707e494e71e/image/2.gif
--------------------------------------------------------------------------------
/image/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liuhao1946/RTT-T-Project/08b1b2f055ce7fc9f203bd6ea5917707e494e71e/image/3.png
--------------------------------------------------------------------------------
/main.py:
--------------------------------------------------------------------------------
1 | # This is a sample Python script.
2 |
3 | # Press Shift+F10 to execute it or replace it with your code.
4 | # Press Double Shift to search everywhere for classes, files, tool windows, actions, and settings.
5 |
6 |
7 | import PySimpleGUI as sg
8 | import time
9 | from datetime import datetime
10 | import threading
11 | import pylink
12 | import re
13 | import json
14 | import logging
15 | #import traceback
16 |
17 |
18 | base64_main_icon = b'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'
19 |
20 | THREAD_RUN_INTERVAL_S = 0.002
21 |
22 | RTT_DATA_WIN = '-DB_OUT-'+sg.WRITE_ONLY_KEY
23 |
24 | class JlinkThread(threading.Thread):
25 |
26 | gui_wakeup_tick_th = 0
27 |
28 | def __init__(self, window,jlink,timestamp = False,thread_start=False):
29 | super().__init__(daemon=True)
30 | self._thread_start = thread_start
31 | self.jlink = jlink
32 | self.window = window
33 | self.timestamp = timestamp
34 | self.event = threading.Event()
35 | self.event.clear()
36 |
37 | def run(self):
38 | rtt_data_list = []
39 | rtt_data_list_temp = []
40 | gui_wake_tick = 0
41 | rtt_data_none_cnt = 0
42 | time_to = False
43 |
44 | while True:
45 | if self._thread_start:
46 | try:
47 | rtt_data_list_temp = self.jlink.rtt_read(0,2048) #1ms = 1k
48 | if len(rtt_data_list_temp):
49 | rtt_data_list = rtt_data_list + rtt_data_list_temp
50 | rtt_data_none_cnt = 0
51 | else:
52 | rtt_data_none_cnt = rtt_data_none_cnt + 1
53 |
54 | #Turn on the timeout function,self.gui_wakeup_tick_th != 0
55 | if self.gui_wakeup_tick_th != 0:
56 | if rtt_data_none_cnt >= self.gui_wakeup_tick_th:
57 | rtt_data_none_cnt = 0
58 | time_to = True
59 | else:
60 | #Turn off the timeout function, 10ms automatically submit data once to the GUI
61 | gui_wake_tick = gui_wake_tick + 1
62 | if gui_wake_tick >= 5:
63 | gui_wake_tick = 0
64 | time_to = True
65 |
66 | if time_to:
67 | time_to = False
68 | if len(rtt_data_list):
69 | str_data = ''.join([chr(i) for i in rtt_data_list])
70 | if self.timestamp == True:
71 | str_data = '[' + datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[0:-3] + '] ' + str_data
72 | self.window.write_event_value('-JLINK_READ_DATA_THREAD-', str_data)
73 | rtt_data_list = []
74 |
75 | time.sleep(THREAD_RUN_INTERVAL_S)
76 | except Exception as e:
77 | logging.debug('Thread:rtt error [' + str(e) + ']\n')
78 | print(str(e))
79 | self.window.write_event_value('-JLINK_READ_DATA_THREAD-', 'J-Link connect lost')
80 | self._thread_start = False
81 | except :
82 | logging.debug('Thread:rtt error\n')
83 | self.window.write_event_value('-JLINK_READ_DATA_THREAD-', 'J-Link connect lost')
84 | self._thread_start = False
85 | else:
86 | print(rtt_data_list)
87 | logging.debug('Thread:rtt data length [' + str(len(rtt_data_list)) + ']')
88 | logging.debug('Thread:rtt data [' + ''.join([chr(i) for i in rtt_data_list]) +']')
89 | logging.debug('Thread:GUI wakeup tick threshold {}'.format(self.gui_wakeup_tick_th))
90 | logging.debug('Thread:J-Link thread wait......')
91 | self.event.wait()
92 | self.event.clear()
93 |
94 | def jlink_thread_ctr(self, state):
95 | self._thread_start = state
96 | if state:
97 | self.event.set()
98 | logging.debug('Thread:J-Link thread enable')
99 | else:
100 | self.event.clear()
101 | logging.debug('Thread:J-Link thread disble')
102 |
103 | def jlink_timestamp_set(self, state):
104 | self.timestamp = state
105 |
106 | def jlink_reset(jlink):
107 | try:
108 | jlink.rtt_stop()
109 | except:
110 | print("rtt stop error\n")
111 | pass
112 | if jlink.opened():
113 | jlink.close()
114 |
115 | def main():
116 | logging.basicConfig(filename='rtt-t.log',filemode='w',encoding='utf-8', level=logging.DEBUG,\
117 | format='%(asctime)s %(message)s',datefmt='%Y/%m/%d %I:%M:%S')
118 | logging.debug('----------------------------------------------------------------')
119 | logging.debug('----------------------------------------------------------------')
120 | logging.debug('---------------RTT-T Debug Log---------------')
121 | logging.debug('----------------------------------------------------------------')
122 | logging.debug('----------------------------------------------------------------')
123 |
124 | with open('config.json', 'r') as f:
125 | json_data = json.load(f)
126 |
127 | chip_list = json_data['chip model']
128 | jk_interface_list = json_data['jlink interface']
129 | jk_speed = json_data['Speed']
130 | rx_timeout = json_data['Rx Timeout']
131 | sn = json_data['SN']
132 | font_type = json_data['font'][0]
133 | font_size = json_data['font size']
134 | try:
135 | data_window_w = int(json_data['data window width'])
136 | except:
137 | data_window_w = 83
138 |
139 | font = font_type + ' '
140 |
141 | jlink = pylink.JLink()
142 | right_click_menu = ['',['Clear','Scroll to the end']]
143 |
144 | cfg_frame_layout = [[sg.Button('Connect J-Link',pad=((45,3),(16,16)),key='-JK_CONNECT-',size=(18,2),button_color=('grey0','grey100'),font=(font+str(12)))],\
145 | [sg.Button('Open Timestamp',key='-TIMESTAMP_CTR-',pad=((45,3),(16,16)),button_color=('grey0','grey100'),size=(18,2),font=(font+str(12)))],\
146 | [sg.Button('Open Real-time saving data',key='-RT_DATA_SAVE-',pad=((45,3),(16,16)),size=(18,2),button_color=('grey0','grey100'),font=(font+str(12)))],\
147 | [sg.Button('Save all data',key='-DATA_SAVE-',pad=((45,3),(16,16)),size=(18,2),button_color=('grey0','grey100'),font=(font+str(12)))],\
148 | [sg.Text('Chip Model'),sg.Combo(chip_list,chip_list[0],size=(16,1),pad=((23,3),(20,16)),key='-CHIP_SEL-')],\
149 | [sg.Text('J-Link Interface'),sg.Combo(jk_interface_list,jk_interface_list[0],size=(16,1),key='-JK_INTER-',pad=((0,3),(20,16)))],\
150 | [sg.Text('RX Timout',pad=(10,20)),sg.InputText(rx_timeout,key='-RX_TIMEOUT-',size=(18,1),pad=((26,3),(20,16)),tooltip='0 means no timeout,Unit ms')],\
151 | [sg.Text('J-Link S/N'),sg.InputText(sn,key='-SN-',pad=((24,3),(20,16)),size=(18,1))],\
152 | [sg.Text('Speed(KHz)'), sg.InputText(jk_speed,pad=((14,3),(20,16)),key='-SPEED-',size=(18,1))],\
153 | ]
154 |
155 | sd_bt_frame_layout = [[sg.Button('Send',key='-SD_DATA_BT-',pad=((45,28),(6,6)),size=(18,2),button_color=('grey0','grey100'),font=(font+str(12)))]]
156 | sd_data_frame_layout = [[sg.InputText('cmd:time syn',key='-SD_DATA_TXT-',size=(50,1),pad=((9,8),(10,15)),font=(font+str(20)),tooltip='Text type')]]
157 |
158 | layout = [[sg.Frame('Config', cfg_frame_layout, vertical_alignment='top',key='-CFG-'),\
159 | sg.Multiline(autoscroll=True,key=RTT_DATA_WIN,size=(data_window_w,31),pad=(10,10),right_click_menu=right_click_menu,font=(font+font_size+' bold'),expand_x=True,expand_y=True)],
160 | [sg.Frame('Send data',sd_bt_frame_layout,vertical_alignment='top'), \
161 | sg.Frame('Text Data',sd_data_frame_layout,vertical_alignment='top')],
162 | ]
163 |
164 | window = sg.Window('RTT Tool 1.5', layout,finalize=True,element_padding=(10,1),return_keyboard_events=False,icon=base64_main_icon,resizable=True)
165 | window.set_min_size(window.size)
166 |
167 | #window['-CFG-'].expand(True, True, True)
168 | window[RTT_DATA_WIN].expand(True, True, True)
169 |
170 | jlink_thread = JlinkThread(window,jlink)
171 | jlink_thread.start()
172 |
173 | mul_scroll_end = False
174 | real_time_save_file_name = False
175 | real_time_save_data = ''
176 |
177 | while True:
178 | event, values = window.read(timeout=200)
179 |
180 | if event == sg.WIN_CLOSED:
181 | jlink_thread.jlink_thread_ctr(False)
182 | jlink_reset(jlink)
183 | break
184 |
185 | #print(event, values)
186 | #Scroll bar in the middle position, as the data in the text box increases, y1 increases and y2 decreases
187 | y1, y2 = window[RTT_DATA_WIN].get_vscroll_position()
188 | if mul_scroll_end == True and bool(1 - y2):
189 | mul_scroll_end = False
190 | window[RTT_DATA_WIN].update(autoscroll=False)
191 | elif mul_scroll_end == False and y2 == 1:
192 | mul_scroll_end = True
193 | window[RTT_DATA_WIN].update(autoscroll=True)
194 |
195 | if event == '-JK_CONNECT-':
196 | if window['-JK_CONNECT-'].get_text() == 'Connect J-Link':
197 | jlink_op_suc = 0
198 | try:
199 | jlink.open()
200 | ser_num = jlink.serial_number
201 | jlink.close()
202 | except pylink.errors.JLinkException as e:
203 | sg.popup(e)
204 | jlink_op_suc = 1
205 |
206 | #J-Link reads S/N successfully
207 | if jlink_op_suc == 0:
208 | window['-SN-'].update(str(ser_num))
209 | window[RTT_DATA_WIN].write('LOG:J-Link SN:'+str(ser_num)+'\n')
210 | try:
211 | jlink.open(str(ser_num))
212 | #Set J-Link interface
213 | jk_interface = window['-JK_INTER-'].get()
214 | if jk_interface == 'SWD':
215 | jlink.set_tif(pylink.enums.JLinkInterfaces.SWD)
216 |
217 | window[RTT_DATA_WIN].write('LOG:J-Link interface:' + jk_interface + '\n')
218 | jlink.set_speed(int(window['-SPEED-'].get()))
219 | window[RTT_DATA_WIN].write('LOG:J-Link speed:' + window['-SPEED-'].get() + 'KHz''\n')
220 | #Connect J-Link
221 | jlink.connect(window['-CHIP_SEL-'].get())
222 | #Set Reset I/O
223 | #jlink.set_reset_strategy(pylink.enums.JLinkResetStrategyCortexM3.RESETPIN)
224 | jlink.reset(ms=10, halt=False)
225 | #J-Link is connected
226 | if jlink.connected():
227 | window['-DB_OUT-' + sg.WRITE_ONLY_KEY].write('LOG:J-Link connect success!\n')
228 | window['-JK_CONNECT-'].update(button_color=('grey0','green4'))
229 | window['-JK_CONNECT-'].update('Disconnect J-Link')
230 |
231 | #Check timeout time
232 | try:
233 | time_ms = int(window['-RX_TIMEOUT-'].get())
234 | except:
235 | sg.popup('Receive timeout time is set incorrectly')
236 | time_ms = 0
237 | window['-RX_TIMEOUT-'].update('0')
238 |
239 | jlink_thread.gui_wakeup_tick_th = int(time_ms / (THREAD_RUN_INTERVAL_S * 10 ** 3))
240 | #print('time_ms:', time_ms,jlink_thread.gui_wakeup_tick_th)
241 | window[RTT_DATA_WIN].write('LOG:RTT rx data timout:' + window['-RX_TIMEOUT-'].get() + '\n')
242 |
243 | if not jlink_thread.is_alive():
244 | jlink_thread.start()
245 | jlink_thread.jlink_thread_ctr(True)
246 |
247 | jlink.rtt_start()
248 | window['-RX_TIMEOUT-'].update(disabled=True)
249 | window['-SN-'].update(disabled=True)
250 | window['-SPEED-'].update(disabled=True)
251 | except ValueError:
252 | logging.debug('Speed setting error')
253 | sg.popup('Speed setting error')
254 | jlink_reset(jlink)
255 | except Exception as e:
256 | logging.debug('J-Link Operation error[' + str(e) + ']')
257 | sg.popup('J-Link Operation error[' + str(e) + ']')
258 | jlink_reset(jlink)
259 | else:
260 | #Thread stop
261 | jlink_thread.jlink_thread_ctr(False)
262 | jlink_reset(jlink)
263 | window[RTT_DATA_WIN].write('LOG:J-Link disconnect!\n')
264 | window['-JK_CONNECT-'].update(button_color=('grey0', 'grey100'))
265 | window['-JK_CONNECT-'].update('Connect J-Link')
266 | window['-RX_TIMEOUT-'].update(disabled=False)
267 | window['-SN-'].update(disabled=False)
268 | window['-SPEED-'].update(disabled=False)
269 |
270 | elif event == 'Clear':
271 | window['-DB_OUT-' + sg.WRITE_ONLY_KEY].update('')
272 |
273 | elif event == '-TIMESTAMP_CTR-':
274 | if window['-TIMESTAMP_CTR-'].get_text() == 'Open Timestamp':
275 | window['-TIMESTAMP_CTR-'].update(button_color=('grey0', 'green4'))
276 | window['-TIMESTAMP_CTR-'].update('Close Timestamp')
277 | jlink_thread.jlink_timestamp_set(True)
278 | else:
279 | window['-TIMESTAMP_CTR-'].update(button_color=('grey0', 'grey100'))
280 | window['-TIMESTAMP_CTR-'].update('Open Timestamp')
281 | jlink_thread.jlink_timestamp_set(False)
282 |
283 | elif event == 'Scroll to the end':
284 | mul_scroll_end = True
285 | window['-DB_OUT-' + sg.WRITE_ONLY_KEY].update(autoscroll=True)
286 |
287 | elif event == '-DATA_SAVE-':
288 | file_name = r'log_' + datetime.now().strftime('%Y-%m-%d-%H-%M-%S') + '.txt'
289 | rtt_data_str = re.sub('(\r\n)+','\n',window[RTT_DATA_WIN].get())
290 | #file_name = os.path.dirname(os.path.realpath(sys.argv[0])) + '\\log\\' + file_name
291 | #print(file_name)
292 | with open(file_name, 'w', encoding='utf-8') as f:
293 | f.write(rtt_data_str)
294 | sg.popup_no_wait('File saved successfully')
295 |
296 | elif event == '-RT_DATA_SAVE-':
297 | if window['-RT_DATA_SAVE-'].get_text() == 'Open Real-time saving data':
298 | window['-RT_DATA_SAVE-'].update(button_color=('grey0','green4'))
299 | window['-RT_DATA_SAVE-'].update('Close Real-time saving data')
300 | real_time_save_file_name = r'real_time_log_' + datetime.now().strftime('%Y-%m-%d-%H-%M-%S') + '.txt'
301 | else:
302 | window['-RT_DATA_SAVE-'].update(button_color=('grey0', 'grey100'))
303 | window['-RT_DATA_SAVE-'].update('Open Real-time saving data')
304 |
305 | elif event == '__TIMEOUT__':
306 | if len(real_time_save_data) > 0:
307 | try:
308 | with open(real_time_save_file_name, 'a', encoding='utf-8') as f:
309 | f.write(real_time_save_data)
310 | real_time_save_data = ''
311 | except Exception as e:
312 | logging.debug('Write real time data to file error[' + str(e) + ']\n')
313 | except:
314 | logging.debug('Write real time data to file error')
315 | sg.Print("Write real time data to file error")
316 |
317 | elif event == '-JLINK_READ_DATA_THREAD-':
318 | if values['-JLINK_READ_DATA_THREAD-'] != 'J-Link connect lost':
319 | window['-DB_OUT-' + sg.WRITE_ONLY_KEY].write(values['-JLINK_READ_DATA_THREAD-'])
320 | if window['-RT_DATA_SAVE-'].get_text() == 'Close Real-time saving data':
321 | real_time_save_data = real_time_save_data + re.sub('(\r\n)+','\n',values['-JLINK_READ_DATA_THREAD-'])
322 | else:
323 | logging.debug('J-Link connect lost')
324 | jlink_reset(jlink)
325 | jlink_thread.jlink_thread_ctr(False)
326 | window['-DB_OUT-' + sg.WRITE_ONLY_KEY].write('LOG:J-Link connection has been lost' + '\n')
327 | window['-JK_CONNECT-'].update(button_color=('grey0', 'grey100'))
328 | window['-JK_CONNECT-'].update('Connect J-Link')
329 | window['-RX_TIMEOUT-'].update(disabled=False)
330 | window['-SN-'].update(disabled=False)
331 | window['-SPEED-'].update(disabled=False)
332 |
333 | elif event == '-SD_DATA_BT-':
334 | data_cmd = window['-SD_DATA_TXT-'].get()
335 | if data_cmd.startswith('cmd:'):
336 | if data_cmd.find('time syn') >= 0:
337 | if jlink.opened():
338 | try:
339 | time_str = 'time syn:' + datetime.now().strftime('%Y-%m-%d-%H-%M-%S')
340 | time_list = [ord(i) for i in time_str]
341 | jlink.rtt_write(0,time_list)
342 | logging.debug('Data send success(cmd:time syn):'+ time_str)
343 | except Exception as e:
344 | logging.debug('Data send failt(cmd:time syn)[' + str(e) + ']\n')
345 | except:
346 | logging.debug('Data send failt(cmd:time syn)')
347 | else:
348 | if jlink.opened():
349 | try:
350 | time_list = [ord(i) for i in data_cmd]
351 | jlink.rtt_write(0, time_list)
352 | logging.debug('Data send success:' + data_cmd)
353 | except Exception as e:
354 | logging.debug('Data send error[' + str(e) + ']\n')
355 | except:
356 | logging.debug('Data send error')
357 | pass
358 |
359 | window.close()
360 |
361 | if __name__ == '__main__':
362 | main()
363 |
--------------------------------------------------------------------------------
/main.spec:
--------------------------------------------------------------------------------
1 | # -*- mode: python ; coding: utf-8 -*-
2 |
3 |
4 | block_cipher = None
5 |
6 |
7 | a = Analysis(['main.py'],
8 | pathex=[],
9 | binaries=[],
10 | datas=[],
11 | hiddenimports=[],
12 | hookspath=[],
13 | hooksconfig={},
14 | runtime_hooks=[],
15 | excludes=[],
16 | win_no_prefer_redirects=False,
17 | win_private_assemblies=False,
18 | cipher=block_cipher,
19 | noarchive=False)
20 | pyz = PYZ(a.pure, a.zipped_data,
21 | cipher=block_cipher)
22 |
23 | exe = EXE(pyz,
24 | a.scripts,
25 | a.binaries,
26 | a.zipfiles,
27 | a.datas,
28 | [],
29 | name='main',
30 | debug=False,
31 | bootloader_ignore_signals=False,
32 | strip=False,
33 | upx=True,
34 | upx_exclude=[],
35 | runtime_tmpdir=None,
36 | console=False,
37 | disable_windowed_traceback=False,
38 | target_arch=None,
39 | codesign_identity=None,
40 | entitlements_file=None , icon='apple.ico')
41 |
--------------------------------------------------------------------------------
/rtt-t.log:
--------------------------------------------------------------------------------
1 | 2022/01/23 05:42:14 ----------------------------------------------------------------
2 | 2022/01/23 05:42:14 ----------------------------------------------------------------
3 | 2022/01/23 05:42:14 ---------------RTT-T Debug Log---------------
4 | 2022/01/23 05:42:14 ----------------------------------------------------------------
5 | 2022/01/23 05:42:14 ----------------------------------------------------------------
6 | 2022/01/23 05:42:15 Thread:rtt data length [0]
7 | 2022/01/23 05:42:15 Thread:rtt data []
8 | 2022/01/23 05:42:15 Thread:GUI wakeup tick threshold 0
9 | 2022/01/23 05:42:15 Thread:J-Link thread wait......
10 | 2022/01/23 05:42:17 Thread:J-Link thread disble
11 |
--------------------------------------------------------------------------------
/windows icon update.bat:
--------------------------------------------------------------------------------
1 |
2 | rem 关闭Windows外壳程序explorer
3 | taskkill /f /im explorer.exe
4 | rem 清理系统图标缓存数据库
5 | attrib -h -s -r "%userprofile%\AppData\Local\IconCache.db"
6 | del /f "%userprofile%\AppData\Local\IconCache.db"
7 | attrib /s /d -h -s -r "%userprofile%\AppData\Local\Microsoft\Windows\Explorer\*"
8 | del /f "%userprofile%\AppData\Local\Microsoft\Windows\Explorer\thumbcache_32.db"
9 | del /f "%userprofile%\AppData\Local\Microsoft\Windows\Explorer\thumbcache_96.db"
10 | del /f "%userprofile%\AppData\Local\Microsoft\Windows\Explorer\thumbcache_102.db"
11 | del /f "%userprofile%\AppData\Local\Microsoft\Windows\Explorer\thumbcache_256.db"
12 | del /f "%userprofile%\AppData\Local\Microsoft\Windows\Explorer\thumbcache_1024.db"
13 | del /f "%userprofile%\AppData\Local\Microsoft\Windows\Explorer\thumbcache_idx.db"
14 | del /f "%userprofile%\AppData\Local\Microsoft\Windows\Explorer\thumbcache_sr.db"
15 | rem 清理 系统托盘记忆的图标
16 | echo y|reg delete "HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify" /v IconStreams
17 | echo y|reg delete "HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify" /v PastIconsStream
18 | rem 重启Windows外壳程序explorer
19 | start explorer
20 | ————————————————
21 | 版权声明:本文为CSDN博主「Vvlowkey」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
22 | 原文链接:https://blog.csdn.net/vvlowkey/article/details/51133486
--------------------------------------------------------------------------------