blackmagicprobe.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. # Copyright (c) 2018 Roman Tataurov <diytronic@yandex.ru>
  2. # Modified 2018 Tavish Naruka <tavishnaruka@gmail.com>
  3. #
  4. # SPDX-License-Identifier: Apache-2.0
  5. '''Runner for flashing with Black Magic Probe.'''
  6. # https://github.com/blacksphere/blackmagic/wiki
  7. import signal
  8. from runners.core import ZephyrBinaryRunner, RunnerCaps
  9. class BlackMagicProbeRunner(ZephyrBinaryRunner):
  10. '''Runner front-end for Black Magic probe.'''
  11. def __init__(self, cfg, gdb_serial):
  12. super().__init__(cfg)
  13. self.gdb = [cfg.gdb] if cfg.gdb else None
  14. self.elf_file = cfg.elf_file
  15. self.gdb_serial = gdb_serial
  16. @classmethod
  17. def name(cls):
  18. return 'blackmagicprobe'
  19. @classmethod
  20. def capabilities(cls):
  21. return RunnerCaps(commands={'flash', 'debug', 'attach'})
  22. @classmethod
  23. def do_create(cls, cfg, args):
  24. return BlackMagicProbeRunner(cfg, args.gdb_serial)
  25. @classmethod
  26. def do_add_parser(cls, parser):
  27. parser.add_argument('--gdb-serial', default='/dev/ttyACM0',
  28. help='GDB serial port')
  29. def bmp_flash(self, command, **kwargs):
  30. if self.elf_file is None:
  31. raise ValueError('Cannot debug; elf file is missing')
  32. command = (self.gdb +
  33. ['-ex', "set confirm off",
  34. '-ex', "target extended-remote {}".format(self.gdb_serial),
  35. '-ex', "monitor swdp_scan",
  36. '-ex', "attach 1",
  37. '-ex', "load {}".format(self.elf_file),
  38. '-ex', "kill",
  39. '-ex', "quit",
  40. '-silent'])
  41. self.check_call(command)
  42. def check_call_ignore_sigint(self, command):
  43. previous = signal.signal(signal.SIGINT, signal.SIG_IGN)
  44. try:
  45. self.check_call(command)
  46. finally:
  47. signal.signal(signal.SIGINT, previous)
  48. def bmp_attach(self, command, **kwargs):
  49. if self.elf_file is None:
  50. command = (self.gdb +
  51. ['-ex', "set confirm off",
  52. '-ex', "target extended-remote {}".format(
  53. self.gdb_serial),
  54. '-ex', "monitor swdp_scan",
  55. '-ex', "attach 1"])
  56. else:
  57. command = (self.gdb +
  58. ['-ex', "set confirm off",
  59. '-ex', "target extended-remote {}".format(
  60. self.gdb_serial),
  61. '-ex', "monitor swdp_scan",
  62. '-ex', "attach 1",
  63. '-ex', "file {}".format(self.elf_file)])
  64. self.check_call_ignore_sigint(command)
  65. def bmp_debug(self, command, **kwargs):
  66. if self.elf_file is None:
  67. raise ValueError('Cannot debug; elf file is missing')
  68. command = (self.gdb +
  69. ['-ex', "set confirm off",
  70. '-ex', "target extended-remote {}".format(self.gdb_serial),
  71. '-ex', "monitor swdp_scan",
  72. '-ex', "attach 1",
  73. '-ex', "file {}".format(self.elf_file),
  74. '-ex', "load {}".format(self.elf_file)])
  75. self.check_call_ignore_sigint(command)
  76. def do_run(self, command, **kwargs):
  77. if self.gdb is None:
  78. raise ValueError('Cannot execute; gdb not specified')
  79. self.require(self.gdb[0])
  80. if command == 'flash':
  81. self.bmp_flash(command, **kwargs)
  82. elif command == 'debug':
  83. self.bmp_debug(command, **kwargs)
  84. elif command == 'attach':
  85. self.bmp_attach(command, **kwargs)
  86. else:
  87. self.bmp_flash(command, **kwargs)