ObjectDictionary
Every CANopen node has an ObjectDictionary. An ObjectDictionary consists of Entries with a given index between 0 and 0xFFFF. An entry may also have a subindex for some specific CANopen types like RECORD or ARRAY types. This subindex must be between 0 and 0xFF. All of this information is stored inside of an EDS file as defined by CiA. This library can parse a standard EDS file and create the corresponding CANopen objects (SDO, NMT, etc...).
Basic Usage
To create an ObjectDictionary directly :
import "github.com/samsamfire/gocanopen/pkg/od"
odict := od.Parse("../testdata/base.eds", 0x20) // parse EDS for node id 0x20
odict := od.Parse("../testdata/base.eds", 0x20)
odict.Index(0x201B) // get entry index by value
odict.Index("UNSIGNED64 value") // accessing with the actual name is also possible
odict.Index(0x201B).SubIndex(0) // returns the associated Variable object (for VAR types, subindex is always 0)
odict.Index(0x1018).SubIndex(1) // access sub-object of array
It is also possible to create new dictionary entries dynamically :
odict.AddVariableType(index, indexName, od.DOMAIN, od.AttributeSdoRw, "") // add a DOMAIN entry, and returns it
odict.AddVariableType(0x2500, "a number", od.UNSIGNED32, od.AttributeSdoRw, "0x1000") // add an UNSIGNED32 entry, readable and writable
record := od.NewRecord()
record.AddSubObject(0, "sub0", od.UNSIGNED8, od.AttributeSdoRw, "0x11")
odict.AddVariableList(0x3030, "record", record) // add a RECORD entry
Some more complex objects can be created dynamically, currently only a few are supported :
odict := od.Parse("../testdata/base.eds", 0x20)
odict.AddRPDO(1) // adds an rpdo object to EDS. i.e. new communication param at 0x1400 and mapping param at 0x1600
odict.AddTPDO(1) // adds a tpdo object to EDS. i.e. new communication param at 0x1800 and mapping param at 0x1A00
odict.AddSYNC() // adds sync object as well as extensions (1005,1006,1007,1019)
A default CANopen EDS is embedded inside of this package. It can be useful for testing purposes, and can be used like so :
Exporting
Exporting OD to an EDS file is also possible. OD can be exported with default or current values.
Special entries
CiA 301 defines a certain number of CANopen communication specific objects inside the object dictionary. These objects are inside of the Communication Profile Area and range between 0x1000 - 0x1FFF. Some of them are mandatory and others are optional. The following table lists the available objects, and the ones that are currently implemented in this stack.
Index | Name | Implemented |
---|---|---|
1000 | device type | yes |
1001 | error register | yes |
1003 | manufacturer status register | yes |
1005 | COB-ID SYNC | yes |
1006 | communication cycle period | yes |
1007 | synchronous window length | yes |
1008 | manufacturer device name | yes |
1009 | manufacturer hardware version | yes |
100A | manufacturer software version | yes |
100C | gard time | no |
100D | life time factor | no |
1010 | store parameters | no |
1011 | restore default parameters | no |
1012 | COB-ID TIME | yes |
1013 | high resolution time stamp | yes |
1014 | COB-ID EMCY | yes |
1015 | Inhibit Time EMCY | yes |
1016 | Consumer heartbeat time | yes |
1017 | Producer heartbeat time | yes |
1018 | Identity Object | yes |
1021 | Store EDS | yes |
1022 | Storage Format | yes |
Check configuration on how to access these entries.
These entries are different than regular OD entries as they use special extensions that can perform various operations on the running CANopen node. You can define your own CANopen extensions for this, you need to create two functions :
- An od.StreamReader that will be called on entry read access
- An od.StreamWriter that will be called on entry write access
The default implementations, i.e. for regular reading and writing are od.ReadEntryDefault and od.WriteEntryDefault.
odict := od.Parse("../testdata/base.eds", 0x20)
entry := odict.AddVariableType(index, indexName, od.DOMAIN, od.AttributeSdoRw, "")
entry.AddExtension(someObject,od.ReadEntryDefault,od.WriteEntryDefault)
Some pre-made extensions are available :