Skip to content

Commit 24ae6fd

Browse files
sago35deadprogram
authored andcommitted
main: add -info option to tinygo monitor
1 parent 938ce22 commit 24ae6fd

File tree

2 files changed

+111
-29
lines changed

2 files changed

+111
-29
lines changed

main.go

Lines changed: 18 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1436,6 +1436,7 @@ func main() {
14361436
llvmFeatures := flag.String("llvm-features", "", "comma separated LLVM features to enable")
14371437
cpuprofile := flag.String("cpuprofile", "", "cpuprofile output")
14381438
monitor := flag.Bool("monitor", false, "enable serial monitor")
1439+
info := flag.Bool("info", false, "print information")
14391440
baudrate := flag.Int("baudrate", 115200, "baudrate of serial monitor")
14401441

14411442
// Internal flags, that are only intended for TinyGo development.
@@ -1731,41 +1732,29 @@ func main() {
17311732
os.Exit(1)
17321733
}
17331734
case "monitor":
1734-
err := Monitor("", *port, options)
1735-
handleCompilerError(err)
1735+
if *info {
1736+
serialPortInfo, err := ListSerialPorts()
1737+
handleCompilerError(err)
1738+
for _, s := range serialPortInfo {
1739+
fmt.Printf("%s %4s %4s %s\n", s.Name, s.VID, s.PID, s.Target)
1740+
}
1741+
} else {
1742+
err := Monitor("", *port, options)
1743+
handleCompilerError(err)
1744+
}
17361745
case "targets":
1737-
dir := filepath.Join(goenv.Get("TINYGOROOT"), "targets")
1738-
entries, err := os.ReadDir(dir)
1746+
specs, err := GetTargetSpecs()
17391747
if err != nil {
17401748
fmt.Fprintln(os.Stderr, "could not list targets:", err)
17411749
os.Exit(1)
17421750
return
17431751
}
1744-
for _, entry := range entries {
1745-
entryInfo, err := entry.Info()
1746-
if err != nil {
1747-
fmt.Fprintln(os.Stderr, "could not get entry info:", err)
1748-
os.Exit(1)
1749-
return
1750-
}
1751-
if !entryInfo.Mode().IsRegular() || !strings.HasSuffix(entry.Name(), ".json") {
1752-
// Only inspect JSON files.
1753-
continue
1754-
}
1755-
path := filepath.Join(dir, entry.Name())
1756-
spec, err := compileopts.LoadTarget(&compileopts.Options{Target: path})
1757-
if err != nil {
1758-
fmt.Fprintln(os.Stderr, "could not list target:", err)
1759-
os.Exit(1)
1760-
return
1761-
}
1762-
if spec.FlashMethod == "" && spec.FlashCommand == "" && spec.Emulator == "" {
1763-
// This doesn't look like a regular target file, but rather like
1764-
// a parent target (such as targets/cortex-m.json).
1765-
continue
1766-
}
1767-
name := entry.Name()
1768-
name = name[:len(name)-5]
1752+
names := []string{}
1753+
for key := range specs {
1754+
names = append(names, key)
1755+
}
1756+
sort.Strings(names)
1757+
for _, name := range names {
17691758
fmt.Println(name)
17701759
}
17711760
case "info":

monitor.go

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,19 @@ import (
1111
"io"
1212
"os"
1313
"os/signal"
14+
"path/filepath"
1415
"regexp"
1516
"strconv"
17+
"strings"
1618
"time"
1719

1820
"github.com/mattn/go-tty"
1921
"github.com/tinygo-org/tinygo/builder"
2022
"github.com/tinygo-org/tinygo/compileopts"
23+
"github.com/tinygo-org/tinygo/goenv"
24+
2125
"go.bug.st/serial"
26+
"go.bug.st/serial/enumerator"
2227
)
2328

2429
// 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 {
128133
return <-errCh
129134
}
130135

136+
// SerialPortInfo is a structure that holds information about the port and its
137+
// associated TargetSpec.
138+
type SerialPortInfo struct {
139+
Name string
140+
IsUSB bool
141+
VID string
142+
PID string
143+
Target string
144+
Spec *compileopts.TargetSpec
145+
}
146+
147+
// ListSerialPort returns serial port information and any detected TinyGo
148+
// target
149+
func ListSerialPorts() ([]SerialPortInfo, error) {
150+
maps, err := GetTargetSpecs()
151+
if err != nil {
152+
return nil, err
153+
}
154+
155+
portsList, err := enumerator.GetDetailedPortsList()
156+
if err != nil {
157+
return nil, err
158+
}
159+
160+
serialPortInfo := []SerialPortInfo{}
161+
for _, p := range portsList {
162+
info := SerialPortInfo{
163+
Name: p.Name,
164+
IsUSB: p.IsUSB,
165+
VID: p.VID,
166+
PID: p.PID,
167+
}
168+
vid := strings.ToLower(p.VID)
169+
pid := strings.ToLower(p.PID)
170+
for k, v := range maps {
171+
usbInterfaces := v.SerialPort
172+
for _, s := range usbInterfaces {
173+
parts := strings.Split(s, ":")
174+
if len(parts) != 2 {
175+
continue
176+
}
177+
if vid == strings.ToLower(parts[0]) && pid == strings.ToLower(parts[1]) {
178+
info.Target = k
179+
info.Spec = v
180+
}
181+
}
182+
}
183+
serialPortInfo = append(serialPortInfo, info)
184+
}
185+
186+
return serialPortInfo, nil
187+
}
188+
189+
func GetTargetSpecs() (map[string]*compileopts.TargetSpec, error) {
190+
dir := filepath.Join(goenv.Get("TINYGOROOT"), "targets")
191+
entries, err := os.ReadDir(dir)
192+
if err != nil {
193+
return nil, fmt.Errorf("could not list targets: %w", err)
194+
}
195+
196+
maps := map[string]*compileopts.TargetSpec{}
197+
for _, entry := range entries {
198+
entryInfo, err := entry.Info()
199+
if err != nil {
200+
return nil, fmt.Errorf("could not get entry info: %w", err)
201+
}
202+
if !entryInfo.Mode().IsRegular() || !strings.HasSuffix(entry.Name(), ".json") {
203+
// Only inspect JSON files.
204+
continue
205+
}
206+
path := filepath.Join(dir, entry.Name())
207+
spec, err := compileopts.LoadTarget(&compileopts.Options{Target: path})
208+
if err != nil {
209+
return nil, fmt.Errorf("cnuld not list target: %w", err)
210+
}
211+
if spec.FlashMethod == "" && spec.FlashCommand == "" && spec.Emulator == "" {
212+
// This doesn't look like a regular target file, but rather like
213+
// a parent target (such as targets/cortex-m.json).
214+
continue
215+
}
216+
name := entry.Name()
217+
name = name[:len(name)-5]
218+
//fmt.Println(name)
219+
maps[name] = spec
220+
}
221+
return maps, nil
222+
}
223+
131224
var addressMatch = regexp.MustCompile(`^panic: runtime error at 0x([0-9a-f]+): `)
132225

133226
// Extract the address from the "panic: runtime error at" message.

0 commit comments

Comments
 (0)