From a4e7eb4233af541f1e4fb23c7205fccbe62963ad Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Fri, 24 Nov 2023 15:48:49 +0100 Subject: [PATCH] Debugger now allows generic selection of sub-configurations (#2435) * debug: extend hotfix for trailing dash '-' to all toolchains * Added additional_config selector for debug configuration * Added docs --- commands/debug/debug_info.go | 12 ++-- docs/platform-specification.md | 68 +++++++++++++++++++ internal/integrationtest/debug/debug_test.go | 57 ++++++++++++++++ .../testdata/hardware/my/samd/boards.txt | 25 +++++++ .../testdata/hardware/my/samd/platform.txt | 5 ++ 5 files changed, 163 insertions(+), 4 deletions(-) create mode 100644 internal/integrationtest/debug/testdata/hardware/my/samd/platform.txt diff --git a/commands/debug/debug_info.go b/commands/debug/debug_info.go index ec254e8912e..6b8064e9d8f 100644 --- a/commands/debug/debug_info.go +++ b/commands/debug/debug_info.go @@ -133,6 +133,12 @@ func getDebugProperties(req *rpc.GetDebugConfigRequest, pme *packagemanager.Expl for k, v := range toolProperties.SubTree("debug").AsMap() { debugProperties.Set(k, toolProperties.ExpandPropsInString(v)) } + if debugAdditionalConfig, ok := toolProperties.GetOk("debug.additional_config"); ok { + debugAdditionalConfig = toolProperties.ExpandPropsInString(debugAdditionalConfig) + for k, v := range toolProperties.SubTree(debugAdditionalConfig).AsMap() { + debugProperties.Set(k, toolProperties.ExpandPropsInString(v)) + } + } if !debugProperties.ContainsKey("executable") { return nil, &arduino.FailedDebugError{Message: tr("Debugging not supported for board %s", req.GetFqbn())} @@ -169,12 +175,10 @@ func getDebugProperties(req *rpc.GetDebugConfigRequest, pme *packagemanager.Expl } } + toolchainPrefix := debugProperties.Get("toolchain.prefix") // HOTFIX: for samd (and maybe some other platforms). We should keep this for a reasonable // amount of time to allow seamless platforms update. - toolchainPrefix := debugProperties.Get("toolchain.prefix") - if toolchainPrefix == "arm-none-eabi-" { - toolchainPrefix = "arm-none-eabi" - } + toolchainPrefix = strings.TrimSuffix(toolchainPrefix, "-") customConfigs := map[string]string{} if cortexDebugProps := debugProperties.SubTree("cortex-debug.custom"); cortexDebugProps.Size() > 0 { diff --git a/docs/platform-specification.md b/docs/platform-specification.md index 43d778a6d1d..8e690cb0787 100644 --- a/docs/platform-specification.md +++ b/docs/platform-specification.md @@ -1452,6 +1452,74 @@ will result in the following JSON: } ``` +### Additional debugger config selection via `debug.additional_config` directive. + +It is possible to use any sub-tree of the platform configuration to override the debugger configuration using the +directive `debug.additional_config=CONFIG_PREFIX`. This rule will use the configuration under `CONFIG_PREFIX.*` to +override the current `debug.*` config. + +This change allows a more convenient rationalization and selection of the configs to apply to the debugger. For example, +we could factor common parts of a configuration in the platform.txt file: + +``` +# CONFIG 1 +debug-overrides.esp32.cortex-debug.custom.name=Arduino on ESP32 +debug-overrides.esp32.cortex-debug.custom.request=attach +debug-overrides.esp32.cortex-debug.custom.postAttachCommands.0=set remote hardware-watchpoint-limit 2 +debug-overrides.esp32.cortex-debug.custom.postAttachCommands.1=monitor reset halt +debug-overrides.esp32.cortex-debug.custom.postAttachCommands.2=monitor gdb_sync +debug-overrides.esp32.cortex-debug.custom.postAttachCommands.3=thb setup +debug-overrides.esp32.cortex-debug.custom.postAttachCommands.4=c +debug-overrides.esp32.cortex-debug.custom.overrideRestartCommands.0=monitor reset halt +debug-overrides.esp32.cortex-debug.custom.overrideRestartCommands.1=monitor gdb_sync +debug-overrides.esp32.cortex-debug.custom.overrideRestartCommands.2=thb setup +debug-overrides.esp32.cortex-debug.custom.overrideRestartCommands.3=c + +# CONFIG 2 +debug-overrides.esp32s2.cortex-debug.custom.name=Arduino on ESP32-S2 +debug-overrides.esp32s2.cortex-debug.custom.request=attach +debug-overrides.esp32s2.cortex-debug.custom.postAttachCommands.0=set remote hardware-watchpoint-limit 2 +debug-overrides.esp32s2.cortex-debug.custom.postAttachCommands.1=monitor reset halt +debug-overrides.esp32s2.cortex-debug.custom.postAttachCommands.2=monitor gdb_sync +debug-overrides.esp32s2.cortex-debug.custom.postAttachCommands.3=thb setup +debug-overrides.esp32s2.cortex-debug.custom.postAttachCommands.4=c +debug-overrides.esp32s2.cortex-debug.custom.overrideRestartCommands.0=monitor reset halt +debug-overrides.esp32s2.cortex-debug.custom.overrideRestartCommands.1=monitor gdb_sync +debug-overrides.esp32s2.cortex-debug.custom.overrideRestartCommands.2=thb setup +debug-overrides.esp32s2.cortex-debug.custom.overrideRestartCommands.3=c +``` + +and choose which one to use depending on the board in the boards.txt file: + +``` +myboard.name=My Board with esp32 +myboard.debug.additional_config=debug-overrides.esp32 + +anotherboard.name=My Board with esp32s2 +anotherboard.debug.additional_config=debug-overrides.esp32s2 +... +``` + +Another possibility is to compose the configuration using another variable present in the board configuration, for +example if in the `platform.txt` we add: + +``` +debug.additional_config=debug-overrides.{build.mcu} +``` + +we may use the `build.mcu` value as a "selector" for the board-specific debug configuration that is overlapped to the +global debug configuration: + +``` +myboard.name=My Board with esp32 +myboard.build.mcu=esp32 +... + +anotherboard.name=My Board with esp32s2 +anotherboard.build.mcu=esp32s2 +... +``` + ### Optimization level for debugging The compiler optimization level that is appropriate for normal usage will often not provide a good experience while diff --git a/internal/integrationtest/debug/debug_test.go b/internal/integrationtest/debug/debug_test.go index 8d3d972af8f..a01597468ec 100644 --- a/internal/integrationtest/debug/debug_test.go +++ b/internal/integrationtest/debug/debug_test.go @@ -272,5 +272,62 @@ func testAllDebugInformation(t *testing.T, env *integrationtest.Environment, cli }`) } + { + // Mixing programmer and additional_config + jsonDebugOut, _, err := cli.Run("debug", "-b", "my:samd:my3", "-P", "my_cold_ice", sketchPath.String(), "--info", "--format", "json") + require.NoError(t, err) + debugOut := requirejson.Parse(t, jsonDebugOut) + debugOut.MustContain(` + { + "toolchain": "gcc", + "toolchain_path": "gcc-path", + "toolchain_prefix": "gcc-prefix", + "server": "openocd", + "server_path": "openocd-path", + "server_configuration": { + "path": "openocd-path", + "scripts_dir": "openocd-scripts-dir", + "scripts": [ + "cold_ice_script" + ] + }, + "custom_configs": { + "cortex-debug": { + "test1": "true" + } + }, + "svd_file": "test1.svd", + "programmer": "my_cold_ice" + }`) + } + + { + // Mixing programmer and additional_config selected by another variable + jsonDebugOut, _, err := cli.Run("debug", "-b", "my:samd:my4", "-P", "my_cold_ice", sketchPath.String(), "--info", "--format", "json") + require.NoError(t, err) + debugOut := requirejson.Parse(t, jsonDebugOut) + debugOut.MustContain(` + { + "toolchain": "gcc", + "toolchain_path": "gcc-path", + "toolchain_prefix": "gcc-prefix", + "server": "openocd", + "server_path": "openocd-path", + "server_configuration": { + "path": "openocd-path", + "scripts_dir": "openocd-scripts-dir", + "scripts": [ + "cold_ice_script" + ] + }, + "custom_configs": { + "cortex-debug": { + "test2": "true" + } + }, + "svd_file": "test2.svd", + "programmer": "my_cold_ice" + }`) + } } } diff --git a/internal/integrationtest/debug/testdata/hardware/my/samd/boards.txt b/internal/integrationtest/debug/testdata/hardware/my/samd/boards.txt index 7a96eac3186..5512eb7e2b3 100644 --- a/internal/integrationtest/debug/testdata/hardware/my/samd/boards.txt +++ b/internal/integrationtest/debug/testdata/hardware/my/samd/boards.txt @@ -87,3 +87,28 @@ my2.debug.server.openocd.path=openocd-path my2.debug.server.openocd.scripts_dir=openocd-scripts-dir my2.debug.server.openocd.script=single-script my2.debug.svd_file=svd-file + +my3.name=My third Cool Board +my3.build.core=arduino:arduino +my3.build.variant=arduino:mkr1000 +my3.debug.toolchain.path=gcc-path +my3.debug.toolchain.prefix=gcc-prefix +my3.debug.server.openocd.path=openocd-path +my3.debug.server.openocd.scripts_dir=openocd-scripts-dir +my3.debug.server.openocd.script=single-script +# this one will be overwritten by additional_config +my3.debug.svd_file=svd-file +my3.debug.additional_config=build.debug.config.test1 + +my4.name=My fourth Cool Board +my4.build.core=arduino:arduino +my4.build.variant=arduino:mkr1000 +my4.debug.toolchain.path=gcc-path +my4.debug.toolchain.prefix=gcc-prefix +my4.debug.server.openocd.path=openocd-path +my4.debug.server.openocd.scripts_dir=openocd-scripts-dir +my4.debug.server.openocd.script=single-script +my4.build.mcu=test2 +# this one will be overwritten by additional_config +my4.debug.svd_file=svd-file +my4.debug.additional_config=build.debug.config.{build.mcu} diff --git a/internal/integrationtest/debug/testdata/hardware/my/samd/platform.txt b/internal/integrationtest/debug/testdata/hardware/my/samd/platform.txt new file mode 100644 index 00000000000..d2a61b9fd25 --- /dev/null +++ b/internal/integrationtest/debug/testdata/hardware/my/samd/platform.txt @@ -0,0 +1,5 @@ +build.debug.config.test1.svd_file=test1.svd +build.debug.config.test1.cortex-debug.custom.test1=true + +build.debug.config.test2.svd_file=test2.svd +build.debug.config.test2.cortex-debug.custom.test2=true