From d2d78d3d0a4d2a96caf1cb85ad5bc1387d9cbc58 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Tue, 12 Nov 2019 11:40:16 +0100 Subject: [PATCH] main: add -programmer flag This flag is overloaded. It can be used in two ways: * Choosing the flash method to use (openocd, msd, command). * Choosing the OpenOCD programmer name. For example, you can use one of these to use OpenOCD instead of the mass-storage device programmer: tinygo flash -target=microbit -programmer=openocd tinygo flash -target=microbit -programmer=cmsis-dap --- compileopts/config.go | 48 ++++++++++++++++++++++++++++++++++++++++++ compileopts/options.go | 1 + compileopts/target.go | 29 ------------------------- main.go | 19 ++++++++++------- 4 files changed, 60 insertions(+), 37 deletions(-) diff --git a/compileopts/config.go b/compileopts/config.go index 47c63b64..240f14c9 100644 --- a/compileopts/config.go +++ b/compileopts/config.go @@ -3,7 +3,9 @@ package compileopts import ( + "errors" "fmt" + "regexp" "strconv" "strings" @@ -152,6 +154,52 @@ func (c *Config) Debug() bool { return c.Options.Debug } +// Programmer returns the flash method and OpenOCD interface name given a +// particular configuration. It may either be all configured in the target JSON +// file or be modified using the -programmmer command-line option. +func (c *Config) Programmer() (method, openocdInterface string) { + switch c.Options.Programmer { + case "": + // No configuration supplied. + return c.Target.FlashMethod, c.Target.OpenOCDInterface + case "openocd", "msd", "command": + // The -programmer flag only specifies the flash method. + return c.Options.Programmer, c.Target.OpenOCDInterface + default: + // The -programmer flag specifies something else, assume it specifies + // the OpenOCD interface name. + return "openocd", c.Options.Programmer + } +} + +// OpenOCDConfiguration returns a list of command line arguments to OpenOCD. +// This list of command-line arguments is based on the various OpenOCD-related +// flags in the target specification. +func (c *Config) OpenOCDConfiguration() (args []string, err error) { + _, openocdInterface := c.Programmer() + if openocdInterface == "" { + return nil, errors.New("OpenOCD programmer not set") + } + if !regexp.MustCompile("^[\\p{L}0-9_-]+$").MatchString(openocdInterface) { + return nil, fmt.Errorf("OpenOCD programmer has an invalid name: %#v", openocdInterface) + } + if c.Target.OpenOCDTarget == "" { + return nil, errors.New("OpenOCD chip not set") + } + if !regexp.MustCompile("^[\\p{L}0-9_-]+$").MatchString(c.Target.OpenOCDTarget) { + return nil, fmt.Errorf("OpenOCD target has an invalid name: %#v", c.Target.OpenOCDTarget) + } + if c.Target.OpenOCDTransport != "" && c.Target.OpenOCDTransport != "swd" { + return nil, fmt.Errorf("unknown OpenOCD transport: %#v", c.Target.OpenOCDTransport) + } + args = []string{"-f", "interface/" + openocdInterface + ".cfg"} + if c.Target.OpenOCDTransport != "" { + args = append(args, "-c", "transport select "+c.Target.OpenOCDTransport) + } + args = append(args, "-f", "target/"+c.Target.OpenOCDTarget+".cfg") + return args, nil +} + type TestConfig struct { CompileTestBinary bool // TODO: Filter the test functions to run, include verbose flag, etc diff --git a/compileopts/options.go b/compileopts/options.go index 891f2172..7336ee3f 100644 --- a/compileopts/options.go +++ b/compileopts/options.go @@ -19,4 +19,5 @@ type Options struct { WasmAbi string HeapSize int64 TestConfig TestConfig + Programmer string } diff --git a/compileopts/target.go b/compileopts/target.go index ca36aaea..3bc05da4 100644 --- a/compileopts/target.go +++ b/compileopts/target.go @@ -5,11 +5,9 @@ package compileopts import ( "encoding/json" "errors" - "fmt" "io" "os" "path/filepath" - "regexp" "runtime" "strings" @@ -277,30 +275,3 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) { } return &spec, nil } - -// OpenOCDConfiguration returns a list of command line arguments to OpenOCD. -// This list of command-line arguments is based on the various OpenOCD-related -// flags in the target specification. -func (spec *TargetSpec) OpenOCDConfiguration() (args []string, err error) { - if spec.OpenOCDInterface == "" { - return nil, errors.New("OpenOCD programmer not set") - } - if !regexp.MustCompile("^[\\p{L}0-9_-]+$").MatchString(spec.OpenOCDInterface) { - return nil, fmt.Errorf("OpenOCD programmer has an invalid name: %#v", spec.OpenOCDInterface) - } - if spec.OpenOCDTarget == "" { - return nil, errors.New("OpenOCD chip not set") - } - if !regexp.MustCompile("^[\\p{L}0-9_-]+$").MatchString(spec.OpenOCDTarget) { - return nil, fmt.Errorf("OpenOCD target has an invalid name: %#v", spec.OpenOCDTarget) - } - if spec.OpenOCDTransport != "" && spec.OpenOCDTransport != "swd" { - return nil, fmt.Errorf("unknown OpenOCD transport: %#v", spec.OpenOCDTransport) - } - args = []string{"-f", "interface/" + spec.OpenOCDInterface + ".cfg"} - if spec.OpenOCDTransport != "" { - args = append(args, "-c", "transport select "+spec.OpenOCDTransport) - } - args = append(args, "-f", "target/"+spec.OpenOCDTarget+".cfg") - return args, nil -} diff --git a/main.go b/main.go index 44e8b5a8..0cf05183 100644 --- a/main.go +++ b/main.go @@ -151,7 +151,8 @@ func Flash(pkgName, port string, options *compileopts.Options) error { // determine the type of file to compile var fileExt string - switch config.Target.FlashMethod { + flashMethod, _ := config.Programmer() + switch flashMethod { case "command", "": switch { case strings.Contains(config.Target.FlashCommand, "{hex}"): @@ -175,7 +176,7 @@ func Flash(pkgName, port string, options *compileopts.Options) error { case "native": return errors.New("unknown flash method \"native\" - did you miss a -target flag?") default: - return errors.New("unknown flash method: " + config.Target.FlashMethod) + return errors.New("unknown flash method: " + flashMethod) } return builder.Build(pkgName, fileExt, config, func(tmppath string) error { @@ -190,7 +191,7 @@ func Flash(pkgName, port string, options *compileopts.Options) error { } // this flashing method copies the binary data to a Mass Storage Device (msd) - switch config.Target.FlashMethod { + switch flashMethod { case "", "command": // Create the command. flashCmd := config.Target.FlashCommand @@ -226,7 +227,7 @@ func Flash(pkgName, port string, options *compileopts.Options) error { return errors.New("mass storage device flashing currently only supports uf2 and hex") } case "openocd": - args, err := config.Target.OpenOCDConfiguration() + args, err := config.OpenOCDConfiguration() if err != nil { return err } @@ -240,7 +241,7 @@ func Flash(pkgName, port string, options *compileopts.Options) error { } return nil default: - return fmt.Errorf("unknown flash method: %s", config.Target.FlashMethod) + return fmt.Errorf("unknown flash method: %s", flashMethod) } }) } @@ -263,13 +264,13 @@ func FlashGDB(pkgName, port string, ocdOutput bool, options *compileopts.Options return builder.Build(pkgName, "", config, func(tmppath string) error { // Find a good way to run GDB. - gdbInterface := config.Target.FlashMethod + gdbInterface, openocdInterface := config.Programmer() switch gdbInterface { case "msd", "command", "": if gdbInterface == "" { gdbInterface = "command" } - if config.Target.OpenOCDInterface != "" && config.Target.OpenOCDTarget != "" { + if openocdInterface != "" && config.Target.OpenOCDTarget != "" { gdbInterface = "openocd" } } @@ -283,7 +284,7 @@ func FlashGDB(pkgName, port string, ocdOutput bool, options *compileopts.Options gdbCommands = append(gdbCommands, "target remote :3333", "monitor halt", "load", "monitor reset halt") // We need a separate debugging daemon for on-chip debugging. - args, err := config.Target.OpenOCDConfiguration() + args, err := config.OpenOCDConfiguration() if err != nil { return err } @@ -515,6 +516,7 @@ func main() { nodebug := flag.Bool("no-debug", false, "disable DWARF debug symbol generation") ocdOutput := flag.Bool("ocd-output", false, "print OCD daemon output during debug") port := flag.String("port", "/dev/ttyACM0", "flash port") + programmer := flag.String("programmer", "", "which hardware programmer to use") cFlags := flag.String("cflags", "", "additional cflags for compiler") ldFlags := flag.String("ldflags", "", "additional ldflags for linker") wasmAbi := flag.String("wasm-abi", "js", "WebAssembly ABI conventions: js (no i64 params) or generic") @@ -541,6 +543,7 @@ func main() { PrintSizes: *printSize, Tags: *tags, WasmAbi: *wasmAbi, + Programmer: *programmer, } if *cFlags != "" {