emdbg.debug.jlink
J-Link Debug Probe
The J-Link debug probe is a closed-source, commercial hardware probe which supports almost all Cortex-M devices.
Command Line Interface
Common tasks are wrapped in a simple Python CLI. For more complex use-cases, use the J-Link drivers directly.
Reset the device remotely:
python3 -m emdbg.debug.jlink -device STM32F765II reset
Run the JLinkGDBServer as a blocking process
python3 -m emdbg.debug.jlink -device STM32F765II run
Upload firmware to a device:
python3 -m emdbg.debug.jlink -device STM32F765II upload --source path/to/firmware.elf
python3 -m emdbg.debug.jlink -device STM32F765II upload --source path/to/firmware.bin --load-addr 0x08008000
Connect to RTT channel 0 for up- and downlink. Opens a telnet client that can be terminated with Ctrl+D.
python3 -m emdbg.debug.jlink -device STM32F765II rtt --channel 0
Output log output over ITM port 1 at 4MHz
python3 -m emdbg.debug.jlink -device STM32F765II itm --channel 1 --baudrate 4000000
Installation
You need to have the J-Link drivers installed for this module to work:
Ubuntu
wget --post-data "accept_license_agreement=accepted" https://www.segger.com/downloads/jlink/JLink_Linux_x86_64.deb
sudo dpkg -i JLink_Linux_x86_64.deb
macOS
brew install segger-jlink
1# Copyright (c) 2023, Auterion AG 2# SPDX-License-Identifier: BSD-3-Clause 3 4""" 5.. include:: jlink.md 6""" 7 8from __future__ import annotations 9import os 10import time 11import signal 12import platform 13import subprocess 14import logging 15import tempfile 16from pathlib import Path 17 18from .backend import ProbeBackend 19from . import gdb 20 21LOGGER = logging.getLogger("debug:jlink") 22 23 24# ----------------------------------------------------------------------------- 25class JLinkBackend(ProbeBackend): 26 """ 27 J-Link specific debug backend implementation. Starts the `JLinkGDBServer` in 28 its own subprocess and connects GDB to port `2331` of the localhost. 29 30 See `call()` for additional information. 31 """ 32 def __init__(self, device: str, speed: int, serial: str = None, rtos: Path = None): 33 """ 34 :param device: part name of the microcontroller to debug. 35 :param speed: SWD connection baudrate in kHz. 36 :param serial: Serial number of J-Link for selection. 37 :param rtos: Path to RTOS plugin for thread-aware debugging. 38 """ 39 super().__init__(":2331") 40 self.device = device 41 self.speed = speed 42 self.serial = serial 43 self.rtos = rtos 44 self.process = None 45 self.name = "jlink" 46 47 def start(self): 48 self.process = call(self.device, self.speed, self.serial, self.rtos, 49 blocking=False, silent=True) 50 LOGGER.info(f"Starting {self.process.pid}...") 51 52 def stop(self): 53 if self.process is not None: 54 LOGGER.info(f"Stopping {self.process.pid}.") 55 os.killpg(os.getpgid(self.process.pid), signal.SIGINT) 56 os.waitpid(os.getpgid(self.process.pid), 0) 57 self.process = None 58 59 60# ----------------------------------------------------------------------------- 61def call(device: str, speed: int, serial: str = None, rtos: Path = None, 62 blocking: bool = True, silent: bool = False) -> "int | subprocess.Popen": 63 """ 64 Starts the `JLinkGDBServer` and connects to the microcontroller without 65 resetting the device and without GUI. You can overwrite the default binary 66 by exporting an alternative in your environment: 67 68 ```sh 69 export PX4_JLINK_GDB_SERVER=path/to/JLinkGDBServer 70 ``` 71 72 :param device: part name of the microcontroller to debug. 73 :param speed: SWD connection baudrate in kHz. 74 :param serial: Serial number of J-Link for selection. 75 :param rtos: Path to RTOS plugin for thread-aware debugging. 76 :param blocking: Run in current process as a blocking call. 77 Set to `False` to run in a new subprocess. 78 :param silent: Disable any reporting from `JLinkGDBServer`. 79 80 :return: The process return code if `blocking` or the Popen object. 81 """ 82 binary = os.environ.get("PX4_JLINK_GDB_SERVER", "JLinkGDBServer") 83 84 command_jlink = f"{binary} -device {device} -speed {speed} -if swd -noreset -nogui" 85 if serial: command_jlink += f" -SelectEmuBySN {serial}" 86 if rtos: command_jlink += f" -rtos {Path(rtos).absolute()}" 87 if silent: command_jlink += " -silent" 88 89 LOGGER.debug(command_jlink) 90 91 kwargs = {"cwd": os.getcwd(), "shell": True} 92 if blocking: 93 return subprocess.call(command_jlink, **kwargs) 94 95 # Disconnect the JLink process from this process, so that any Ctrl-C usage 96 # in GDB does not get passed on to the JLink process. 97 kwargs["start_new_session"] = True 98 return subprocess.Popen(command_jlink, **kwargs) 99 100 101# ----------------------------------------------------------------------------- 102def itm(device: str, baudrate: int = None, port: int = None, serial: str = None) -> int: 103 """ 104 Launches `JLinkSWOViewer`, connects to the microcontroller. You can 105 overwrite the default binary by exporting an alternative in your environment: 106 107 ```sh 108 export PX4_JLINK_SWO_VIEWER=path/to/JLinkSWOViewer 109 ``` 110 111 :param device: part name of the microcontroller to debug. 112 :param baudrate: optional frequency of the SWO connection. 113 :param port: ITM port to display at startup. You can modify this at runtime. 114 :param serial: Serial number of J-Link for selection. 115 116 :return: the process return code 117 """ 118 binary = os.environ.get("PX4_JLINK_SWO_VIEWER", "JLinkSWOViewer") 119 command_jlink = f"{binary} -device {device} -itmport {port or 0}" 120 if baudrate: command_jlink += f" -swofreq {baudrate}" 121 try: 122 return subprocess.call(command_jlink, shell=True) 123 except KeyboardInterrupt: 124 pass 125 126 127def rtt(backend: JLinkBackend, channel: int = 0) -> int: 128 """ 129 Launches the backend in the background and connects a telnet client to the 130 Real-Time Transfer process. You can disconnect with Ctrl+D. 131 132 :param backend: A J-Link backend object. 133 :param channel: The RTT channel to connect to. 134 135 :return: the process return code 136 """ 137 import telnetlib 138 # Start JLinkGDBServer in the background 139 with backend.scope(): 140 with telnetlib.Telnet("localhost", 19021) as tn: 141 try: 142 tn.interact() 143 except KeyboardInterrupt: 144 pass 145 return 0 146 147# ----------------------------------------------------------------------------- 148def erase(device: str, speed: int, address_range: tuple[int, int] = None, 149 serial: str = None) -> int: 150 """ 151 Erases (part of) the device via JLink. 152 153 :param device: part name of the microcontroller to program. You can 154 overwrite the default binary by exporting an alternative in 155 your environment: 156 ```sh 157 export PX4_JLINK=path/to/JLinkExe 158 ``` 159 :param speed: SWD connection baudrate in kHz. 160 :param address_range: Optional [start, end] address to erase only part of device. 161 :param serial: Serial number of J-Link for selection. 162 163 :return: the process return code of JLink 164 """ 165 binary = os.environ.get("PX4_JLINK", "JLinkExe") 166 if address_range is not None: 167 address_range = f"{address_range[0]} {address_range[1]}" 168 with tempfile.NamedTemporaryFile() as fcmd: 169 commands = f"Erase {address_range or ''}\nExit" 170 Path(fcmd.name).write_text(commands) 171 jcmd = f"{binary} -device {device} -speed {speed} -ExitOnError 1 " \ 172 f"-if swd -autoconnect 1 -nogui 1 -commandfile {fcmd.name}" 173 if serial: jcmd += f" -SelectEmuBySN {serial}" 174 LOGGER.debug(f"{jcmd}\n{commands}") 175 return subprocess.call(jcmd, shell=True) 176 177def program(source: Path, device: str, speed: int, serial: str = None, load_addr: int = None) -> int: 178 """ 179 Loads the source file into the microcontroller and resets the device. You can 180 overwrite the default binary by exporting an alternative in your environment: 181 182 ```sh 183 export PX4_JLINK=path/to/JLinkExe 184 ``` 185 186 :param source: path to a `.bin`, `.hex`, or `.elf` file to upload. 187 :param device: part name of the microcontroller to program. 188 :param speed: SWD connection baudrate in kHz. 189 :param serial: Serial number of J-Link for selection. 190 :param load_addr: Specifies the start address to load a `.bin` file. 191 192 :return: the process return code of JLink 193 """ 194 binary = os.environ.get("PX4_JLINK", "JLinkExe") 195 if load_addr is None and Path(source).suffix == ".bin": 196 load_addr = 0x0800_0000 197 with tempfile.NamedTemporaryFile() as fcmd: 198 # LoadFile erases the correct amount of sectors, then writes the new 199 # binary or hex file. We still need to reset afterwards. 200 commands = f"LoadFile {source} {load_addr or ''}\nReset\nExit" 201 Path(fcmd.name).write_text(commands) 202 jcmd = f"{binary} -device {device} -speed {speed} -ExitOnError 1 " \ 203 f"-if swd -autoconnect 1 -nogui 1 -commandfile {fcmd.name}" 204 if serial: jcmd += f" -SelectEmuBySN {serial}" 205 LOGGER.debug(f"{jcmd}\n{commands}") 206 return subprocess.call(jcmd, shell=True) 207 208def reset(device: str, speed: int, serial: str = None) -> int: 209 """ 210 Resets the device via JLink. 211 212 :param device: part name of the microcontroller to program. You can 213 overwrite the default binary by exporting an alternative in 214 your environment: 215 ```sh 216 export PX4_JLINK=path/to/JLinkExe 217 ``` 218 :param speed: SWD connection baudrate in kHz. 219 :param serial: Serial number of J-Link for selection. 220 221 :return: the process return code of JLink 222 """ 223 binary = os.environ.get("PX4_JLINK", "JLinkExe") 224 with tempfile.NamedTemporaryFile() as fcmd: 225 commands = "Reset\nExit" 226 Path(fcmd.name).write_text(commands) 227 jcmd = f"{binary} -device {device} -speed {speed} -ExitOnError 1 " \ 228 f"-if swd -autoconnect 1 -nogui 1 -commandfile {fcmd.name}" 229 if serial: jcmd += f" -SelectEmuBySN {serial}" 230 LOGGER.debug(f"{jcmd}\n{commands}") 231 return subprocess.call(jcmd, shell=True) 232 233 234# ----------------------------------------------------------------------------- 235def _add_subparser(subparser): 236 parser = subparser.add_parser("jlink", help="Use JLink as Backend.") 237 parser.add_argument( 238 "-device", 239 required=True, 240 help="Connect to this device.") 241 parser.add_argument( 242 "-speed", 243 type=int, 244 default=12000, 245 help="SWO baudrate in kHz.") 246 parser.add_argument( 247 "-serial", 248 default=None, 249 help="Serial of the J-Link.") 250 parser.set_defaults(backend=lambda args: JLinkBackend(args.device, args.speed, args.serial)) 251 return parser 252 253 254# ----------------------------------------------------------------------------- 255if __name__ == "__main__": 256 import argparse 257 import emdbg 258 259 parser = argparse.ArgumentParser( 260 description="JLink debug probe: Upload, reset, and logging") 261 parser.add_argument( 262 "-device", 263 required=True, 264 help="Connect to this device.") 265 parser.add_argument( 266 "-speed", 267 type=int, 268 default=12000, 269 help="SWD baudrate in kHz.") 270 parser.add_argument( 271 "-serial", 272 default=None, 273 help="Serial of the J-Link.") 274 parser.add_argument( 275 "-v", 276 dest="verbosity", 277 action="count", 278 help="Verbosity level.") 279 280 subparsers = parser.add_subparsers(title="Command", dest="command") 281 282 subparsers.add_parser("reset", help="Reset the device.") 283 284 subparsers.add_parser("run", help="Run JLinkGDBServer.") 285 286 erase_parser = subparsers.add_parser("erase", help="Erase devices.") 287 erase_parser.add_argument( 288 "--range", 289 help="The range of addresses to erase as a tuple separated by comma. " 290 "For example: --range 0x0800_0000,0x0800_1000") 291 292 upload_parser = subparsers.add_parser("upload", help="Upload firmware.") 293 upload_parser.add_argument( 294 "--source", 295 required=True, 296 help="The firmware to upload: `.bin`, `.hex`, or `.elf` file") 297 upload_parser.add_argument( 298 "--load-addr", 299 help="The load address of the binary file") 300 301 rtt_parser = subparsers.add_parser("rtt", help="Connect to an RTT channel.") 302 rtt_parser.add_argument( 303 "--channel", 304 type=int, 305 default=0, 306 help="The RTT channel to connect to.") 307 308 itm_parser = subparsers.add_parser("itm", help="Show ITM log output.") 309 itm_parser.add_argument( 310 "--baudrate", 311 type=int, 312 help="Force a baudrate instead of auto-selecting it.") 313 itm_parser.add_argument( 314 "--channel", 315 type=int, 316 help="The channel to output.") 317 318 args = parser.parse_args() 319 emdbg.logger.configure(args.verbosity) 320 321 if args.command == "reset": 322 exit(reset(args.device, args.speed, args.serial)) 323 324 if args.command == "run": 325 exit(call(args.device, args.speed, args.serial, blocking=True)) 326 327 if args.command == "erase": 328 addr_range = [int(a, 0) for a in args.range.split(",")] if args.range else None 329 exit(erase(args.device, args.speed, addr_range, args.serial)) 330 331 if args.command == "upload": 332 exit(program(os.path.abspath(args.source), args.device, args.speed, args.serial)) 333 334 if args.command == "rtt": 335 backend = JLinkBackend(args.device, args.speed, args.serial) 336 exit(rtt(backend, args.channel)) 337 338 if args.command == "itm": 339 exit(itm(args.device, args.baudrate, args.channel, args.serial)) 340 341 LOGGER.error("Unknown command!") 342 exit(1)
26class JLinkBackend(ProbeBackend): 27 """ 28 J-Link specific debug backend implementation. Starts the `JLinkGDBServer` in 29 its own subprocess and connects GDB to port `2331` of the localhost. 30 31 See `call()` for additional information. 32 """ 33 def __init__(self, device: str, speed: int, serial: str = None, rtos: Path = None): 34 """ 35 :param device: part name of the microcontroller to debug. 36 :param speed: SWD connection baudrate in kHz. 37 :param serial: Serial number of J-Link for selection. 38 :param rtos: Path to RTOS plugin for thread-aware debugging. 39 """ 40 super().__init__(":2331") 41 self.device = device 42 self.speed = speed 43 self.serial = serial 44 self.rtos = rtos 45 self.process = None 46 self.name = "jlink" 47 48 def start(self): 49 self.process = call(self.device, self.speed, self.serial, self.rtos, 50 blocking=False, silent=True) 51 LOGGER.info(f"Starting {self.process.pid}...") 52 53 def stop(self): 54 if self.process is not None: 55 LOGGER.info(f"Stopping {self.process.pid}.") 56 os.killpg(os.getpgid(self.process.pid), signal.SIGINT) 57 os.waitpid(os.getpgid(self.process.pid), 0) 58 self.process = None
J-Link specific debug backend implementation. Starts the JLinkGDBServer
in
its own subprocess and connects GDB to port 2331
of the localhost.
See call()
for additional information.
33 def __init__(self, device: str, speed: int, serial: str = None, rtos: Path = None): 34 """ 35 :param device: part name of the microcontroller to debug. 36 :param speed: SWD connection baudrate in kHz. 37 :param serial: Serial number of J-Link for selection. 38 :param rtos: Path to RTOS plugin for thread-aware debugging. 39 """ 40 super().__init__(":2331") 41 self.device = device 42 self.speed = speed 43 self.serial = serial 44 self.rtos = rtos 45 self.process = None 46 self.name = "jlink"
Parameters
- device: part name of the microcontroller to debug.
- speed: SWD connection baudrate in kHz.
- serial: Serial number of J-Link for selection.
- rtos: Path to RTOS plugin for thread-aware debugging.
48 def start(self): 49 self.process = call(self.device, self.speed, self.serial, self.rtos, 50 blocking=False, silent=True) 51 LOGGER.info(f"Starting {self.process.pid}...")
Starts the debug probe as a non-blocking subprocess.
53 def stop(self): 54 if self.process is not None: 55 LOGGER.info(f"Stopping {self.process.pid}.") 56 os.killpg(os.getpgid(self.process.pid), signal.SIGINT) 57 os.waitpid(os.getpgid(self.process.pid), 0) 58 self.process = None
Halts the debug probe process.
Inherited Members
62def call(device: str, speed: int, serial: str = None, rtos: Path = None, 63 blocking: bool = True, silent: bool = False) -> "int | subprocess.Popen": 64 """ 65 Starts the `JLinkGDBServer` and connects to the microcontroller without 66 resetting the device and without GUI. You can overwrite the default binary 67 by exporting an alternative in your environment: 68 69 ```sh 70 export PX4_JLINK_GDB_SERVER=path/to/JLinkGDBServer 71 ``` 72 73 :param device: part name of the microcontroller to debug. 74 :param speed: SWD connection baudrate in kHz. 75 :param serial: Serial number of J-Link for selection. 76 :param rtos: Path to RTOS plugin for thread-aware debugging. 77 :param blocking: Run in current process as a blocking call. 78 Set to `False` to run in a new subprocess. 79 :param silent: Disable any reporting from `JLinkGDBServer`. 80 81 :return: The process return code if `blocking` or the Popen object. 82 """ 83 binary = os.environ.get("PX4_JLINK_GDB_SERVER", "JLinkGDBServer") 84 85 command_jlink = f"{binary} -device {device} -speed {speed} -if swd -noreset -nogui" 86 if serial: command_jlink += f" -SelectEmuBySN {serial}" 87 if rtos: command_jlink += f" -rtos {Path(rtos).absolute()}" 88 if silent: command_jlink += " -silent" 89 90 LOGGER.debug(command_jlink) 91 92 kwargs = {"cwd": os.getcwd(), "shell": True} 93 if blocking: 94 return subprocess.call(command_jlink, **kwargs) 95 96 # Disconnect the JLink process from this process, so that any Ctrl-C usage 97 # in GDB does not get passed on to the JLink process. 98 kwargs["start_new_session"] = True 99 return subprocess.Popen(command_jlink, **kwargs)
Starts the JLinkGDBServer
and connects to the microcontroller without
resetting the device and without GUI. You can overwrite the default binary
by exporting an alternative in your environment:
export PX4_JLINK_GDB_SERVER=path/to/JLinkGDBServer
Parameters
- device: part name of the microcontroller to debug.
- speed: SWD connection baudrate in kHz.
- serial: Serial number of J-Link for selection.
- rtos: Path to RTOS plugin for thread-aware debugging.
- blocking: Run in current process as a blocking call.
Set to
False
to run in a new subprocess. - silent: Disable any reporting from
JLinkGDBServer
.
Returns
The process return code if
blocking
or the Popen object.
103def itm(device: str, baudrate: int = None, port: int = None, serial: str = None) -> int: 104 """ 105 Launches `JLinkSWOViewer`, connects to the microcontroller. You can 106 overwrite the default binary by exporting an alternative in your environment: 107 108 ```sh 109 export PX4_JLINK_SWO_VIEWER=path/to/JLinkSWOViewer 110 ``` 111 112 :param device: part name of the microcontroller to debug. 113 :param baudrate: optional frequency of the SWO connection. 114 :param port: ITM port to display at startup. You can modify this at runtime. 115 :param serial: Serial number of J-Link for selection. 116 117 :return: the process return code 118 """ 119 binary = os.environ.get("PX4_JLINK_SWO_VIEWER", "JLinkSWOViewer") 120 command_jlink = f"{binary} -device {device} -itmport {port or 0}" 121 if baudrate: command_jlink += f" -swofreq {baudrate}" 122 try: 123 return subprocess.call(command_jlink, shell=True) 124 except KeyboardInterrupt: 125 pass
Launches JLinkSWOViewer
, connects to the microcontroller. You can
overwrite the default binary by exporting an alternative in your environment:
export PX4_JLINK_SWO_VIEWER=path/to/JLinkSWOViewer
Parameters
- device: part name of the microcontroller to debug.
- baudrate: optional frequency of the SWO connection.
- port: ITM port to display at startup. You can modify this at runtime.
- serial: Serial number of J-Link for selection.
Returns
the process return code
128def rtt(backend: JLinkBackend, channel: int = 0) -> int: 129 """ 130 Launches the backend in the background and connects a telnet client to the 131 Real-Time Transfer process. You can disconnect with Ctrl+D. 132 133 :param backend: A J-Link backend object. 134 :param channel: The RTT channel to connect to. 135 136 :return: the process return code 137 """ 138 import telnetlib 139 # Start JLinkGDBServer in the background 140 with backend.scope(): 141 with telnetlib.Telnet("localhost", 19021) as tn: 142 try: 143 tn.interact() 144 except KeyboardInterrupt: 145 pass 146 return 0
Launches the backend in the background and connects a telnet client to the Real-Time Transfer process. You can disconnect with Ctrl+D.
Parameters
- backend: A J-Link backend object.
- channel: The RTT channel to connect to.
Returns
the process return code
149def erase(device: str, speed: int, address_range: tuple[int, int] = None, 150 serial: str = None) -> int: 151 """ 152 Erases (part of) the device via JLink. 153 154 :param device: part name of the microcontroller to program. You can 155 overwrite the default binary by exporting an alternative in 156 your environment: 157 ```sh 158 export PX4_JLINK=path/to/JLinkExe 159 ``` 160 :param speed: SWD connection baudrate in kHz. 161 :param address_range: Optional [start, end] address to erase only part of device. 162 :param serial: Serial number of J-Link for selection. 163 164 :return: the process return code of JLink 165 """ 166 binary = os.environ.get("PX4_JLINK", "JLinkExe") 167 if address_range is not None: 168 address_range = f"{address_range[0]} {address_range[1]}" 169 with tempfile.NamedTemporaryFile() as fcmd: 170 commands = f"Erase {address_range or ''}\nExit" 171 Path(fcmd.name).write_text(commands) 172 jcmd = f"{binary} -device {device} -speed {speed} -ExitOnError 1 " \ 173 f"-if swd -autoconnect 1 -nogui 1 -commandfile {fcmd.name}" 174 if serial: jcmd += f" -SelectEmuBySN {serial}" 175 LOGGER.debug(f"{jcmd}\n{commands}") 176 return subprocess.call(jcmd, shell=True)
Erases (part of) the device via JLink.
Parameters
device: part name of the microcontroller to program. You can overwrite the default binary by exporting an alternative in your environment:
export PX4_JLINK=path/to/JLinkExe
speed: SWD connection baudrate in kHz.
- address_range: Optional [start, end] address to erase only part of device.
- serial: Serial number of J-Link for selection.
Returns
the process return code of JLink
178def program(source: Path, device: str, speed: int, serial: str = None, load_addr: int = None) -> int: 179 """ 180 Loads the source file into the microcontroller and resets the device. You can 181 overwrite the default binary by exporting an alternative in your environment: 182 183 ```sh 184 export PX4_JLINK=path/to/JLinkExe 185 ``` 186 187 :param source: path to a `.bin`, `.hex`, or `.elf` file to upload. 188 :param device: part name of the microcontroller to program. 189 :param speed: SWD connection baudrate in kHz. 190 :param serial: Serial number of J-Link for selection. 191 :param load_addr: Specifies the start address to load a `.bin` file. 192 193 :return: the process return code of JLink 194 """ 195 binary = os.environ.get("PX4_JLINK", "JLinkExe") 196 if load_addr is None and Path(source).suffix == ".bin": 197 load_addr = 0x0800_0000 198 with tempfile.NamedTemporaryFile() as fcmd: 199 # LoadFile erases the correct amount of sectors, then writes the new 200 # binary or hex file. We still need to reset afterwards. 201 commands = f"LoadFile {source} {load_addr or ''}\nReset\nExit" 202 Path(fcmd.name).write_text(commands) 203 jcmd = f"{binary} -device {device} -speed {speed} -ExitOnError 1 " \ 204 f"-if swd -autoconnect 1 -nogui 1 -commandfile {fcmd.name}" 205 if serial: jcmd += f" -SelectEmuBySN {serial}" 206 LOGGER.debug(f"{jcmd}\n{commands}") 207 return subprocess.call(jcmd, shell=True)
Loads the source file into the microcontroller and resets the device. You can overwrite the default binary by exporting an alternative in your environment:
export PX4_JLINK=path/to/JLinkExe
Parameters
- source: path to a
.bin
,.hex
, or.elf
file to upload. - device: part name of the microcontroller to program.
- speed: SWD connection baudrate in kHz.
- serial: Serial number of J-Link for selection.
- load_addr: Specifies the start address to load a
.bin
file.
Returns
the process return code of JLink
209def reset(device: str, speed: int, serial: str = None) -> int: 210 """ 211 Resets the device via JLink. 212 213 :param device: part name of the microcontroller to program. You can 214 overwrite the default binary by exporting an alternative in 215 your environment: 216 ```sh 217 export PX4_JLINK=path/to/JLinkExe 218 ``` 219 :param speed: SWD connection baudrate in kHz. 220 :param serial: Serial number of J-Link for selection. 221 222 :return: the process return code of JLink 223 """ 224 binary = os.environ.get("PX4_JLINK", "JLinkExe") 225 with tempfile.NamedTemporaryFile() as fcmd: 226 commands = "Reset\nExit" 227 Path(fcmd.name).write_text(commands) 228 jcmd = f"{binary} -device {device} -speed {speed} -ExitOnError 1 " \ 229 f"-if swd -autoconnect 1 -nogui 1 -commandfile {fcmd.name}" 230 if serial: jcmd += f" -SelectEmuBySN {serial}" 231 LOGGER.debug(f"{jcmd}\n{commands}") 232 return subprocess.call(jcmd, shell=True)
Resets the device via JLink.
Parameters
device: part name of the microcontroller to program. You can overwrite the default binary by exporting an alternative in your environment:
export PX4_JLINK=path/to/JLinkExe
speed: SWD connection baudrate in kHz.
- serial: Serial number of J-Link for selection.
Returns
the process return code of JLink