diff --git a/compileopts/target.go b/compileopts/target.go index 2e989ac5..949f00e4 100644 --- a/compileopts/target.go +++ b/compileopts/target.go @@ -47,6 +47,7 @@ type TargetSpec struct { OpenOCDInterface string `json:"openocd-interface"` OpenOCDTarget string `json:"openocd-target"` OpenOCDTransport string `json:"openocd-transport"` + JLinkDevice string `json:"jlink-device"` } // copyProperties copies all properties that are set in spec2 into itself. @@ -122,6 +123,9 @@ func (spec *TargetSpec) copyProperties(spec2 *TargetSpec) { if spec2.OpenOCDTransport != "" { spec.OpenOCDTransport = spec2.OpenOCDTransport } + if spec2.JLinkDevice != "" { + spec.JLinkDevice = spec2.JLinkDevice + } } // load reads a target specification from the JSON in the given io.Reader. It diff --git a/main.go b/main.go index f9059d2d..f2df643c 100644 --- a/main.go +++ b/main.go @@ -288,12 +288,13 @@ func FlashGDB(pkgName string, ocdOutput bool, options *compileopts.Options) erro gdbInterface, openocdInterface := config.Programmer() switch gdbInterface { case "msd", "command", "": - if openocdInterface != "" && config.Target.OpenOCDTarget != "" { - gdbInterface = "openocd" - } if len(config.Target.Emulator) != 0 { // Assume QEMU as an emulator. gdbInterface = "qemu" + } else if openocdInterface != "" && config.Target.OpenOCDTarget != "" { + gdbInterface = "openocd" + } else if config.Target.JLinkDevice != "" { + gdbInterface = "jlink" } } @@ -331,6 +332,31 @@ func FlashGDB(pkgName string, ocdOutput bool, options *compileopts.Options) erro // Maybe we should send a .Kill() after x seconds? daemon.Wait() }() + case "jlink": + gdbCommands = append(gdbCommands, "target remote :2331", "load", "monitor reset halt") + + // We need a separate debugging daemon for on-chip debugging. + daemon := exec.Command("JLinkGDBServer", "-device", config.Target.JLinkDevice) + if ocdOutput { + // Make it clear which output is from the daemon. + w := &ColorWriter{ + Out: os.Stderr, + Prefix: "jlink: ", + Color: TermColorYellow, + } + daemon.Stdout = w + daemon.Stderr = w + } + // Make sure the daemon doesn't receive Ctrl-C that is intended for + // GDB (to break the currently executing program). + setCommandAsDaemon(daemon) + // Start now, and kill it on exit. + daemon.Start() + defer func() { + daemon.Process.Signal(os.Interrupt) + // Maybe we should send a .Kill() after x seconds? + daemon.Wait() + }() case "qemu": gdbCommands = append(gdbCommands, "target remote :1234")