Skip to content

Commit

Permalink
non blocking reads through channel and goroutine
Browse files Browse the repository at this point in the history
  • Loading branch information
James Portman committed Dec 2, 2022
1 parent 55ea3db commit bed42f2
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 18 deletions.
28 changes: 10 additions & 18 deletions ecu-2j.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,8 @@ func readFirstBytesFromPortTwoj(fn string) ([]byte, error) {
fmt.Println("Serial cable set to:")
fmt.Println(mode)

go serialReadRoutine(sp)

sp.SetBreak(false)
time.Sleep(200 * time.Millisecond)

Expand All @@ -305,22 +307,10 @@ func readFirstBytesFromPortTwoj(fn string) ([]byte, error) {
readLoops := 0
readLoopsLimit := 200
for readLoops < readLoopsLimit {
readLoops++

// only read again if we don't have a full packet ready
// the reads are always blocking on linux even though they aren't in windows...
// TODO: move the serial reads and writes to their own go routines then it doesn't matter if it blocks
if len(buffer) <= 0 || len(buffer) < int(buffer[0])+2 {
rb := make([]byte, 256)
n, _ := sp.Read(rb[:])
rb = rb[0:n] // chop down to actual data size
buffer = append(buffer, rb...)

if n > 0 {
readLoops = 0 // reset timeout
// fmt.Print(hex.Dump(buffer))
}
}
// this timeout needs changing to time without an answer rather than number of loops
// readLoops++

buffer = append(buffer, nonBlockingSerialRead()...)

// clear leading zeros (from our wake up)
for len(buffer) > 0 && buffer[0] == 0x00 {
Expand All @@ -329,7 +319,8 @@ func readFirstBytesFromPortTwoj(fn string) ([]byte, error) {
}

if len(buffer) == 0 {
fmt.Println("buffer empty")
// fmt.Println("buffer empty")
time.Sleep(1 * time.Millisecond)
continue
}

Expand All @@ -347,7 +338,8 @@ func readFirstBytesFromPortTwoj(fn string) ([]byte, error) {
// TODO: check for implausible packet size

if len(buffer) < packetSize + 2 {
fmt.Println("waiting for rest of data packet")
// fmt.Println("waiting for rest of data packet")
time.Sleep(1 * time.Millisecond)
continue
}

Expand Down
3 changes: 3 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ var (
globalLogLines = []string{}

outgoingData chan string // for pushing data out of the websocket

serialReadChannel = make(chan byte, 1024)
// serialWriteChannel = make(chan byte, 1024)
)

func main() {
Expand Down
33 changes: 33 additions & 0 deletions serialReadWrite.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package main

import (
"github.com/distributed/sers"
)
// go routines for serial read
// mostly because reads erroneously block in Linux, even with a timeout set

func serialReadRoutine(sp sers.SerialPort) {
for {
rb := make([]byte, 256)
n, _ := sp.Read(rb[:])
rb = rb[0:n] // chop down to actual data size
for i := 0; i < n; i++ {
serialReadChannel <- rb[i]
}
}
}

// reads all currently available data from the channel
func nonBlockingSerialRead() ([]byte) {
buffer := make([]byte, 0)
outer:
for {
select {
case msg := <-serialReadChannel:
buffer = append(buffer, msg)
default:
break outer
}
}
return buffer
}

0 comments on commit bed42f2

Please sign in to comment.