summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxengineering <me@xengineering.eu>2024-05-30 17:37:44 +0200
committerxengineering <me@xengineering.eu>2024-05-30 17:37:44 +0200
commit0f62b35cb1a1ff69e8c29285322a251010cf5ee1 (patch)
treed4f37b86a7c9d628b204d087fa47bd4a0c21fa2d
parent034c8209f6e6f17bf5b6f265e2a3ef58f05b2c80 (diff)
downloadiot-core-0f62b35cb1a1ff69e8c29285322a251010cf5ee1.tar
iot-core-0f62b35cb1a1ff69e8c29285322a251010cf5ee1.tar.zst
iot-core-0f62b35cb1a1ff69e8c29285322a251010cf5ee1.zip
software: communication: Use Go channels
Go channels help to decouple the communication layers defined by the OSI model [1]. The physical layer can be abstracted by an RX and TX byte channel and the data link layer by two frame channels. [1]: https://en.wikipedia.org/wiki/OSI_model
-rw-r--r--software/communication/interface.go33
-rw-r--r--software/communication/physical.go45
-rw-r--r--software/main.go5
3 files changed, 51 insertions, 32 deletions
diff --git a/software/communication/interface.go b/software/communication/interface.go
index 672617e..ebd8d6b 100644
--- a/software/communication/interface.go
+++ b/software/communication/interface.go
@@ -2,28 +2,17 @@ package communication
import (
"fmt"
-
- "go.bug.st/serial"
)
type SerialInterface struct {
- port serial.Port
+ phy physical
}
func NewSerialInterface() (SerialInterface, error) {
iface := SerialInterface{}
+ var err error
- devices, err := getStSerials()
- if err != nil {
- return iface, err
- }
-
- if len(devices) != 1 {
- return iface, fmt.Errorf("Require exactly one serial device from STMicroelectronics but %d attached", len(devices))
- }
- device := devices[0]
-
- iface.port, err = openSerial(device)
+ iface.phy, err = newPhysical()
if err != nil {
return iface, err
}
@@ -31,21 +20,9 @@ func NewSerialInterface() (SerialInterface, error) {
return iface, nil
}
-func (i *SerialInterface) Cat() error {
+func (i *SerialInterface) Cat() {
for {
- data, err := i.Read()
- if err != nil {
- return err
- }
+ data := <-i.phy.rx
fmt.Printf("%s", string(data))
}
}
-
-func (i *SerialInterface) Read() ([]byte, error) {
- buff := make([]byte, 100)
- n, err := i.port.Read(buff)
- if err != nil {
- return []byte{}, err
- }
- return buff[:n], nil
-}
diff --git a/software/communication/physical.go b/software/communication/physical.go
index 853e4c4..0ba3690 100644
--- a/software/communication/physical.go
+++ b/software/communication/physical.go
@@ -1,6 +1,9 @@
package communication
import (
+ "fmt"
+ "log"
+
"go.bug.st/serial"
"go.bug.st/serial/enumerator"
)
@@ -9,6 +12,35 @@ const (
ST_VID = `0483`
)
+type physical struct {
+ port serial.Port
+ rx chan byte
+}
+
+func newPhysical() (physical, error) {
+ p := physical{}
+
+ devices, err := getStSerials()
+ if err != nil {
+ return p, err
+ }
+
+ if len(devices) != 1 {
+ return p, fmt.Errorf("Require exactly one serial device from STMicroelectronics but %d attached", len(devices))
+ }
+ device := devices[0]
+
+ p.port, err = openSerial(device)
+ if err != nil {
+ return p, err
+ }
+
+ p.rx = make(chan byte)
+ go p.Receive()
+
+ return p, nil
+}
+
func getStSerials() ([]string, error) {
retval := make([]string, 0)
@@ -39,3 +71,16 @@ func openSerial(device string) (serial.Port, error) {
}
return port, nil
}
+
+func (p *physical) Receive() {
+ for {
+ buff := make([]byte, 100)
+ n, err := p.port.Read(buff)
+ if err != nil {
+ log.Fatal(err)
+ }
+ for i := 0; i < n; i++ {
+ p.rx <- buff[i]
+ }
+ }
+}
diff --git a/software/main.go b/software/main.go
index d0ca2cd..0a6b590 100644
--- a/software/main.go
+++ b/software/main.go
@@ -12,8 +12,5 @@ func main() {
log.Fatal(err)
}
- err = iface.Cat()
- if err != nil {
- log.Fatal(err)
- }
+ iface.Cat()
}