SWO logger is a log tool designed to get the log from SWO interface and note the time stamp of every single line.
This tool is developed by Python based on pylink library. And thanks to Meng for his great effort on jlinkhelper.py development. We took a lot of reference to his code and made use of his code (only a little bit modification).
Now, tool is packed as .exe format with all dependency. User could simply paste it to anywhere he wants to execute.
When you double click the icon, you will see a popup terminal as following:
You input the number before items (1, 2 or 3) to select different device you need to connect to. Then, you'll be required to input the log file name in the following line: (e.g. swo_test.txt)
The log file with name you input will be saved in the same path with your .exe file. You could also save your log file into where you want by indicating the absolute path.
If you have your right device connected, you would find the following info:
The yellow label shows the serial number of your device. The blue one shows SWO speed and the red one shows the device name.
After this, you would find the log info from your device if there is.
In the following part, I paste most important functions here. It would be helpful if you want to know more about how this tool works.
- Connect to the target device via JLink
def connect_target(device, jlink_serial=None):
JLINK_RESET = '''\
device {part}
si SWD
speed 1000
connect
exit
'''
cmdfile = open('connect.jlink', 'w')
cmdfile.write(JLINK_RESET.format(part=device))
cmdfile.close()
if sys.platform == 'darwin':
# in Mac OS
JLink_CL = "JLinkExe"
elif sys.platform == 'win32':
JLink_CL = "jlink.exe"
if (jlink_serial == None):
subprocess.run([JLink_CL,
"-Device", device,
"-If", "SWD",
"-Speed", "1000",
"-ExitOnError", "1"
"-CommandFile", "connect.jlink"])
else:
subprocess.run([JLink_CL,
"-Device", device,
"-SelectEmuBySN", jlink_serial,
"-If", "SWD",
"-Speed", "1000",
"-ExitOnError", "1"
"-CommandFile", "connect.jlink"])
- Get the data from SWO interface and print it to terminal
def serial_wire_viewer(device, path="", jlink_serial=None):
"""Implements a Serial Wire Viewer (SWV).
A Serial Wire Viewer (SWV) allows us implement real-time logging of output
from a connected device over Serial Wire Output (SWO).
Args:
jlink_serial (str): the J-Link serial number
device (str): the target CPU
path: the log file path
Returns:
Always returns ``0``.
Raises:
JLinkException: on error
"""
global swo_running
buf = StringIO.StringIO()
jlink = pylink.JLink(log=buf.write, detailed_log=buf.write)
jlink.open(serial_no=jlink_serial)
# Use Serial Wire Debug as the target interface. Need this in order to use
# Serial Wire Output.
jlink.set_tif(pylink.enums.JLinkInterfaces.SWD)
jlink.connect(device, verbose=True)
jlink.coresight_configure()
jlink.set_reset_strategy(pylink.enums.JLinkResetStrategyCortexM3.CORE)
# Have to halt the CPU before getitng its speed.
# jlink.reset()
# jlink.halt()
cpu_speed = 47860 #jlink.cpu_speed() # 47860
swo_speed = 1000000 # jlink.swo_supported_speeds(cpu_speed, 10)[9]
# Start logging serial wire output.
jlink.swo_start(swo_speed)
jlink.swo_flush()
# Output the information about the program.
sys.stdout.write('Reading data from port 0:\n\n')
# To solve file write crush in Windows
f = open(path, "w", encoding='utf-8')
# Reset the core without halting so that it runs.
#jlink.reset(ms=10, halt=False)
connect_target(device, jlink_serial)
swo_running = True
log_line = []
# Use the `try` loop to catch a keyboard interrupt in order to stop logging
# serial wire output.
try:
while swo_running:
# Check for any bytes in the stream.
num_bytes = jlink.swo_num_bytes()
if num_bytes == 0:
# If no bytes exist, sleep for a bit before trying again.
time.sleep(0.1)
continue
data = jlink.swo_read_stimulus(0, num_bytes)
# transfer to ASCII encode
data_str = ''.join(map(chr, data))
data_list = list(data_str)
for idx, item in enumerate(data_list):
log_line.append(item)
if item == '\n':
ct = time.time()
local_time = time.localtime(ct)
data_head = time.strftime("%Y-%m-%d %H:%M:%S", local_time)
data_secs = (ct - int(ct)) * 1000
time_stamp = "%s.%03d" % (data_head, data_secs)
log_line.insert(0, '['+time_stamp+'] ')
data_str = "".join(log_line)
sys.stdout.write(data_str)
f.write(data_str)
sys.stdout.flush()
f.flush()
log_line = []
except KeyboardInterrupt:
pass
sys.stdout.write('\n')
f.write('\n')
f.close()
# Stop logging serial wire output.
jlink.swo_stop()
return 0
I also attach all source code and .exe file in the attachment. You could download and check them if you need.
2022-05-12 update:
Version 2.2
- Added support for Apollo4 Family
- Added exception handling when JLINK connection lost.
- Default log file name.
Comments
0 comments
Article is closed for comments.