od

package
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: 18 Imported by: 0

Documentation

Index

Constants

View Source
const (
	ObjectTypeDOMAIN byte = 0x2
	ObjectTypeVAR    byte = 0x7
	ObjectTypeARRAY  byte = 0x8
	ObjectTypeRECORD byte = 0x9
)

CANopen supported ObjectType

View Source
const (
	BOOLEAN        uint8 = 0x01
	INTEGER8       uint8 = 0x02
	INTEGER16      uint8 = 0x03
	INTEGER32      uint8 = 0x04
	UNSIGNED8      uint8 = 0x05
	UNSIGNED16     uint8 = 0x06
	UNSIGNED32     uint8 = 0x07
	REAL32         uint8 = 0x08
	VISIBLE_STRING uint8 = 0x09
	OCTET_STRING   uint8 = 0x0A
	UNICODE_STRING uint8 = 0x0B
	DOMAIN         uint8 = 0x0F
	REAL64         uint8 = 0x11
	INTEGER64      uint8 = 0x15
	UNSIGNED64     uint8 = 0x1B
)

CANopen supported datatypes

View Source
const (
	MaxMappedEntriesPdo = uint8(8)
	FlagsPdoSize        = uint8(32)
)
View Source
const (
	AttributeSdoR   uint8 = 0x01 // SDO server may read from the variable
	AttributeSdoW   uint8 = 0x02 // SDO server may write to the variable
	AttributeSdoRw  uint8 = 0x03 // SDO server may read from or write to the variable
	AttributeTpdo   uint8 = 0x04 // Variable is mappable into TPDO (can be read)
	AttributeRpdo   uint8 = 0x08 // Variable is mappable into RPDO (can be written)
	AttributeTrpdo  uint8 = 0x0C // Variable is mappable into TPDO or RPDO
	AttributeTsrdo  uint8 = 0x10 // Variable is mappable into transmitting SRDO
	AttributeRsrdo  uint8 = 0x20 // Variable is mappable into receiving SRDO
	AttributeTrsrdo uint8 = 0x30 // Variable is mappable into tx or rx SRDO
	AttributeMb     uint8 = 0x40 // Variable is multi-byte ((u)int16_t to (u)int64_t)
	// Shorter value, than specified variable size, may be
	// written to the variable. SDO write will fill remaining memory with zeroes.
	// Attribute is used for VISIBLE_STRING and UNICODE_STRING.
	AttributeStr uint8 = 0x80
)

Object dictionary object attribute

View Source
const (
	EntryDeviceType                  uint16 = 0x1000
	EntryErrorRegister               uint16 = 0x1001
	EntryManufacturerStatusRegister  uint16 = 0x1003
	EntryCobIdSYNC                   uint16 = 0x1005
	EntryCommunicationCyclePeriod    uint16 = 0x1006
	EntrySynchronousWindowLength     uint16 = 0x1007
	EntryManufacturerDeviceName      uint16 = 0x1008
	EntryManufacturerHardwareVersion uint16 = 0x1009
	EntryManufacturerSoftwareVersion uint16 = 0x100A
	EntryStoreParameters             uint16 = 0x1010
	EntryRestoreDefaultParameters    uint16 = 0x1011
	EntryCobIdTIME                   uint16 = 0x1012
	EntryHighResTimestamp            uint16 = 0x1013
	EntryCobIdEMCY                   uint16 = 0x1014
	EntryInhibitTimeEMCY             uint16 = 0x1015
	EntryConsumerHeartbeatTime       uint16 = 0x1016
	EntryProducerHeartbeatTime       uint16 = 0x1017
	EntryIdentityObject              uint16 = 0x1018
	EntrySynchronousCounterOverflow  uint16 = 0x1019
	EntryStoreEDS                    uint16 = 0x1021
	EntryStorageFormat               uint16 = 0x1022
	EntrySDOServerParameter          uint16 = 0x1200
	EntrySDOClientParameter          uint16 = 0x1280
	EntryRPDOCommunicationStart      uint16 = 0x1400
	EntryRPDOCommunicationEnd        uint16 = 0x15FF
	EntryRPDOMappingStart            uint16 = 0x1600
	EntryRPDOMappingEnd              uint16 = 0x17FF
	EntryTPDOCommunicationStart      uint16 = 0x1800
	EntryTPDOCommunicationEnd        uint16 = 0x19FF
	EntryTPDOMappingStart            uint16 = 0x1A00
	EntryTPDOMappingEnd              uint16 = 0x1BFF
)

Standard CANopen object entries index

View Source
const (
	AreaCommunicationProfileStart        uint16 = 0x1000
	AreaCommunicationProfileEnd          uint16 = 0x1FFF
	AreaManufacturerSpecificProfileStart uint16 = 0x2000
	AreaManufacturerSpecificProfileEnd   uint16 = 0x5FFF
	AreaDeviceProfileStart               uint16 = 0x6000
	AreaDeviceProfileEnd                 uint16 = 0x9FFF
	AreaInterfaceProfileStart            uint16 = 0xA000
	AreaInterfaceProfileEnd              uint16 = 0xBFFF
	AreaFutureUseStart                   uint16 = 0xC000
	AreaFutureUseEnd                     uint16 = 0xFFFF
)

Standard CANopen object areas

View Source
const (
	FormatEDSAscii  = 0
	FormatEDSZipped = 0x90
)

EDS formats

Variables

View Source
var ErrEdsFormat = errors.New("invalid EDS format")
View Source
var ErrorDescriptionMap = map[ODR]string{
	ErrPartial:      "Incomplete transfer",
	ErrNo:           "No error",
	ErrOutOfMem:     "Out of memory",
	ErrUnsuppAccess: "Unsupported access to an object",
	ErrWriteOnly:    "Attempt to read a write only object",
	ErrReadonly:     "Attempt to write a read only object",
	ErrIdxNotExist:  "Object does not exist in the object dictionary",
	ErrNoMap:        "Object cannot be mapped to the PDO",
	ErrMapLen:       "Num and len of object to be mapped exceeds PDO len",
	ErrParIncompat:  "General parameter incompatibility reasons",
	ErrDevIncompat:  "General internal incompatibility in device",
	ErrHw:           "Access failed due to hardware error",
	ErrTypeMismatch: "Data type does not match, length does not match",
	ErrDataLong:     "Data type does not match, length too high",
	ErrDataShort:    "Data type does not match, length too short",
	ErrSubNotExist:  "Sub index does not exist",
	ErrInvalidValue: "Invalid value for parameter (download only)",
	ErrValueHigh:    "Value range of parameter written too high",
	ErrValueLow:     "Value range of parameter written too low",
	ErrMaxLessMin:   "Maximum value is less than minimum value.",
	ErrNoRessource:  "Resource not available: SDO connection",
	ErrGeneral:      "General error",
	ErrDataTransf:   "Data cannot be transferred or stored to application",
	ErrDataLocCtrl:  "Data cannot be transferred because of local control",
	ErrDataDevState: "Data cannot be tran. because of present device state",
	ErrOdMissing:    "Object dict. not present or dynamic generation fails",
	ErrNoData:       "No data available",
}
View Source
var OBJ_NAME_MAP = map[byte]string{
	ObjectTypeDOMAIN: "DOMAIN  ",
	ObjectTypeVAR:    "VARIABLE",
	ObjectTypeARRAY:  "ARRAY   ",
	ObjectTypeRECORD: "RECORD  ",
}

Functions

func CheckSize

func CheckSize(length int, dataType uint8) error

Helper function for checking consistency between size and datatype

func DecodeAttribute added in v1.3.0

func DecodeAttribute(attribute uint8) string

Encode attribute

func DecodeToString added in v1.3.0

func DecodeToString(data []byte, dataType uint8, base int) (v string, e error)

Decode byte array given the CANopen data type Function will return either string, int64, uint64, or float64

func DecodeToType added in v1.3.0

func DecodeToType(data []byte, dataType uint8) (v any, e error)

Decode byte array given the CANopen data type Function will return either string, int64, uint64, or float64

func EncodeAttribute added in v1.3.0

func EncodeAttribute(accessType string, pdoMapping bool, dataType uint8) uint8

Decode the attribute in function of the of attribute type and pdo mapping for EDS entry

func EncodeFromGeneric

func EncodeFromGeneric(data any) ([]byte, error)

Encode from generic type

func EncodeFromString

func EncodeFromString(value string, datatype uint8, offset uint8) ([]byte, error)

EncodeFromString value from EDS into bytes respecting canopen datatype

func ExportEDS added in v1.3.0

func ExportEDS(odict *ObjectDictionary, defaultValues bool, filename string) error

Export OD inside of an EDS file OD can be exported with default values (initial values) Or with current values (with new PDO mapping for example) The created file is not 100% compliant with CiA but will work for this library.

func ReadEntryDefault

func ReadEntryDefault(stream *Stream, data []byte, countRead *uint16) error

This is the default "StreamReader" type for every OD entry It Reads a value from the original OD location i.e. Stream object And writes it inside data. It also updates the actual read count, countRead

func ReadEntryDisabled

func ReadEntryDisabled(stream *Stream, data []byte, countRead *uint16) error

"StreamReader" when the actual OD entry to be read is disabled

func ReadEntryFileObject

func ReadEntryFileObject(stream *Stream, data []byte, countRead *uint16) error

[SDO] Custom function for reading a file like object

func ReadEntryReader

func ReadEntryReader(stream *Stream, data []byte, countRead *uint16) error

[SDO] Custom function for reading an io.Reader

func WriteEntryDefault

func WriteEntryDefault(stream *Stream, data []byte, countWritten *uint16) error

This is the default "StreamWriter" type for every OD entry It writes data to the Stream object It also updates the number write count, countWritten

func WriteEntryDisabled

func WriteEntryDisabled(stream *Stream, data []byte, countWritten *uint16) error

"StreamWriter" when the actual OD entry to be written is disabled

func WriteEntryFileObject

func WriteEntryFileObject(stream *Stream, data []byte, countWritten *uint16) error

[SDO] Custom function for writing a file like object

Types

type EDSFormatHandler added in v1.3.0

type EDSFormatHandler func(nodeId uint8, formatType uint8, reader io.Reader) (*ObjectDictionary, error)

EDSFormatHandler takes a formatType, nodeId and a reader to handle an EDS file stored as a proprietary format (zip, etc)

type Entry

type Entry struct {
	// The OD index e.g. x1006
	Index uint16
	// The OD name inside of EDS
	Name string
	// The OD object type, as cited above.
	ObjectType uint8
	// contains filtered or unexported fields
}

An Entry object is the main building block of an ObjectDictionary. it holds an OD entry, i.e. an OD object at a specific index. An entry can be one of the following object types, defined by CiA 301

If the Object is an ARRAY or a RECORD it can hold also multiple sub entries. sub entries are always of type VAR, for simplicity.

func (*Entry) AddExtension

func (entry *Entry) AddExtension(object any, read StreamReader, write StreamWriter)

Add an extension to an OD entry This allows an OD entry to perform custom behaviour on read or on write. Some extensions are already defined in this package for defined CiA entries e.g. objects x1005, x1006, etc. Implementation of the default StreamReader & StreamWriter for a regular OD entry can be found here ReadEntryDefault & WriteEntryDefault.

func (*Entry) Extension

func (entry *Entry) Extension() *extension

func (*Entry) FlagPDOByte

func (entry *Entry) FlagPDOByte(subIndex byte) *uint8

func (*Entry) GetRawData

func (entry *Entry) GetRawData(subIndex uint8, length uint16) ([]byte, error)

GetRawData returns the raw byte slice stored inside of OD

func (*Entry) PutRawData added in v1.3.0

func (entry *Entry) PutRawData(subindex uint8, data []byte) error

PutRawData updates the raw byte slice stored in OD

func (*Entry) PutUint16

func (entry *Entry) PutUint16(subIndex uint8, data uint16, origin bool) error

PutUint16 writes an UNSIGNED16 to OD entry. origin can be set to true in order to bypass any existing extension.

func (*Entry) PutUint32

func (entry *Entry) PutUint32(subIndex uint8, data uint32, origin bool) error

PutUint32 writes an UNSIGNED32 to OD entry. origin can be set to true in order to bypass any existing extension.

func (*Entry) PutUint64

func (entry *Entry) PutUint64(subIndex uint8, data uint64, origin bool) error

PutUint64 writes an UNSIGNED64 to OD entry. origin can be set to true in order to bypass any existing extension.

func (*Entry) PutUint8

func (entry *Entry) PutUint8(subIndex uint8, value uint8, origin bool) error

PutUint8 writes an UNSIGNED8 to OD entry. origin can be set to true in order to bypass any existing extension.

func (*Entry) ReadExactly added in v1.3.0

func (entry *Entry) ReadExactly(subIndex uint8, b []byte, origin bool) error

Read exactly len(b) bytes from OD at (index,subIndex) origin parameter controls extension usage if any

func (*Entry) SubCount

func (entry *Entry) SubCount() int

SubCount returns the number of sub entries inside entry. If entry is of VAR type it will return 1

func (*Entry) SubIndex

func (entry *Entry) SubIndex(subIndex any) (v *Variable, e error)

Subindex returns the Variable at a given subindex. subindex can be a string, int, or uint8. When using a string it will try to find the subindex according to the OD naming.

func (*Entry) Uint16

func (entry *Entry) Uint16(subIndex uint8) (uint16, error)

Uint16 reads data inside of OD as if it were and UNSIGNED16. It returns an error if length is incorrect or read failed.

func (*Entry) Uint32

func (entry *Entry) Uint32(subIndex uint8) (uint32, error)

Uint32 reads data inside of OD as if it were and UNSIGNED32. It returns an error if length is incorrect or read failed.

func (*Entry) Uint64

func (entry *Entry) Uint64(subIndex uint8) (uint64, error)

Uint64 reads data inside of OD as if it were and UNSIGNED64. It returns an error if length is incorrect or read failed.

func (*Entry) Uint8

func (entry *Entry) Uint8(subIndex uint8) (uint8, error)

Uint8 reads data inside of OD as if it were and UNSIGNED8. It returns an error if length is incorrect or read failed.

func (*Entry) WriteExactly added in v1.3.0

func (entry *Entry) WriteExactly(subIndex uint8, b []byte, origin bool) error

Write exactly len(b) bytes to OD at (index,subIndex) origin parameter controls extension usage if exists

type FileObject

type FileObject struct {
	FilePath  string
	WriteMode int
	ReadMode  int
	File      *os.File
}

type ODR

type ODR int8
const (
	ErrPartial      ODR = -1
	ErrNo           ODR = 0
	ErrOutOfMem     ODR = 1
	ErrUnsuppAccess ODR = 2
	ErrWriteOnly    ODR = 3
	ErrReadonly     ODR = 4
	ErrIdxNotExist  ODR = 5
	ErrNoMap        ODR = 6
	ErrMapLen       ODR = 7
	ErrParIncompat  ODR = 8
	ErrDevIncompat  ODR = 9
	ErrHw           ODR = 10
	ErrTypeMismatch ODR = 11
	ErrDataLong     ODR = 12
	ErrDataShort    ODR = 13
	ErrSubNotExist  ODR = 14
	ErrInvalidValue ODR = 15
	ErrValueHigh    ODR = 16
	ErrValueLow     ODR = 17
	ErrMaxLessMin   ODR = 18
	ErrNoRessource  ODR = 19
	ErrGeneral      ODR = 20
	ErrDataTransf   ODR = 21
	ErrDataLocCtrl  ODR = 22
	ErrDataDevState ODR = 23
	ErrOdMissing    ODR = 24
	ErrNoData       ODR = 25
	ErrCount        ODR = 26
)

func (ODR) Error

func (odr ODR) Error() string

type ObjectDictionary

type ObjectDictionary struct {
	Reader io.ReadSeeker
	// contains filtered or unexported fields
}

ObjectDictionary is used for storing all entries of a CANopen node according to CiA 301. This is the internal representation of an EDS file

func Default

func Default() *ObjectDictionary

Return embeded default object dictionary

func DefaultEDSFormatHandler added in v1.3.0

func DefaultEDSFormatHandler(nodeId uint8, formatType uint8, reader io.Reader) (*ObjectDictionary, error)

Default EDS format handler used by this library This can be used as a template to add other format handlers

func NewOD

func NewOD() *ObjectDictionary

func Parse

func Parse(file any, nodeId uint8) (*ObjectDictionary, error)

Parse an EDS file file can be either a path or an *os.File or []byte Other file types could be supported in the future

func (*ObjectDictionary) AddFile

func (od *ObjectDictionary) AddFile(index uint16, indexName string, filePath string, readMode int, writeMode int)

AddFile adds a file like object, of type DOMAIN to OD readMode and writeMode should be given to determine what type of access to the file is allowed e.g. os.O_RDONLY if only reading is allowed

func (*ObjectDictionary) AddRPDO

func (od *ObjectDictionary) AddRPDO(rpdoNb uint16) error

AddRPDO adds an RPDO entry to the OD. This means that an RPDO Communication & Mapping parameter entries are created with the given rpdoNb. This however does not create the corresponding CANopen objects

func (*ObjectDictionary) AddReader

func (od *ObjectDictionary) AddReader(index uint16, indexName string, reader io.Reader)

AddReader adds an io.Reader object, of type DOMAIN to OD

func (*ObjectDictionary) AddSYNC

func (od *ObjectDictionary) AddSYNC()

AddSYNC adds a SYNC entry to the OD. This adds objects 0x1005, 0x1006, 0x1007 & 0x1019 to the OD. By default, SYNC is added with producer disabled and can id of 0x80

func (*ObjectDictionary) AddTPDO

func (od *ObjectDictionary) AddTPDO(tpdoNb uint16) error

AddTPDO adds a TPDO entry to the OD. This means that a TPDO Communication & Mapping parameter entries are created with the given tpdoNb. This however does not create the corresponding CANopen objects

func (*ObjectDictionary) AddVariableList

func (od *ObjectDictionary) AddVariableList(index uint16, name string, varList *VariableList) *Entry

AddVariableList adds an entry of type ARRAY or RECORD depending on VariableList

func (*ObjectDictionary) AddVariableType

func (od *ObjectDictionary) AddVariableType(
	index uint16,
	name string,
	datatype uint8,
	attribute uint8,
	value string,
) (*Entry, error)

AddVariableType adds an entry of type VAR to OD the value should be given as a string with hex representation e.g. 0x22 or 0x55555 If the variable already exists, it will be overwritten

func (*ObjectDictionary) Entries added in v1.3.0

func (od *ObjectDictionary) Entries() map[uint16]*Entry

Entries returns map of indexes and entries

func (*ObjectDictionary) Index

func (od *ObjectDictionary) Index(index any) *Entry

Index returns an OD entry at the specified index. index can either be a string, int or uint16. This method does not return an error (for chaining with Subindex()) but instead returns nil if no corresponding Entry is found.

type Stream

type Stream struct {

	// The actual corresponding data stored inside of OD
	Data []byte
	// This is used to keep track of how much has been written or read.
	// It is typically used for long running transfers i.e. block transfers.
	DataOffset uint32
	// The actual length of the data inside of the OD. This can be different
	// from len(Data) when manipulating data with varying sizes like strings
	// or buffers.
	DataLength uint32
	// A custom object that can be used when using a custom extension
	// see [AddExtension]
	Object any
	// The OD attribute of the entry inside OD. e.g. AttributeSdoR
	Attribute uint8
	// The subindex of this OD entry. For a VAR type this is always 0.
	Subindex uint8
	// contains filtered or unexported fields
}

A Stream object is used for streaming data from / to an OD entry. It is meant to be used inside of a StreamReader or StreamWriter function and provides low level access for defining custom behaviour when reading or writing to an OD entry.

type StreamReader

type StreamReader func(stream *Stream, read []byte, countRead *uint16) error

A StreamReader is a function that reads from a Stream object and updates the countRead and the read slice with the read bytes

type StreamWriter

type StreamWriter func(stream *Stream, to_write []byte, countWritten *uint16) error

A StreamWriter is a function that writes to a Stream object using the to_write slice and updates countWritten

type Streamer

type Streamer struct {
	Stream
	// contains filtered or unexported fields
}

Streamer is created before accessing an OD entry It creates a buffer from OD Data []byte slice and provides a default reader and a default writer

func NewStreamer

func NewStreamer(entry *Entry, subIndex uint8, origin bool) (*Streamer, error)

Create an object streamer for a given od entry + subindex

func (*Streamer) HasAttribute

func (s *Streamer) HasAttribute(attribute uint8) bool

Returns True if has the specific OD attribute

func (*Streamer) Read

func (s *Streamer) Read(b []byte) (n int, err error)

Implements io.Reader

func (*Streamer) Reader

func (s *Streamer) Reader() StreamReader

Return streamer reader

func (*Streamer) ResetData

func (s *Streamer) ResetData(size uint32, offset uint32)

func (*Streamer) SetReader

func (s *Streamer) SetReader(reader StreamReader)

Sets a new streamer reader

func (*Streamer) SetStream

func (s *Streamer) SetStream(stream Stream)

func (*Streamer) SetWriter

func (s *Streamer) SetWriter(writer StreamWriter)

Sets a new streamer writer

func (*Streamer) Write

func (s *Streamer) Write(b []byte) (n int, err error)

Implements io.Writer

func (*Streamer) Writer

func (s *Streamer) Writer() StreamWriter

Return streamer writer

type Variable

type Variable struct {

	// Name of this variable
	Name string
	// The CiA 301 data type of this variable
	DataType byte
	// Attribute contains the access type as well as the mapping
	// information. e.g. AttributeSdoRw | AttributeRpdo
	Attribute uint8
	// StorageLocation has information on which medium is the data
	// stored. Currently this is unused, everything is stored in RAM
	StorageLocation string

	// The subindex for this variable if part of an ARRAY or RECORD
	SubIndex uint8
	// contains filtered or unexported fields
}

Variable is the main data representation for a value stored inside of OD It is used to store a "VAR" or "DOMAIN" object type as well as any sub entry of a "RECORD" or "ARRAY" object type

func NewVariable

func NewVariable(
	subindex uint8,
	name string,
	datatype uint8,
	attribute uint8,
	value string,
) (*Variable, error)

Create a new variable

func NewVariableFromSection

func NewVariableFromSection(
	section *ini.Section,
	name string,
	nodeId uint8,
	index uint16,
	subindex uint8,
) (*Variable, error)

Create variable from section entry

func (*Variable) DataLength

func (variable *Variable) DataLength() uint32

Return number of bytes

func (*Variable) DefaultValue

func (variable *Variable) DefaultValue() []byte

Return default value as byte slice

type VariableList

type VariableList struct {
	Variables []*Variable
	// contains filtered or unexported fields
}

VariableList is the data representation for storing a "RECORD" or "ARRAY" object type

func NewArray

func NewArray(length uint8) *VariableList

func NewRecord

func NewRecord() *VariableList

func (*VariableList) AddSubObject

func (rec *VariableList) AddSubObject(
	subindex uint8,
	name string,
	datatype uint8,
	attribute uint8,
	value string,
) (*Variable, error)

AddSubObject adds a Variable to the VariableList If the VariableList is an ARRAY then the subindex should be identical to the actual placement inside of the array. Otherwise it can be any valid subindex value, and the VariableList will grow accordingly

func (*VariableList) GetSubObject

func (rec *VariableList) GetSubObject(subindex uint8) (*Variable, error)

GetSubObject returns the Variable corresponding to a given subindex if not found, it errors with ODR_SUB_NOT_EXIST

Jump to

Keyboard shortcuts

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