intel_s1000.py 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. # Copyright (c) 2018 Intel Corporation.
  2. # Copyright 2018 Open Source Foundries Limited.
  3. #
  4. # SPDX-License-Identifier: Apache-2.0
  5. '''Runner for debugging and flashing Intel S1000 CRB'''
  6. from os import path
  7. import time
  8. import signal
  9. from runners.core import ZephyrBinaryRunner
  10. DEFAULT_XT_GDB_PORT = 20000
  11. class IntelS1000BinaryRunner(ZephyrBinaryRunner):
  12. '''Runner front-end for Intel S1000.'''
  13. def __init__(self, cfg, xt_ocd_dir,
  14. ocd_topology, ocd_jtag_instr, gdb_flash_file,
  15. gdb_port=DEFAULT_XT_GDB_PORT):
  16. super().__init__(cfg)
  17. self.board_dir = cfg.board_dir
  18. self.elf_name = cfg.elf_file
  19. self.gdb_cmd = cfg.gdb
  20. self.xt_ocd_dir = xt_ocd_dir
  21. self.ocd_topology = ocd_topology
  22. self.ocd_jtag_instr = ocd_jtag_instr
  23. self.gdb_flash_file = gdb_flash_file
  24. self.gdb_port = gdb_port
  25. @classmethod
  26. def name(cls):
  27. return 'intel_s1000'
  28. @classmethod
  29. def do_add_parser(cls, parser):
  30. # Optional
  31. parser.add_argument(
  32. '--xt-ocd-dir', default='/opt/tensilica/xocd-12.0.4/xt-ocd',
  33. help='ocd-dir, defaults to /opt/tensilica/xocd-12.0.4/xt-ocd')
  34. parser.add_argument(
  35. '--ocd-topology', default='topology_dsp0_flyswatter2.xml',
  36. help='ocd-topology, defaults to topology_dsp0_flyswatter2.xml')
  37. parser.add_argument(
  38. '--ocd-jtag-instr', default='dsp0_gdb.txt',
  39. help='ocd-jtag-instr, defaults to dsp0_gdb.txt')
  40. parser.add_argument(
  41. '--gdb-flash-file', default='load_elf.txt',
  42. help='gdb-flash-file, defaults to load_elf.txt')
  43. parser.add_argument(
  44. '--gdb-port', default=DEFAULT_XT_GDB_PORT,
  45. help='xt-gdb port, defaults to 20000')
  46. @classmethod
  47. def do_create(cls, cfg, args):
  48. return IntelS1000BinaryRunner(
  49. cfg, args.xt_ocd_dir,
  50. args.ocd_topology, args.ocd_jtag_instr, args.gdb_flash_file,
  51. gdb_port=args.gdb_port)
  52. def do_run(self, command, **kwargs):
  53. self.require(self.xt_ocd_dir)
  54. kwargs['ocd-topology'] = path.join(self.board_dir, 'support',
  55. self.ocd_topology)
  56. kwargs['ocd-jtag-instr'] = path.join(self.board_dir, 'support',
  57. self.ocd_jtag_instr)
  58. kwargs['gdb-flash-file'] = path.join(self.board_dir, 'support',
  59. self.gdb_flash_file)
  60. if command == 'flash':
  61. self.flash(**kwargs)
  62. elif command == 'debugserver':
  63. self.debugserver(**kwargs)
  64. else:
  65. self.do_debug(**kwargs)
  66. def flash(self, **kwargs):
  67. if self.gdb_cmd is None:
  68. raise ValueError('Cannot debug; no gdb specified')
  69. self.require(self.gdb_cmd)
  70. topology_file = kwargs['ocd-topology']
  71. jtag_instr_file = kwargs['ocd-jtag-instr']
  72. gdb_flash_file = kwargs['gdb-flash-file']
  73. self.log_gdbserver_message(self.gdb_port)
  74. server_cmd = [self.xt_ocd_dir,
  75. '-c', topology_file,
  76. '-I', jtag_instr_file]
  77. # Start the server
  78. # Note that XTOCD takes a few seconds to execute and always fails the
  79. # first time. It has to be relaunched the second time to work.
  80. server_proc = self.popen_ignore_int(server_cmd)
  81. time.sleep(6)
  82. server_proc.terminate()
  83. server_proc = self.popen_ignore_int(server_cmd)
  84. time.sleep(6)
  85. # Start the client
  86. gdb_cmd = [self.gdb_cmd, '-x', gdb_flash_file]
  87. client_proc = self.popen_ignore_int(gdb_cmd)
  88. # Wait for 3 seconds (waiting for XTGDB to finish loading the image)
  89. time.sleep(3)
  90. # At this point, the ELF image is loaded and the program is in
  91. # execution. Now we can quit the client (xt-gdb) and the server
  92. # (xt-ocd) as they are not needed anymore. The loaded program
  93. # (ELF) will continue to run though.
  94. client_proc.terminate()
  95. server_proc.terminate()
  96. def do_debug(self, **kwargs):
  97. if self.elf_name is None:
  98. raise ValueError('Cannot debug; elf is missing')
  99. if self.gdb_cmd is None:
  100. raise ValueError('Cannot debug; no gdb specified')
  101. self.require(self.gdb_cmd)
  102. topology_file = kwargs['ocd-topology']
  103. jtag_instr_file = kwargs['ocd-jtag-instr']
  104. self.log_gdbserver_message(self.gdb_port)
  105. server_cmd = [self.xt_ocd_dir,
  106. '-c', topology_file,
  107. '-I', jtag_instr_file]
  108. # Start the server
  109. # Note that XTOCD takes a few seconds to execute and always fails the
  110. # first time. It has to be relaunched the second time to work.
  111. server_proc = self.popen_ignore_int(server_cmd)
  112. time.sleep(6)
  113. server_proc.terminate()
  114. server_proc = self.popen_ignore_int(server_cmd)
  115. time.sleep(6)
  116. gdb_cmd = [self.gdb_cmd,
  117. '-ex', 'target remote :{}'.format(self.gdb_port),
  118. self.elf_name]
  119. # Start the client
  120. # The below statement will consume the "^C" keypress ensuring
  121. # the python main application doesn't exit. This is important
  122. # since ^C in gdb means a "halt" operation.
  123. previous = signal.signal(signal.SIGINT, signal.SIG_IGN)
  124. try:
  125. self.check_call(gdb_cmd)
  126. finally:
  127. signal.signal(signal.SIGINT, previous)
  128. server_proc.terminate()
  129. server_proc.wait()
  130. def debugserver(self, **kwargs):
  131. topology_file = kwargs['ocd-topology']
  132. jtag_instr_file = kwargs['ocd-jtag-instr']
  133. self.log_gdbserver_message(self.gdb_port)
  134. server_cmd = [self.xt_ocd_dir,
  135. '-c', topology_file,
  136. '-I', jtag_instr_file]
  137. # Note that XTOCD takes a few seconds to execute and always fails the
  138. # first time. It has to be relaunched the second time to work.
  139. server_proc = self.popen_ignore_int(server_cmd)
  140. time.sleep(6)
  141. server_proc.terminate()
  142. self.check_call(server_cmd)
  143. def log_gdbserver_message(self, gdb_port):
  144. self.logger.info('Intel S1000 GDB server running on port {}'.
  145. format(gdb_port))