Skip to content

Instantly share code, notes, and snippets.

@cryptix
Created August 18, 2014 22:11
Show Gist options
  • Save cryptix/575bfe907c6dd141949e to your computer and use it in GitHub Desktop.
Save cryptix/575bfe907c6dd141949e to your computer and use it in GitHub Desktop.
subprocess as a connection
package main
import (
"bufio"
"flag"
"fmt"
"io"
"log"
"os"
"path/filepath"
"github.com/tarm/goserial"
. "bachelorDB"
. "utils"
)
var (
local = flag.Bool("local", false, "toggle local process or serial connection")
readTestPath = filepath.Join("/", "home", "cryptix", "proj", "uBlaze", "coeffControll", "coeffControll")
)
func main() {
var (
err error
conn io.ReadWriteCloser
)
flag.Parse()
if flag.NArg() != 1 {
fmt.Fprintln(os.Stderr, "Usage: coeffsSender (-local) <name>")
os.Exit(1)
}
InitDb("192.168.0.10", "filters")
fname := flag.Args()[0]
fir, err := GetCoeffsByName(fname)
Check(err)
log.Println("Coeffs loaded:", fname)
if *local {
conn, err = StartStdioProcess(readTestPath)
Check(err)
} else {
serconf := serial.Config{Name: "/dev/cu.SLAB_USBtoUART", Baud: 115200}
conn, err = serial.OpenPort(&serconf)
Check(err)
}
defer conn.Close()
log.Printf("Using serial connection: %v", !*local)
// sender channel
coeffs := make(chan int)
go func() {
for coeff := range coeffs {
log.Printf(">[%d]\n", coeff)
_, err = fmt.Fprintf(conn, "%7d\n", coeff)
Check(err)
}
}()
// advancer channel
next := make(chan bool)
go func() {
scanner := bufio.NewScanner(conn)
for scanner.Scan() {
line := scanner.Text()
log.Println("<", line)
next <- true
}
Check(scanner.Err())
}()
// begin
_, err = fmt.Fprintln(conn, "STRT")
Check(err)
<-next
log.Println("STRT send")
// send
for _, coeff := range fir.Vals {
coeffs <- coeff
<-next
}
close(coeffs)
_, err = fmt.Fprintln(conn, "STOP")
Check(err)
<-next
log.Println("Done")
}
package main
import (
"io"
"os/exec"
)
type StdioConn struct {
Out io.ReadCloser
In io.WriteCloser
}
func (s StdioConn) Close() (err error) {
if err = s.In.Close(); err != nil {
return err
}
if err = s.Out.Close(); err != nil {
return err
}
return nil
}
func (s *StdioConn) Read(p []byte) (n int, err error) {
n, err = s.Out.Read(p)
// log.Printf("read[%d] bytes '%s'", n, string(p))
return
}
func (s *StdioConn) Write(p []byte) (n int, err error) {
n, err = s.In.Write(p)
// log.Printf("wrote[%d] '%s'", n, string(p))
return
}
func StartStdioProcess(path string) (*StdioConn, error) {
var (
err error
cmd = exec.Command(path)
conn StdioConn
)
// works too but havn't tested the difference much yet
// conn.Out, cmd.Stdout = io.Pipe()
// cmd.Stdin, conn.In = io.Pipe()
conn.Out, err = cmd.StdoutPipe()
if err != nil {
return nil, err
}
conn.In, err = cmd.StdinPipe()
if err != nil {
return nil, err
}
if err = cmd.Start(); err != nil {
return nil, err
}
go cmd.Wait()
return &conn, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment