Skip to content

Commit

Permalink
Find ST-Link mount for serial port on Linux
Browse files Browse the repository at this point in the history
CL: mos: Find ST-Link mount for serial port on Linux

PUBLISHED_FROM=2225a5211c90137a53bd5fe7073d2c38068d59d9
  • Loading branch information
Deomid Ryabkov authored and cesantabot committed Nov 5, 2018
1 parent 07d42bc commit 0408166
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 51 deletions.
19 changes: 13 additions & 6 deletions mos/flash.go
Expand Up @@ -18,6 +18,7 @@ import (
espFlasher "cesanta.com/mos/flash/esp/flasher"
"cesanta.com/mos/flash/stm32"
"github.com/cesanta/errors"
"github.com/golang/glog"
flag "github.com/spf13/pflag"
)

Expand Down Expand Up @@ -135,14 +136,20 @@ func flash(ctx context.Context, devConn *dev.DevConn) error {
// But for now, we'll just find mountpoints that sort of look like STLink...
port = *portFlag
if port == "auto" || (strings.HasPrefix(port, "/dev/") || strings.HasPrefix(port, "COM")) {
mm, err := stm32.FindSTLinkMounts()
port, err = stm32.GetSTLinkMountForPort(port)
if err != nil {
return errors.Trace(err)
glog.Infof("Did not find port corresponding to %s: %s", *portFlag, err)
mm, err := stm32.GetSTLinkMounts()
if err != nil {
return errors.Trace(err)
}
if len(mm) == 0 {
return errors.Errorf("No STM32 devices found")
}
port = mm[0]
} else {
glog.Infof("%s -> %s", *portFlag, port)
}
if len(mm) == 0 {
return errors.Errorf("No STM32 devices found")
}
port = mm[0]
}
stm32FlashOpts.ShareName = port
err = stm32.Flash(fw, &stm32FlashOpts)
Expand Down
21 changes: 21 additions & 0 deletions mos/flash/stm32/flasher-share.go
Expand Up @@ -4,8 +4,10 @@ import (
"io/ioutil"
"os"
"path/filepath"
"strings"
"time"

"cesanta.com/common/go/ourutil"
"cesanta.com/mos/flash/common"
"github.com/cesanta/errors"
"github.com/golang/glog"
Expand All @@ -15,6 +17,25 @@ var (
stlinkDevPrefixes = []string{"DIS_", "NODE_"}
)

func getSTLinkMountsInDir(dir string) ([]string, error) {
glog.V(1).Infof("Looking for ST-Link devices under %q", dir)
ee, err := ioutil.ReadDir(dir)
if err != nil {
return nil, errors.Annotatef(err, "failed to list %q", dir)
}
var res []string
for _, e := range ee {
for _, p := range stlinkDevPrefixes {
if strings.HasPrefix(e.Name(), p) {
n := filepath.Join(dir, e.Name())
ourutil.Reportf("Found STLink mount: %s", n)
res = append(res, n)
}
}
}
return res, nil
}

type FlashOpts struct {
ShareName string
Timeout time.Duration
Expand Down
10 changes: 10 additions & 0 deletions mos/flash/stm32/flasher_darwin.go
@@ -0,0 +1,10 @@
package stm32

func GetSTLinkMountForPort(port string) (string, error) {
// TODO(rojer)
return "", errors.NotImplementedf("GetSTLinkMountForPort")
}

func GetSTLinkMounts() ([]string, error) {
return getSTLinkMountsInDir("/Volumes")
}
63 changes: 63 additions & 0 deletions mos/flash/stm32/flasher_linux.go
@@ -0,0 +1,63 @@
package stm32

import (
"bufio"
"os"
"path/filepath"
"strings"

"github.com/cesanta/errors"
"github.com/golang/glog"
)

func GetSTLinkMountForPort(port string) (string, error) {
port, _ = filepath.EvalSymlinks(port)
// Find the USB device directory corresponding to the TTY device.
usbDevDir := ""
ports, _ := filepath.Glob("/sys/bus/usb/devices/*/*/tty/*")
for _, p := range ports {
// /sys/bus/usb/devices/NNN/NNN:1.2/tty/ttyACMx (CDC is interface 1, endpoint 2).
if filepath.Base(p) == filepath.Base(port) {
dd1, _ := filepath.Split(p)
dd2, _ := filepath.Split(filepath.Clean(dd1))
dd3, _ := filepath.Split(filepath.Clean(dd2))
usbDevDir = filepath.Clean(dd3) // /sys/bus/usb/devices/NNN
glog.V(1).Infof("%s -> %s -> %s", port, p, usbDevDir)
}
}
if usbDevDir == "" {
return "", errors.Errorf("no USB device found for %s", port)
}
// Find the block device name associated with this USB device.
// Expand /sys/bus/usb/devices/NNN/*/*/*/*/block, it will contain the list of devices (only one).
blockDevs, _ := filepath.Glob(filepath.Join(usbDevDir, "*", "*", "*", "*", "block", "*"))
if len(blockDevs) == 0 {
return "", errors.Errorf("no block device found for %s", port)
}
dev := filepath.Join("/dev", filepath.Base(blockDevs[0]))
// Now find mount point for this device.

glog.V(1).Infof("%s -> %s", port, dev)
f, err := os.Open("/proc/mounts")
if err != nil {
return "", errors.Annotatef(err, "failed to open list of mounts")
}
defer f.Close()
mp := ""
sc := bufio.NewScanner(f)
for sc.Scan() {
parts := strings.Split(sc.Text(), " ")
if parts[0] == dev {
mp = parts[1]
break
}
}
if mp == "" {
return "", errors.Errorf("%s is not mounted", dev)
}
return mp, nil
}

func GetSTLinkMounts() ([]string, error) {
return getSTLinkMountsInDir(filepath.Join("/", "media", os.Getenv("USER")))
}
43 changes: 0 additions & 43 deletions mos/flash/stm32/flasher_posix.go

This file was deleted.

10 changes: 8 additions & 2 deletions mos/flash/stm32/flasher_windows.go
Expand Up @@ -16,8 +16,9 @@ import (
"golang.org/x/sys/windows"
)

// Enumerate drives and find ones that have name start with one of the known prefixes.
func FindSTLinkMounts() ([]string, error) {
// GetSTLinkMounts enumerated drives and finds ones that have
// a name starting with one of the known prefixes.
func GetSTLinkMounts() ([]string, error) {
drivesBitMask, err := windows.GetLogicalDrives()
if err != nil {
return nil, errors.Annotatef(err, "GetLogicalDrives")
Expand Down Expand Up @@ -63,3 +64,8 @@ func getDriveInfo(drive string) (string, string, uint32, error) {

return syscall.UTF16ToString(volName), syscall.UTF16ToString(fsName), volSerial, nil
}

func GetSTLinkMountForPort(port string) (string, error) {
// TODO(rojer)
return "", errors.NotImplementedf("GetSTLinkMountForPort")
}

0 comments on commit 0408166

Please sign in to comment.