diff options
author | sago35 <[email protected]> | 2023-10-30 19:00:54 +0900 |
---|---|---|
committer | Ron Evans <[email protected]> | 2023-11-02 15:37:43 +0100 |
commit | 24ae6fdf293502f032ed8cec857515b356b32b4a (patch) | |
tree | a3162a8b79cb316b984a508eb5b087ed7e7d7ed5 /monitor.go | |
parent | 938ce22307194504431d91d162608c47e4b4ffd3 (diff) | |
download | tinygo-24ae6fdf293502f032ed8cec857515b356b32b4a.tar.gz tinygo-24ae6fdf293502f032ed8cec857515b356b32b4a.zip |
main: add -info option to tinygo monitor
Diffstat (limited to 'monitor.go')
-rw-r--r-- | monitor.go | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/monitor.go b/monitor.go index 9bef531f9..23846b352 100644 --- a/monitor.go +++ b/monitor.go @@ -11,14 +11,19 @@ import ( "io" "os" "os/signal" + "path/filepath" "regexp" "strconv" + "strings" "time" "github.com/mattn/go-tty" "github.com/tinygo-org/tinygo/builder" "github.com/tinygo-org/tinygo/compileopts" + "github.com/tinygo-org/tinygo/goenv" + "go.bug.st/serial" + "go.bug.st/serial/enumerator" ) // Monitor connects to the given port and reads/writes the serial port. @@ -128,6 +133,94 @@ func Monitor(executable, port string, options *compileopts.Options) error { return <-errCh } +// SerialPortInfo is a structure that holds information about the port and its +// associated TargetSpec. +type SerialPortInfo struct { + Name string + IsUSB bool + VID string + PID string + Target string + Spec *compileopts.TargetSpec +} + +// ListSerialPort returns serial port information and any detected TinyGo +// target +func ListSerialPorts() ([]SerialPortInfo, error) { + maps, err := GetTargetSpecs() + if err != nil { + return nil, err + } + + portsList, err := enumerator.GetDetailedPortsList() + if err != nil { + return nil, err + } + + serialPortInfo := []SerialPortInfo{} + for _, p := range portsList { + info := SerialPortInfo{ + Name: p.Name, + IsUSB: p.IsUSB, + VID: p.VID, + PID: p.PID, + } + vid := strings.ToLower(p.VID) + pid := strings.ToLower(p.PID) + for k, v := range maps { + usbInterfaces := v.SerialPort + for _, s := range usbInterfaces { + parts := strings.Split(s, ":") + if len(parts) != 2 { + continue + } + if vid == strings.ToLower(parts[0]) && pid == strings.ToLower(parts[1]) { + info.Target = k + info.Spec = v + } + } + } + serialPortInfo = append(serialPortInfo, info) + } + + return serialPortInfo, nil +} + +func GetTargetSpecs() (map[string]*compileopts.TargetSpec, error) { + dir := filepath.Join(goenv.Get("TINYGOROOT"), "targets") + entries, err := os.ReadDir(dir) + if err != nil { + return nil, fmt.Errorf("could not list targets: %w", err) + } + + maps := map[string]*compileopts.TargetSpec{} + for _, entry := range entries { + entryInfo, err := entry.Info() + if err != nil { + return nil, fmt.Errorf("could not get entry info: %w", err) + } + if !entryInfo.Mode().IsRegular() || !strings.HasSuffix(entry.Name(), ".json") { + // Only inspect JSON files. + continue + } + path := filepath.Join(dir, entry.Name()) + spec, err := compileopts.LoadTarget(&compileopts.Options{Target: path}) + if err != nil { + return nil, fmt.Errorf("cnuld not list target: %w", err) + } + if spec.FlashMethod == "" && spec.FlashCommand == "" && spec.Emulator == "" { + // This doesn't look like a regular target file, but rather like + // a parent target (such as targets/cortex-m.json). + continue + } + name := entry.Name() + name = name[:len(name)-5] + //fmt.Println(name) + maps[name] = spec + } + return maps, nil +} + var addressMatch = regexp.MustCompile(`^panic: runtime error at 0x([0-9a-f]+): `) // Extract the address from the "panic: runtime error at" message. |