can provides an interface to a CAN bus to read and write frames. The library is based on the SocketCAN network stack on Linux.
I'm using a Raspberry Pi 2 Model B and PiCAN2 CAN-Bus board for Raspberry Pi 2 to connect to a CAN bus.
The Raspberry Pi runs Raspbian.
Update /boot/config.txt
with
dtparam=spi=on
dtoverlay=mcp2515-can0-overlay,oscillator=16000000,interrupt=25
dtoverlay=spi-bcm2835-overlay
and reboot.
After phyiscally connecting to the CAN bus, you have to set up the can network interface for a specific bitrate, i.e. 50 kB
sudo ip link set can0 up type can bitrate 50000
Running ifconfig
should now include the can0
interface.
You should test if you actually receive data from the CAN bus. You can either use the candump
tool from the can-utils or a simple reimplementation under cmd/candump.go
.
Either way you will see something like this
> go run $GOSRC/github.com/brutella/can/cmd/candump.go -if can0
can0 100 [6] 20 83 0C 00 67 29 ' ...g)'
can0 701 [1] 05 '.'
bus, _ := can.NewBusForInterfaceWithName("can0")
bus.ConnectAndPublish()
frm := can.Frame{
ID: 0x701,
Length: 1,
Flags: 0,
Res0: 0,
Res1: 0,
Data: [8]uint8{0x05},
}
bus.Publish(frm)
bus.SubscribeFunc(handleCANFrame)
func handleCANFrame(frm can.Frame) {
...
}
There is more to learn from the documentation.
Matthias Hochgatterer
Github: https://github.com/brutella
Twitter: https://twitter.com/brutella
can is available under the MIT license. See the LICENSE file for more info.
import "github.com/brutella/can"
Package can provides an implemention of a CAN bus to send and receive CAN frames.
- Constants
- func Marshal(frm Frame) (b []byte, err error)
- func NewSockaddr(proto uint16, Ifindex int) syscall.Sockaddr
- func Unmarshal(b []byte, frm *Frame) (err error)
- func Wait(bus *Bus, id uint32, timeout time.Duration) <-chan WaitResponse
- type Bus
- func NewBus(rwc ReadWriteCloser) *Bus
- func NewBusForInterfaceWithName(ifaceName string) (*Bus, error)
- func (b *Bus) ConnectAndPublish() error
- func (b *Bus) Disconnect() error
- func (b *Bus) Publish(frame Frame) error
- func (b *Bus) Subscribe(handler Handler)
- func (b *Bus) SubscribeFunc(fn HandlerFunc)
- func (b *Bus) Unsubscribe(handler Handler)
- type Frame
- type Handler
- type HandlerFunc
- type ReadWriteCloser
- type Reader
- type WaitResponse
- type Writer
const (
// MaskIDSff is used to extract the valid 11-bit CAN identifier bits from the frame ID of a standard frame format.
MaskIDSff = 0x000007FF
// MaskIDEff is used to extract the valid 29-bit CAN identifier bits from the frame ID of an extended frame format.
MaskIDEff = 0x1FFFFFFF
// MaskErr is used to extract the the error flag (0 = data frame, 1 = error message) from the frame ID.
MaskErr = 0x20000000
// MaskRtr is used to extract the rtr flag (1 = rtr frame) from the frame ID
MaskRtr = 0x40000000
// MaskEff is used to extract the eff flag (0 = standard frame, 1 = extended frame) from the frame ID
MaskEff = 0x80000000
)
const (
// MaxFrameDataLength defines the max length of a CAN data frame defined in ISO 11898-1.
MaxFrameDataLength = 8
// MaxExtFrameDataLength defines the max length of an CAN extended data frame defined in ISO ISO 11898-7.
MaxExtFrameDataLength = 64
)
const AF_CAN = syscall.AF_CAN
func Marshal
func Marshal(frm Frame) (b []byte, err error)
Marshal returns the byte encoding of frm.
func NewSockaddr
func NewSockaddr(proto uint16, Ifindex int) syscall.Sockaddr
func Unmarshal
func Unmarshal(b []byte, frm *Frame) (err error)
Unmarshal parses the bytes b and stores the result in the value pointed to by frm.
func Wait
func Wait(bus *Bus, id uint32, timeout time.Duration) <-chan WaitResponse
Wait returns a channel, which receives a frame or an error, if the frame with the expected id didn't arrive on time.
type Bus
Bus represents the CAN bus. Handlers can subscribe to receive frames. Frame are sent using the *Publish* method.
type Bus struct {
// contains filtered or unexported fields
}
func NewBus
func NewBus(rwc ReadWriteCloser) *Bus
NewBus returns a new CAN bus.
func NewBusForInterfaceWithName(ifaceName string) (*Bus, error)
NewBusForInterfaceWithName returns a bus from the network interface with name ifaceName.
func (*Bus) ConnectAndPublish
func (b *Bus) ConnectAndPublish() error
ConnectAndPublish starts handling CAN frames to publish them to handlers.
func (*Bus) Disconnect
func (b *Bus) Disconnect() error
Disconnect stops handling CAN frames.
func (*Bus) Publish
func (b *Bus) Publish(frame Frame) error
Publish publishes a frame on the bus.
Frames publishes with the Publish methods are not received by handlers.
func (*Bus) Subscribe
func (b *Bus) Subscribe(handler Handler)
Subscribe adds a handler to the bus.
func (*Bus) SubscribeFunc
func (b *Bus) SubscribeFunc(fn HandlerFunc)
SubscribeFunc adds a function as handler.
func (*Bus) Unsubscribe
func (b *Bus) Unsubscribe(handler Handler)
Unsubscribe removes a handler.
type Frame
Frame represents a standard CAN data frame
type Frame struct {
// bit 0-28: CAN identifier (11/29 bit)
// bit 29: error message flag (ERR)
// bit 30: remote transmision request (RTR)
// bit 31: extended frame format (EFF)
ID uint32
Length uint8
Flags uint8
Res0 uint8
Res1 uint8
Data [MaxFrameDataLength]uint8
}
type Handler
The Handler interfaces defines a method to receive a frame.
type Handler interface {
Handle(frame Frame)
}
func NewHandler
func NewHandler(fn HandlerFunc) Handler
NewHandler returns a new handler which calls fn when a frame is received.
type HandlerFunc
HandlerFunc defines the function type to handle a frame.
type HandlerFunc func(frame Frame)
type ReadWriteCloser
The ReadWriteCloser interface combines the Reader and Writer and `io.Closer` interface.
type ReadWriteCloser interface {
Reader
Writer
io.Closer
}
func NewEchoReadWriteCloser() ReadWriteCloser
NewEchoReadWriteCloser returns a ReadWriteCloser which echoes received bytes.
func NewReadWriteCloser
func NewReadWriteCloser(rwc io.ReadWriteCloser) ReadWriteCloser
NewReadWriteCloser returns a ReadWriteCloser for an `io.ReadWriteCloser`.
func NewReadWriteCloserForInterface(i *net.Interface) (ReadWriteCloser, error)
type Reader
The Reader interface extends the `io.Reader` interface by method to read a frame.
type Reader interface {
io.Reader
ReadFrame(*Frame) error
}
type WaitResponse
A WaitResponse encapsulates the response of waiting for a frame.
type WaitResponse struct {
Frame Frame
Err error
}
type Writer
The Writer interface extends the `io.Writer` interface by method to write a frame.
type Writer interface {
io.Writer
WriteFrame(Frame) error
}
Generated by gomarkdoc