canopen

package module
v1.3.0 Latest Latest
Warning

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

Go to latest
Published: Oct 8, 2024 License: GPL-3.0 Imports: 3 Imported by: 0

README

��# gocanopen

Go Reference Go Report Card

gocanopen is an implementation of the CANopen protocol (CiA 301) written in pure golang. It aims to be simple and efficient. This package can be used for master usage but also supports creating regular CANopen nodes.

Features

All the main components of CiA 301 are supported, these include :

  • SDO server/client
  • NMT master/slave
  • HB producer/consumer
  • TPDO/RPDO
  • EMERGENCY producer/consumer
  • SYNC producer/consumer
  • TIME producer/consumer

Partial support also exists for CiA 309, specifically :

  • HTTP gateway

gocanopen does not require the use of an external tool to generate some source code from an EDS file. EDS files can be loaded dynamically from disk to create local nodes with default supported objects. The library comes with a default embedded EDS file, which can be used when creating nodes.

Supported CAN transceivers

Currently this package supports the following transceivers:

  • socketcan
  • kvaser
  • virtualcan here

In order to use kvaser, canlib should be downloaded & installed. Specific compile flags are needed :

  • CFLAGS: -g -Wall -I/path_to_kvaser/canlib/include
  • LDFLAGS: -L/path_to_kvaser/canlib

More transceivers can be added by creating your own driver and implementing the following interface :

type Bus interface {
	Connect(...any) error                   // Connect to the actual bus
	Disconnect() error                      // Disconnect from bus
	Send(frame Frame) error                 // Send a frame on the bus
	Subscribe(callback FrameListener) error // Subscribe to all can frames
}

Feel free to contribute to add specific drivers, we will find a way to integrate them in this repo. This repo contains two implementation examples : socketcan.go, and virtual.go used for testing.

Documentation

  1. Introduction
  2. Network
  3. Object Dictionary
  4. Local nodes

Usage

Examples can be found in /examples

Basic setup example :

package main

import (
	"fmt"

	"github.com/samsamfire/gocanopen/pkg/network"
	"github.com/samsamfire/gocanopen/pkg/od"
)

func main() {
	network := network.NewNetwork(nil)
	err := network.Connect("socketcan", "can0", 500_000)
	if err != nil {
		panic(err)
	}
	defer network.Disconnect()

	// Add a remote node to the network, either by providing an EDS file
	// Or downloading from the node. We use here a default OD available with the library
	node, err := network.AddRemoteNode(0x10, od.Default())
	if err != nil {
		panic(err)
	}

	// Read standard entry containing device name (0x1008)
	value, err := node.Configurator().ReadManufacturerDeviceName()
	if err != nil {
		fmt.Printf("error reading node %v device name : %v\n", node.GetID(), err)
	} else {
		fmt.Printf("node %v device name is %v\n", node.GetID(), value)
	}

	// Perform a network scan to detect other nodes...
	res, err := network.Scan(1000)
	if err != nil {
		panic(err)
	}
	fmt.Println("scanned the following nodes : ", res)
}

Work ongoing

  • Improve documentation & examples
  • More testing
  • API improvements

Testing

Testing is done :

  • With unit testing
  • Testing against an other implementation in python

Tests are done with virtualcan server, which can be used easily with github actions. More tests are always welcome if you believe that some part of the spec is not properly tested.

For running tests, install the required packages pip install -r ./tests/requirements.txt Run the tests with : pytest -v

Logs

The application uses the log package logrus Logs can be adjusted with different log levels :

import log "github.com/sirupsen/logrus"

log.SetLevel(log.DebugLevel)
// log.SetLevel(log.WarnLevel)

Documentation

Index

Constants

View Source
const (
	CanErrorTxWarning          = 0x0001 // CAN transmitter warning
	CanErrorTxPassive          = 0x0002 // CAN transmitter passive
	CanErrorTxBusOff           = 0x0004 // CAN transmitter bus off
	CanErrorTxOverflow         = 0x0008 // CAN transmitter overflow
	CanErrorPdoLate            = 0x0080 // TPDO is outside sync window
	CanErrorRxWarning          = 0x0100 // CAN receiver warning
	CanErrorRxPassive          = 0x0200 // CAN receiver passive
	CanErrorRxOverflow         = 0x0800 // CAN receiver overflow
	CanErrorWarnPassive        = 0x0303 // Combination
	CanRtrFlag          uint32 = 0x40000000
	CanSffMask          uint32 = 0x000007FF
)

Variables

View Source
var (
	ErrIllegalArgument       = errors.New("error in function arguments")
	ErrOutOfMemory           = errors.New("memory allocation failed")
	ErrTimeout               = errors.New("function timeout")
	ErrIllegalBaudrate       = errors.New("illegal baudrate passed to function")
	ErrRxOverflow            = errors.New("previous message was not processed yet")
	ErrRxPdoOverflow         = errors.New("previous PDO was not processed yet")
	ErrRxMsgLength           = errors.New("wrong receive message length")
	ErrRxPdoLength           = errors.New("wrong receive PDO length")
	ErrTxOverflow            = errors.New("previous message is still waiting, buffer full")
	ErrTxPdoWindow           = errors.New("synchronous TPDO is outside window")
	ErrTxUnconfigured        = errors.New("transmit buffer was not configured properly")
	ErrOdParameters          = errors.New("error in Object Dictionary parameters")
	ErrDataCorrupt           = errors.New("stored data are corrupt")
	ErrCRC                   = errors.New("crc does not match")
	ErrTxBusy                = errors.New("sending rejected because driver is busy. Try again")
	ErrWrongNMTState         = errors.New("command can't be processed in the current state")
	ErrSyscall               = errors.New("syscall failed")
	ErrInvalidState          = errors.New("driver not ready")
	ErrNodeIdUnconfiguredLSS = errors.New("node-id is in LSS unconfigured state. If objects are handled properly, this may not be an error")
)

Functions

func IsIDRestricted added in v1.2.0

func IsIDRestricted(canId uint16) bool

Types

type Bus

type Bus interface {
	Connect(...any) error                   // Connect to the CAN bus
	Disconnect() error                      // Disconnect from CAN bus
	Send(frame Frame) error                 // Send a frame on the bus
	Subscribe(callback FrameListener) error // Subscribe to all received CAN frames
}

A CAN Bus interface

type BusManager

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

Bus manager is a wrapper around the CAN bus interface Used by the CANopen stack to control errors, callbacks for specific IDs, etc.

func NewBusManager

func NewBusManager(bus Bus) *BusManager

func (*BusManager) Bus

func (bm *BusManager) Bus() Bus

func (*BusManager) Error added in v1.2.0

func (bm *BusManager) Error() uint16

Get CAN error

func (*BusManager) Handle

func (bm *BusManager) Handle(frame Frame)

Implements the FrameListener interface This handles all received CAN frames from Bus

func (*BusManager) Process added in v1.2.0

func (bm *BusManager) Process() error

This should be called cyclically to update errors

func (*BusManager) Send

func (bm *BusManager) Send(frame Frame) error

Send a CAN message Limited error handling

func (*BusManager) SetBus added in v1.2.0

func (bm *BusManager) SetBus(bus Bus)

Set bus

func (*BusManager) Subscribe

func (bm *BusManager) Subscribe(ident uint32, mask uint32, rtr bool, callback FrameListener) error

Subscribe to a specific CAN ID

type Frame

type Frame struct {
	ID    uint32
	Flags uint8
	DLC   uint8
	Data  [8]byte
}

A generic 11bit CAN frame

func NewFrame

func NewFrame(id uint32, flags uint8, dlc uint8) Frame

type FrameListener

type FrameListener interface {
	Handle(frame Frame)
}

Interface for handling a received CAN frame

Directories

Path Synopsis
examples
master
Example of master usage
Example of master usage
internal
crc
pkg
can
can/kvaser
provide fallback when not compiling kvaser
provide fallback when not compiling kvaser
network
This package is a pure golang implementation of the CANopen protocol
This package is a pure golang implementation of the CANopen protocol
nmt
od
pdo
sdo

Jump to

Keyboard shortcuts

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