From d3ab2fa4330dfa7b2b9d4427af7d72fac6bc21a2 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Sat, 14 Sep 2024 16:40:14 -0700 Subject: [PATCH] debugger: start of a debugger client that uses the serial debug gateware --- debugger/main.go | 105 +++++++++++++++++++++++++++++++++++++++++++++++ go.mod | 9 ++++ go.sum | 6 +++ 3 files changed, 120 insertions(+) create mode 100644 debugger/main.go create mode 100644 go.mod create mode 100644 go.sum diff --git a/debugger/main.go b/debugger/main.go new file mode 100644 index 0000000..d07ad86 --- /dev/null +++ b/debugger/main.go @@ -0,0 +1,105 @@ +package main + +import ( + "errors" + "fmt" + "log" + "sync" + "time" + + "go.bug.st/serial" +) + +const portDev = "/dev/ttyUSB0" + +func main() { + dbg, err := Open() + if err != nil { + log.Fatalf("connecting to debugger: %v", err) + } + defer dbg.Close() + + fmt.Println("Writing...") + if err := dbg.Write(0x42, 123); err != nil { + log.Fatalf("writing to memory: %v", err) + } + v, err := dbg.Read(0x42) + if err != nil { + log.Fatalf("reading from memory: %v", err) + } + fmt.Printf("addr 0: %02x\n", v) +} + +type Debugger struct { + port serial.Port + mu sync.Mutex +} + +func Open() (*Debugger, error) { + mode := &serial.Mode{ + BaudRate: 115_200, + } + port, err := serial.Open(portDev, mode) + if err != nil { + return nil, err + } + + return &Debugger{port: port}, nil +} + +func (d *Debugger) Close() error { + d.mu.Lock() // note, deliberately no unlocking, to poison. + return d.port.Close() +} + +func encode(addr int, write bool, data byte) [4]byte { + writeVal := uint8(0) + if write { + writeVal = 1 + } + var ret [4]byte + ret[3] = data + ret[2] = byte(addr<<1) | writeVal + ret[1] = byte(addr >> 7) + ret[0] = byte(addr >> 15) + return ret +} + +func (d *Debugger) Read(addr int) (byte, error) { + d.mu.Lock() + defer d.mu.Unlock() + if addr >= 2<<17 { + return 0, fmt.Errorf("read %d out of bounds", addr) + } + + packet := encode(addr, false, 0) + fmt.Printf("Writing: %02x %02x %02x %02x\n", packet[0], packet[1], packet[2], packet[3]) + if _, err := d.port.Write(packet[:]); err != nil { + return 0, err + } + + d.port.SetReadTimeout(2 * time.Second) + + n, err := d.port.Read(packet[:1]) + if err != nil { + return 0, err + } else if n == 0 { + return 0, errors.New("no read") + } + return packet[0], nil +} + +func (d *Debugger) Write(addr int, val byte) error { + d.mu.Lock() + defer d.mu.Unlock() + if addr >= 2<<17 { + return fmt.Errorf("write %d out of bounds", addr) + } + + packet := encode(addr, true, val) + fmt.Printf("Writing: %02x %02x %02x %02x\n", packet[0], packet[1], packet[2], packet[3]) + if _, err := d.port.Write(packet[:]); err != nil { + return err + } + return nil +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..222199f --- /dev/null +++ b/go.mod @@ -0,0 +1,9 @@ +module git.sentinel65x.com/dave/gary + +go 1.22.6 + +require ( + github.com/creack/goselect v0.1.2 // indirect + go.bug.st/serial v1.6.2 // indirect + golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..2f35f6f --- /dev/null +++ b/go.sum @@ -0,0 +1,6 @@ +github.com/creack/goselect v0.1.2 h1:2DNy14+JPjRBgPzAd1thbQp4BSIihxcBf0IXhQXDRa0= +github.com/creack/goselect v0.1.2/go.mod h1:a/NhLweNvqIYMuxcMOuWY516Cimucms3DglDzQP3hKY= +go.bug.st/serial v1.6.2 h1:kn9LRX3sdm+WxWKufMlIRndwGfPWsH1/9lCWXQCasq8= +go.bug.st/serial v1.6.2/go.mod h1:UABfsluHAiaNI+La2iESysd9Vetq7VRdpxvjx7CmmOE= +golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 h1:v6hYoSR9T5oet+pMXwUWkbiVqx/63mlHjefrHmxwfeY= +golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=