folie

package module
v0.0.0-...-be91734 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 29, 2017 License: Unlicense Imports: 21 Imported by: 1

README

Folie v3

GoDoc license

The Forth Live Explorer is a command-line utility to talk to a micro-controller via a (local or remote) serial port. Its main mode of operation is as interactive terminal, but it can also upload code to an STM32 µC and is tailored in particular for use with Mecrisp Forth.

This is experimental code, the stable version is at:
https://github.com/jeelabs/embello/tree/master/tools/folie

Acknowledgments

  • Mecrisp Forth by Matthias Koch (GPL3) - the reason Folie exists
  • Go (BSD) - the language which gets types, concurrency, builds, and deployment right
  • go-serial by Christian Maglie (BSD) - knows about serial ports across all platforms
  • readline by @chzyer (MIT) - takes care of local line editing and history
  • the JeeLabs chat group - you know who you are...

Documentation

Index

Constants

View Source
const (
	RawIn    = iota // raw bytes input
	ResetIn         // reset uC (has no data)
	PacketIn        // data packet (data is packet)
	ForthIn         // forth source code (data is code, no echo desired)
	FlashIn         // flash upload (data is flash binary/hex)
)
View Source
const (
	Iac  = 255
	Will = 251
	Sb   = 250
	Se   = 240

	ComPortOpt = 44
	SetParity  = 3
	SetControl = 5

	PAR_NONE = 1
	PAR_EVEN = 3

	FLOW_OFF = 1
	DTR_ON   = 8
	DTR_OFF  = 9
	RTS_ON   = 11
	RTS_OFF  = 12
)
View Source
const (
	ACK        = 0x79
	NAK        = 0x1F
	GET_CMD    = 0x00
	GETID_CMD  = 0x02
	GO_CMD     = 0x21
	WRITE_CMD  = 0x31
	ERASE_CMD  = 0x43
	EXTERA_CMD = 0x44
	WRUNP_CMD  = 0x73
	RDUNP_CMD  = 0x92
)

Variables

View Source
var Verbose bool

Functions

func MicroConnRunner

func MicroConnRunner(mc MicroConn, rx chan<- []byte) error

MicroConnRunner takes a MicroConn and an rx channel. It operates a goroutine that reads from the MicroConn into the channel allowing higher levels to select on that channel. It also catches errors and reopens the MicroConn transparently.

MicroConnRunner does not take part in the sending of data, instead, the MicroConn's Write method should be called directly. It is expected that catching errors on Read is sufficient and "heals" errors on the sending side quickly enough.

The initial opening of the connection is done synchronously so an error can be returned immediately, afterwards goroutines are spawned to continue the connection(s).

func NewReadline

func NewReadline() (*readline.Instance, error)

NewReadline creates a readline instance on stdin/out.

func RunConsole

func RunConsole(rdl *readline.Instance, rx chan<- []byte, done chan error)

RunConsole is an infinite loop to push lines read on stdin into the rx channel.

func SelectPort

func SelectPort(console *readline.Instance) string

SelectPort enumerates available ports, prompts for a choice, and returns the chosen port name. It returns an empty string if nothing useful was chosen.

Types

type FileCompleter

type FileCompleter struct{}

FileCompleter performs filename completion for readline.

func (FileCompleter) Do

func (f FileCompleter) Do(line []rune, pos int) (newLine [][]rune, length int)

Do returns a list of candidate completions given the whole line and the current offset into it. The length return value is how long they shared the same characters in line. Example:

[go, git, git-shell, grep]
Do("g", 1) => ["o", "it", "it-shell", "rep"], 1
Do("gi", 2) => ["t", "t-shell"], 2
Do("git", 3) => ["", "-shell"], 3

type MicroConn

type MicroConn interface {
	// Read must return an error if there is a problem with the connection.
	// Write must be atomic and it must return an io.EOF error if the conn is closed.
	io.ReadWriteCloser

	Open() error     // (re-)open the connection
	Reset(bool) bool // reset the microcontroller, the param says whether to enter the bootloader

}

MicroConn represents a connection to a microcontroller which is a bidirectional line-oriented connection plus a number of out-of-band commands to perform actions such as resetting the microcontroller, and flashing a raw binary.

type MicroFlasher

type MicroFlasher interface {
	Flash(pgm []byte)
}

type NetInput

type NetInput struct {
	What int    // one of RawIn, PacketIn, CommandIn, FlashIn
	Buf  []byte // data
}

NetInput can hold a byte buffer or a command.

type SSHClient

type SSHClient struct {
	// contains filtered or unexported fields
}

SSHClient represents an instance of an SSH client that connect to a remote folie as a network input. Locally it takes the place of a serial port or telnet connection. Therefore SSHClient implements MicroConn.

func NewSSHClient

func NewSSHClient(addr string) (*SSHClient, error)

NewSSHClient prepares the crypto info to connect to a remote folie process via SSH. It returns an SSHClient on which Open can be called multiple times to open an re-open the connection.

func (*SSHClient) Close

func (sc *SSHClient) Close() error

func (*SSHClient) Flash

func (sc *SSHClient) Flash(pgm []byte)

func (*SSHClient) Open

func (sc *SSHClient) Open() error

Open dials the SSH connection to the remote folie server. It also requests and interactive shell session.

func (*SSHClient) Read

func (sc *SSHClient) Read(buf []byte) (int, error)

func (*SSHClient) Reset

func (sc *SSHClient) Reset(bootloader bool) bool

func (*SSHClient) Write

func (sc *SSHClient) Write(buf []byte) (int, error)

type SSHServer

type SSHServer struct {
	// contains filtered or unexported fields
}

SSHServer represents an instance of an SSH server that accepts incoming connections that gain access to the serial port managed by folie.

func NewSSHServer

func NewSSHServer(listenAddr, serverKeyFile, authorizedKeysFile string) (*SSHServer, error)

NewSSHServer creates a new SSHServer, opens the listening socket, and validates that the server key and authorized keys files can be read.

func (*SSHServer) Run

func (ss *SSHServer) Run(rx chan<- NetInput, addTxWriter func(io.Writer))

Run is an infinite loop that accepts incoming connections. For each connection it starts a goroutine that reads on the connection and pushes bytes into the rx channel (which is shared across all). It also makes a callback to ss.addTxWriter to register the SSH channel with the switchboard for transmission.

type SerialConn

type SerialConn struct {
	Path string // pathname of device
	Baud int    // desired baud rate, if 0 defaults to 115200
	// contains filtered or unexported fields
}

SerialConn implements microConn for a microcontroller attached to a local serial port.

func (*SerialConn) Close

func (sc *SerialConn) Close() error

Close closes the connection.

func (*SerialConn) Open

func (sc *SerialConn) Open() error

Open connects to the serial device and initializes the baud rate as well as RTS & DTR.

func (*SerialConn) Read

func (sc *SerialConn) Read(buf []byte) (int, error)

Read bytes from the connection.

func (*SerialConn) Reset

func (sc *SerialConn) Reset(enterBoot bool) bool

Reset resets the attached microcontroller. If enterBoot is true the microcontroller enters the built-in bootloader allowing flash memory to be reprogrammed. Return true if the reset can be issued, false if there is an error.

func (*SerialConn) Write

func (sc *SerialConn) Write(buf []byte) (int, error)

Write atomically sends bytes across the connection.

type Switchboard

type Switchboard struct {
	MicroInput   <-chan []byte   // receive from microcontroller
	MicroOutput  MicroConn       // send to microcontroller
	ConsoleInput <-chan []byte   // receive from interactive console (has ! commands)
	NetworkInput <-chan NetInput // receive from remote consoles (no ! commands)

	AssetNames []string                     // list of built-in firmwares
	Asset      func(string) ([]byte, error) // callback to get asset
	// contains filtered or unexported fields
}

Switchboard represents the central point where all input and output methods come together. This where data is forwarded from one to another and where the decision is made whether to interpret commands or pass data through uninterpreted.

func (*Switchboard) AddConsoleOutput

func (sw *Switchboard) AddConsoleOutput(wr io.Writer)

AddConsoleOutput registers a new writer to get console output.

func (*Switchboard) RemoveConsoleOutput

func (sw *Switchboard) RemoveConsoleOutput(wr io.Writer)

RemoveConsoleOutput unregisters a write from receiving console output. In general this is not needed and instead the fact that the writer produces an error on close is used.

func (*Switchboard) Run

func (sw *Switchboard) Run()

Run operates teh switchboard and specifically processes input and writes it as approprite to outputs. Run is an infinite for loop with a select, so once input arrives that captures the thread of control until the corresponding output is done. In some cases, such as when calling specialCommand, further input may be awaited and processed, so a command can block the entire switchboard until it's done. This is helpful when running commands (like flashing the uC) that should not be interrupted by other stuff.

type TelnetConn

type TelnetConn struct {
	Addr string // telnet server address, passed to net.Dial
	Path string // serial port to which serplus is attached.
	// contains filtered or unexported fields
}

TelnetConn implements microConn for a microcontroller attached via a telnet connection to a server that understands telnet escapes for adjusting the baudrate and toggling DTS/RTS. Examples are ser2net and esp-link. It also connects to serplus via a serial port. Only one of Addr or Path must be set.

func (*TelnetConn) Close

func (tc *TelnetConn) Close() error

Close the connection.

func (*TelnetConn) Open

func (tc *TelnetConn) Open() error

Open connects to the telnet server and sends the initial escape sequence to configure the remote serial device.

func (*TelnetConn) Read

func (tc *TelnetConn) Read(buf []byte) (int, error)

Read bytes from the connection.

func (*TelnetConn) Reset

func (tc *TelnetConn) Reset(enterBoot bool) bool

Reset the remote microcontroller. Return true if the reset can be issued, false if there is an error.

func (*TelnetConn) Write

func (tc *TelnetConn) Write(buf []byte) (int, error)

Write atomically sends bytes across the connection. It escapes the Telnet escape character.

type Uploader

type Uploader struct {
	Tx     MicroConn
	Rx     <-chan []byte
	Stdout io.Writer
	// contains filtered or unexported fields
}

func (*Uploader) Upload

func (u *Uploader) Upload(data []byte)

Uploader implements the STM32 usart boot protocol to upload new firmware.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL