Compare commits

...

11 Commits

  1. 245
      admin/main.go
  2. 30
      admin/prepare.sh
  3. 170
      admin/tbm.go
  4. 45
      protocol/main.go
  5. 30
      protocol/tbm.go

@ -0,0 +1,245 @@
package main
import (
"flag"
"fmt"
"log"
"os"
"strconv"
"time"
)
type CommandFunc func(tbm *TBM, args []string) error
var (
serial_device = flag.String("serial-device", "/dev/ttyUSB0", "Serial device to use")
serial_baudrate = flag.Int("serial-baud", 9600, "Serial baud rate")
commands = map[string]CommandFunc{
"echo": cmd_echo,
"jtag": cmd_jtag,
"buzzer": cmd_buzzer,
"led": cmd_led,
"reset": cmd_reset,
"flash_probe": cmd_flash_probe,
"flash_release": cmd_flash_release,
"flash_info": cmd_flash_info,
"flash_read": cmd_flash_read,
"flash_erase": cmd_flash_erase,
"ftl_probe": cmd_ftl_probe,
"date": cmd_date,
"time": cmd_time,
"set-date": cmd_set_date,
"set-time": cmd_set_time,
"sync-time" : cmd_sync_time,
"mount": cmd_mount,
"umount": cmd_umount,
"format": cmd_format,
"mkdir": cmd_mkdir,
"rmdir": cmd_rmdir,
"ls": cmd_ls,
"stat": cmd_stat,
"cat": cmd_cat,
"write": cmd_write,
"append": cmd_append,
"mv": cmd_mv,
"cp": cmd_cp,
"rm": cmd_rm,
}
)
func cmd_generic(tbm *TBM, command string, args []string, payload []byte) error {
cmd := &Command{command, args, payload}
tbm.Commands <- cmd
res := <-tbm.Results
if res.errcode[0] != '0' {
return fmt.Errorf("Error: %s", res.errcode)
}
fmt.Printf("%s", res.output)
return nil
}
func cmd_echo(tbm *TBM, args []string) error {
return cmd_generic(tbm, "echo", args, nil);
}
func cmd_jtag(tbm *TBM, args []string) error {
return cmd_generic(tbm, "jtag", args, nil)
}
func cmd_buzzer(tbm *TBM, args []string) error {
return cmd_generic(tbm, "buzzer", args, nil)
}
func cmd_led(tbm *TBM, args []string) error {
return cmd_generic(tbm, "led", args, nil)
}
func cmd_reset(tbm *TBM, args []string) error {
return cmd_generic(tbm, "reset", args, nil)
}
func cmd_flash_probe(tbm *TBM, args []string) error {
return cmd_generic(tbm, "flash_probe", args, nil)
}
func cmd_flash_release(tbm *TBM, args []string) error {
return cmd_generic(tbm, "flash_release", args, nil)
}
func cmd_flash_info(tbm *TBM, args []string) error {
return cmd_generic(tbm, "flash_info", args, nil)
}
func cmd_flash_read(tbm *TBM, args []string) error {
return cmd_generic(tbm, "flash_read", args, nil)
}
func cmd_flash_erase(tbm *TBM, args []string) error {
return cmd_generic(tbm, "flash_erase", args, nil)
}
func cmd_ftl_probe(tbm *TBM, args []string) error {
return cmd_generic(tbm, "ftl_probe", args, nil)
}
func cmd_date(tbm *TBM, args []string) error {
return cmd_generic(tbm, "date", args, nil)
}
func cmd_time(tbm *TBM, args []string) error {
return cmd_generic(tbm, "time", args, nil)
}
func cmd_set_date(tbm *TBM, args []string) error {
return cmd_generic(tbm, "set_date", args, nil)
}
func cmd_set_time(tbm *TBM, args []string) error {
return cmd_generic(tbm, "set_time", args, nil)
}
func cmd_sync_time(tbm *TBM, args []string) error {
return cmd_generic(tbm, "set_time", []string{strconv.FormatInt(
time.Now().Unix(), 10)}, nil)
}
func cmd_mount(tbm *TBM, args []string) error {
return cmd_generic(tbm, "mount", args, nil)
}
func cmd_umount(tbm *TBM, args []string) error {
return cmd_generic(tbm, "umount", args, nil)
}
func cmd_format(tbm *TBM, args []string) error {
return cmd_generic(tbm, "format", args, nil)
}
func cmd_mkdir(tbm *TBM, args []string) error {
return cmd_generic(tbm, "mkdir", args, nil)
}
func cmd_rmdir(tbm *TBM, args []string) error {
return cmd_generic(tbm, "rmdir", args, nil)
}
func cmd_ls(tbm *TBM, args []string) error {
return cmd_generic(tbm, "ls", args, nil)
}
func cmd_stat(tbm *TBM, args []string) error {
return cmd_generic(tbm, "stat", args, nil)
}
func cmd_cat(tbm *TBM, args []string) error {
return cmd_generic(tbm, "cat", args, nil)
}
func cmd_write(tbm *TBM, args []string) error {
f, _ := os.Open(args[0])
defer f.Close()
buf := make([]byte, 256)
n, err := f.Read(buf)
if n == 0 {
return err
}
cmd_generic(tbm, "write", []string{args[1]}, buf)
for {
n, err = f.Read(buf)
if n == 0 {
return err
}
cmd_generic(tbm, "append", []string{args[1]}, buf)
}
}
func cmd_append(tbm *TBM, args []string) error {
var n int
var err error
f, _ := os.Open(args[0])
defer f.Close()
buf := make([]byte, 256)
for {
n, err = f.Read(buf)
if n == 0 {
return err
}
cmd_generic(tbm, "append", []string{args[1]}, buf)
}
}
func cmd_mv(tbm *TBM, args []string) error {
return cmd_generic(tbm, "mv", args, nil)
}
func cmd_cp(tbm *TBM, args []string) error {
return cmd_generic(tbm, "cp", args, nil)
}
func cmd_rm(tbm *TBM, args []string) error {
return cmd_generic(tbm, "rm", args, nil)
}
func main() {
flag.Parse()
args := flag.Args()
if len(args) == 0 {
log.Fatalf("Please specify at least one command")
}
command := args[0]
command_function, ok := commands[command]
if !ok {
log.Fatalf("Unknown command: %s", command)
}
t := &TBM{}
err := t.Connect(*serial_device, *serial_baudrate)
if err != nil {
log.Fatal(err)
}
t.Handle()
defer t.Close()
err = command_function(t, args[1:])
if err != nil {
log.Fatal(err)
}
}

@ -0,0 +1,30 @@
#!/bin/sh
die()
{
echo $1
exit -1
}
echo -n "Synchronizing time... "
timeout 1 ./admin -serial-baud 115200 sync-time || die "ERROR"
echo -n "Identifying flash chip... "
timeout 1 ./admin -serial-baud 115200 flash_probe 1>/dev/null || die "ERROR"
timeout 1 ./admin -serial-baud 115200 flash_info
echo -n "Erasing flash chip..."
timeout 60 ./admin -serial-baud 115200 flash_erase 0x0 0x100 1>/dev/null || die "ERROR"
echo "OK"
echo -n "Formatting flash chip... "
timeout 10 ./admin -serial-baud 115200 ftl_probe || die "ERROR"
timeout 10 ./admin -serial-baud 115200 format || die "ERROR"
echo "OK"
echo -n "Testing filesystem..."
timeout 10 ./admin -serial-baud 115200 mount || die "ERROR"
timeout 10 ./admin -serial-baud 115200 mkdir test || die "ERROR"
timeout 10 ./admin -serial-baud 115200 ls | grep -Fqe "test" || die "ERROR"
timeout 10 ./admin -serial-baud 115200 rmdir test || die "ERROR"
echo "OK"

@ -0,0 +1,170 @@
package main
import (
"fmt"
"io"
"log"
"strings"
"time"
"github.com/tarm/serial"
)
type TBM struct {
Commands chan *Command
Results chan *Result
Port *serial.Port
}
type Command struct {
command string
args []string
payload []byte
}
type Result struct {
output []byte
errcode []byte
}
func (t *TBM) Connect(device string, baud int) error {
t.Commands = make(chan *Command)
t.Results = make(chan *Result)
serialconfig := &serial.Config{Name: device, Baud: baud}
port, err := serial.OpenPort(serialconfig)
if err != nil {
return err
}
t.Port = port
return nil
}
func (t *TBM) Handle() error {
go handleResults(t.Port, t.Results)
go handleCommands(t.Port, t.Commands)
return nil
}
func (t *TBM) Close() {
t.Port.Close()
}
func deserialise(in io.Reader, init []byte) (*Result, []byte, error) {
var (
output, errorcode []byte
data, rest []byte
)
want_output := true
_ = copy(data, init)
for {
buf := make([]byte, 4096)
n, err := in.Read(buf)
if err != nil {
return nil, nil, err
}
n2 := n + len(data)
data = append(data, buf[:n]...)
for i := 0; i < n2; i++ {
// '\r' is really '\n'
if data[i] == '\r' {
data = append(data[:i], data[i+1:]...)
n2--
continue
}
if data[i] == 0x4 {
if want_output {
want_output = false
output = data[:i]
data = data[i+1:]
// The TBM gives us our own commands back
for j := 0; j < len(output); j++ {
if output[j] == '\n' {
output = output[j+1:]
break
}
}
break
} else {
errorcode = data[:i]
rest = data[i+1:]
return &Result{output, errorcode}, rest, nil
}
}
}
}
}
func handleResults(in io.Reader, c chan *Result) {
var (
res *Result
rest []byte
err error
)
for {
res, rest, err = deserialise(in, rest)
if err != nil {
log.Fatal(err)
}
c <- res
}
}
func serialise(out io.Writer, command string, args []string, payload []byte) error {
var quoted_args []string
var err error
quoted_args = append(quoted_args, command)
for _, arg := range args {
quoted_args = append(quoted_args, fmt.Sprintf("\"%s\"", arg))
}
out_string := strings.Join(quoted_args, " ")
output := []byte(out_string)
output = append(output, '\r')
_, err = out.Write(output)
// err is non nil if n != len(output)
if err != nil {
return err
}
if payload == nil {
return nil
}
// FIXME: wait for command to finish
time.Sleep(time.Second)
output = append(payload, 0x4)
_, err = out.Write(output)
return err
}
func handleCommands(out io.Writer, c chan *Command) {
for command := range c {
err := serialise(out, command.command, command.args, command.payload)
if err != nil {
log.Fatal(err)
}
}
}

@ -12,11 +12,22 @@ var (
serial_device = flag.String("serial-device", "/dev/ttyUSB0", "Serial device to use")
serial_baudrate = flag.Int("serial-baud", 9600, "Serial baud rate")
commands = map[string]CommandFunc{"hi": cmd_hi, "ls": cmd_ls, "cat": cmd_cat, "time": cmd_time, "bootversion": cmd_bootversion, "bootok": cmd_bootok}
commands = map[string]CommandFunc{
"hi": cmd_hi,
"buzzer": cmd_buzzer,
"led": cmd_led,
"reset": cmd_reset,
"ls": cmd_ls,
"cat": cmd_cat,
"date": cmd_date,
"time": cmd_time,
"boot_version": cmd_bootversion,
"boot_ok": cmd_bootok,
}
)
func cmd_generic(tbm *TBM, command string, args []string) error {
cmd := &Command{command, args}
func cmd_generic(tbm *TBM, command string, args []string, payload []byte) error {
cmd := &Command{command, args, payload}
tbm.Commands <- cmd
res := <-tbm.Results
@ -29,27 +40,43 @@ func cmd_generic(tbm *TBM, command string, args []string) error {
}
func cmd_hi(tbm *TBM, args []string) error {
return cmd_generic(tbm, "hi", []string{"v20170802 testing"})
return cmd_generic(tbm, "hi", []string{"v20170802 testing"}, nil)
}
func cmd_buzzer(tbm *TBM, args []string) error {
return cmd_generic(tbm, "buzzer", args, nil)
}
func cmd_led(tbm *TBM, args []string) error {
return cmd_generic(tbm, "led", args, nil)
}
func cmd_reset(tbm *TBM, args []string) error {
return cmd_generic(tbm, "reset", args, nil)
}
func cmd_ls(tbm *TBM, args []string) error {
return cmd_generic(tbm, "ls", args)
return cmd_generic(tbm, "ls", args, nil)
}
func cmd_cat(tbm *TBM, args []string) error {
return cmd_generic(tbm, "cat", args)
return cmd_generic(tbm, "cat", args, nil)
}
func cmd_date(tbm *TBM, args []string) error {
return cmd_generic(tbm, "time", args, nil)
}
func cmd_time(tbm *TBM, args []string) error {
return cmd_generic(tbm, "time", args)
return cmd_generic(tbm, "time", args, nil)
}
func cmd_bootversion(tbm *TBM, args []string) error {
return cmd_generic(tbm, "booting", args)
return cmd_generic(tbm, "booting", args, nil)
}
func cmd_bootok(tbm *TBM, args []string) error {
return cmd_generic(tbm, "booting", []string{"ok"})
return cmd_generic(tbm, "booting", []string{"ok"}, nil)
}
func main() {

@ -5,6 +5,7 @@ import (
"io"
"log"
"strings"
"time"
"github.com/tarm/serial"
)
@ -18,6 +19,7 @@ type TBM struct {
type Command struct {
command string
args []string
payload []byte
}
type Result struct {
@ -75,7 +77,9 @@ func deserialise(in io.Reader, init []byte) (*Result, []byte, error) {
for i := 0; i < n2; i++ {
// '\r' is really '\n'
if data[i] == '\r' {
data[i] = '\n'
data = append(data[:i], data[i+1:]...)
n2--
continue
}
if data[i] == 0x4 {
@ -83,15 +87,13 @@ func deserialise(in io.Reader, init []byte) (*Result, []byte, error) {
want_output = false
output = data[:i]
data = data[i+1:]
/*
// The TBM gives us our own commands back
for j := 0; j < len(output); j++ {
if output[j] == '\r' {
if output[j] == '\n' {
output = output[j+1:]
break
}
}
*/
break
} else {
errorcode = data[:i]
@ -124,8 +126,9 @@ func handleResults(in io.Reader, c chan *Result) {
}
}
func serialise(out io.Writer, command string, args []string) error {
func serialise(out io.Writer, command string, args []string, payload []byte) error {
var quoted_args []string
var err error
quoted_args = append(quoted_args, command)
@ -137,20 +140,29 @@ func serialise(out io.Writer, command string, args []string) error {
output := []byte(out_string)
output = append(output, '\r')
//output = append(output, 0x4)
_, err := out.Write(output)
_, err = out.Write(output)
// err is non nil if n != len(output)
if err != nil {
return err
}
return nil
if payload == nil {
return nil
}
// FIXME: wait for command to finish
time.Sleep(time.Second)
output = append(payload, 0x4)
_, err = out.Write(output)
return err
}
func handleCommands(out io.Writer, c chan *Command) {
for command := range c {
err := serialise(out, command.command, command.args)
err := serialise(out, command.command, command.args, command.payload)
if err != nil {
log.Fatal(err)
}

Loading…
Cancel
Save