scripts: runners: improvements for spi_burn west runner

Following changes has been made by this commit:
    - fix issue when a binary is not able to be found by relative path
    - implement "west debug" command
    - implement --dt-flash option

Signed-off-by: Alex Kolosov <rikorsev@gmail.com>
diff --git a/boards/common/spi_burn.board.cmake b/boards/common/spi_burn.board.cmake
index 3a6c27c..d52a4a0 100644
--- a/boards/common/spi_burn.board.cmake
+++ b/boards/common/spi_burn.board.cmake
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: Apache-2.0
 
 board_set_flasher_ifnset(spi_burn)
+board_set_debugger_ifnset(spi_burn)
 board_finalize_runner_args(spi_burn)
diff --git a/boards/riscv/tlsr9518adk80d/board.cmake b/boards/riscv/tlsr9518adk80d/board.cmake
index 6226c57..c65504f 100644
--- a/boards/riscv/tlsr9518adk80d/board.cmake
+++ b/boards/riscv/tlsr9518adk80d/board.cmake
@@ -1,4 +1,4 @@
 # SPDX-License-Identifier: Apache-2.0
 
-board_runner_args(spi_burn --addr 0x0)
+board_runner_args(spi_burn)
 include(${ZEPHYR_BASE}/boards/common/spi_burn.board.cmake)
diff --git a/boards/riscv/tlsr9518adk80d/doc/index.rst b/boards/riscv/tlsr9518adk80d/doc/index.rst
index 411f3d6..b2b1c16 100644
--- a/boards/riscv/tlsr9518adk80d/doc/index.rst
+++ b/boards/riscv/tlsr9518adk80d/doc/index.rst
@@ -279,7 +279,24 @@
 Debugging
 =========
 
-Supporting UART debug and OpenOCD+GDB.
+This port supports UART debug and OpenOCD+GDB. The `west debug` command also supported. You may run
+it in a simple way, like:
+
+.. code-block:: console
+
+   west debug
+
+Or with additional arguments, like:
+
+.. code-block:: console
+
+   west debug --gdb-port=<port_number> --gdb-ex=<additional_ex_arguments>
+
+Example:
+
+.. code-block:: console
+
+   west debug --gdb-port=1111 --gdb-ex="-ex monitor reset halt -ex b main -ex continue"
 
 References
 **********
diff --git a/scripts/west_commands/runners/spi_burn.py b/scripts/west_commands/runners/spi_burn.py
index 7785856..265d1cd 100644
--- a/scripts/west_commands/runners/spi_burn.py
+++ b/scripts/west_commands/runners/spi_burn.py
@@ -2,24 +2,26 @@
 #
 # SPDX-License-Identifier: Apache-2.0
 
+import re
 import os
 import time
 import subprocess
 
-from runners.core import ZephyrBinaryRunner, RunnerCaps
+from runners.core import ZephyrBinaryRunner, RunnerCaps, BuildConfiguration
 
 class SpiBurnBinaryRunner(ZephyrBinaryRunner):
     '''Runner front-end for SPI_burn.'''
 
-    def __init__(self, cfg, addr, spiburn, iceman, timeout, erase=False):
+    def __init__(self, cfg, addr, spiburn, iceman, timeout, gdb_port, gdb_ex, erase=False):
         super().__init__(cfg)
 
-        self.bin = cfg.bin_file
         self.spiburn = spiburn
         self.iceman = iceman
         self.addr = addr
         self.timeout = int(timeout)
         self.erase = bool(erase)
+        self.gdb_port = gdb_port
+        self.gdb_ex = gdb_ex
 
     @classmethod
     def name(cls):
@@ -27,7 +29,7 @@
 
     @classmethod
     def capabilities(cls):
-        return RunnerCaps(commands={'flash'}, erase=True)
+        return RunnerCaps(commands={'flash', 'debug'}, erase=True, flash_addr=True)
 
     @classmethod
     def do_add_parser(cls, parser):
@@ -36,6 +38,8 @@
         parser.add_argument('--timeout', default=10,
                             help='ICEman connection establishing timeout in seconds')
         parser.add_argument('--telink-tools-path', help='path to Telink flash tools')
+        parser.add_argument('--gdb-port', default='1111', help='Port to connect for gdb-client')
+        parser.add_argument('--gdb-ex', default='', nargs='?', help='Additional gdb commands to run')
 
     @classmethod
     def do_create(cls, cfg, args):
@@ -48,7 +52,14 @@
             spiburn = 'SPI_burn'
             iceman  = 'ICEman'
 
-        return SpiBurnBinaryRunner(cfg, args.addr, spiburn, iceman, args.timeout, args.erase)
+        # Get flash address offset
+        if args.dt_flash == 'y':
+            build_conf = BuildConfiguration(cfg.build_dir)
+            address = hex(cls.get_flash_address(args, build_conf) - build_conf['CONFIG_FLASH_BASE_ADDRESS'])
+        else:
+            address = args.addr
+
+        return SpiBurnBinaryRunner(cfg, address, spiburn, iceman, args.timeout, args.gdb_port, args.gdb_ex, args.erase)
 
     def do_run(self, command, **kwargs):
 
@@ -59,14 +70,19 @@
 
         if command == "flash":
             self._flash()
+
+        elif command == "debug":
+            self._debug()
+
         else:
             self.logger.error(f'{command} not supported!')
 
     def start_iceman(self):
 
         # Start ICEman as background process
-        cmd_ice_run = ["./ICEman", '-Z', 'v5', '-l', 'aice_sdp.cfg']
-        self.ice_process = subprocess.Popen(cmd_ice_run, stdout=subprocess.PIPE)
+        self.ice_process = self.popen_ignore_int(["./ICEman", '-Z', 'v5', '-l', 'aice_sdp.cfg'],
+                                                            cwd=os.path.dirname(self.iceman_path),
+                                                            stdout=subprocess.PIPE)
 
         # Wait till it ready or exit by timeout
         start = time.time()
@@ -83,23 +99,13 @@
 
     def _flash(self):
 
-        origin_dir = os.getcwd()
-        iceman_dir = os.path.dirname(self.iceman_path)
-
         try:
 
-            # ICEman tool from Andestech is required to be run from its root dir,
-            # due to the tool looking for its config files in currently active dir.
-            # In attempt to run it from other dirs it returns with an error that
-            # required config file is missing
-
-            # Go into ICEman dir
-            os.chdir(iceman_dir)
-
+            # Start ICEman
             self.start_iceman()
 
             # Compose flash command
-            cmd_flash = [self.spiburn, '--addr', str(self.addr), '--image', self.bin]
+            cmd_flash = [self.spiburn, '--addr', str(self.addr), '--image', self.cfg.bin_file]
 
             if self.erase:
                 cmd_flash += ["--erase-all"]
@@ -110,5 +116,21 @@
         finally:
             self.stop_iceman()
 
-            # Restore origin dir
-            os.chdir(origin_dir)
+    def _debug(self):
+
+        try:
+
+            # Start ICEman
+            self.start_iceman()
+
+            # format -ex commands
+            gdb_ex = re.split("(-ex) ", self.gdb_ex)[1::]
+
+            # Compose gdb command
+            client_cmd = [self.cfg.gdb, self.cfg.elf_file, '-ex', f'target remote :{self.gdb_port}'] + gdb_ex
+
+            # Run gdb
+            self.run_client(client_cmd)
+
+        finally:
+            self.stop_iceman()