Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement debug command #94

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions tockloader/board_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -594,3 +594,9 @@ def _align_and_stretch_to_page(self, address, binary):
binary = binary + after_binary

return (address, binary)

def debug_binary(self, binary):
"""
Debug the binary on the board.
"""
return
5 changes: 5 additions & 0 deletions tockloader/jlinkexe.py
Original file line number Diff line number Diff line change
Expand Up @@ -459,3 +459,8 @@ def run_terminal(self):
l = stdout_line.decode("utf-8")
if not l.startswith("###RTT Client: *"):
print(l, end="")

def debug(self, binary):
logging.error(
"This functionality is not implemented for JLink"
)
bradjc marked this conversation as resolved.
Show resolved Hide resolved
24 changes: 24 additions & 0 deletions tockloader/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,20 @@ def command_flash(args):
logging.status("Flashing binar{} to board...".format(plural))
tock_loader.flash_binary(binary, args.address, pad=pad)

def command_debug(args):
# Check if binary exists
if not os.path.exists(args.binary):
raise TockLoaderException("{} does not exist".format(args.binary))

# For now, we do not compile or flash binary on the board

# Debug the binary to the chip
tock_loader = TockLoader(args)
tock_loader.open()

logging.status("Debug binary {} to board...".format(args.binary))
tock_loader.debug_binary(args.binary)


def command_read(args):
"""
Expand Down Expand Up @@ -1056,6 +1070,16 @@ def main():
)
list_known_boards.set_defaults(func=command_list_known_boards)

debug_binary = subparser.add_parser(
"debug-binary",
parents=[parent, parent_channel],
help="Debug the binary installed on the board",
)
debug_binary.set_defaults(func=command_debug)
debug_binary.add_argument(
"--binary", help="The binary file or files to flash to the chip"
bradjc marked this conversation as resolved.
Show resolved Hide resolved
)

argcomplete.autocomplete(parser)
args, unknown_args = parser.parse_known_args()

Expand Down
92 changes: 92 additions & 0 deletions tockloader/openocd.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
import subprocess
import tempfile
import time
import os
import signal

from .board_interface import BoardInterface
from .exceptions import TockLoaderException
Expand Down Expand Up @@ -450,3 +452,93 @@ def run_terminal(self):
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)

def _run_gdb_server(self):
self.open_link_to_board()
logging.status("Starting OpenOCD debug server.")
openocd_command, _ = self._gather_openocd_cmdline(
[],
None,
exit=False,
)

logging.debug('Running "{}".'.format(openocd_command.replace("$", "\$")))

cflags = 0
preexec = None
system = platform.system()

# Create new process preventing to catch Ctrl+C
if system == 'Windows':
cflags |= subprocess.CREATE_NEW_PROCESS_GROUP
elif system in {'Linux', 'Darwin'}:
preexec = os.setsid

# This won't print messages from OpenOCD,
# to avoid interfering with the console.
ocd_p = subprocess.Popen(
shlex.split(openocd_command),
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
preexec_fn=preexec,
creationflags=cflags,
)

return ocd_p

def _run_gdb_client(self, binary):
gdb_command = f'arm-none-eabi-gdb --exec {binary} --symbols {binary} -eval-command="target remote localhost:3333"'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would gdb-multiarch work just as well here? Otherwise this command only works on arm boards

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right.

I think gdb-multiarch is not present on a lot of system. People tends to use gdb or arm-none-eabi-gdb.

So, to use the correct gdb, I suggest this:

  • Check for "gdb-multiarch" in PATH
  • If not in PATH, use gdb or arm-none-eabi-gdb depending on self.arch variable.

Would it be better ?

Thanks

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choosing based on the board arch is fine. Maybe that won't work in all cases, but that is OK for now.


logging.debug('Running "{}".'.format(gdb_command))

# Ignore SIGINT. gdb must be exited properly by user
previous = signal.signal(signal.SIGINT, signal.SIG_IGN)

gdb_p = subprocess.Popen(
shlex.split(gdb_command),
)

gdb_p.wait()

signal.signal(signal.SIGINT, previous)

return gdb_p

def _reset_board(self):
openocd_command, _ = self._gather_openocd_cmdline(
[
"reset halt",
],
None,
)
subprocess.run(
shlex.split(openocd_command),
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)

def debug(self, binary):
cleanup = []
try:
ocd_p = self._run_gdb_server()

cleanup.append(ocd_p.wait)
cleanup.append(ocd_p.kill)

time.sleep(1)
if ocd_p.poll():
logging.error('Openocd server not running')
raise

gdb_p = self._run_gdb_client(binary)

cleanup.append(gdb_p.wait)
cleanup.append(gdb_p.kill)
except:
logging.error("Can't start debugg session")
bradjc marked this conversation as resolved.
Show resolved Hide resolved
finally:
logging.status("Stopping debug session")
for f in reversed(cleanup):
f()

self._reset_board()
7 changes: 7 additions & 0 deletions tockloader/tockloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -1440,3 +1440,10 @@ def _print_apps(self, apps, verbose, quiet):
else:
# In quiet mode just show the names.
print(" ".join([app.get_name() for app in apps]))

def debug_binary(self, binary):
bradjc marked this conversation as resolved.
Show resolved Hide resolved
"""
"""
# Enter bootloader mode to get things started
with self._start_communication_with_board():
self.channel.debug(binary)