CANopen Library concept
The CANopen Library is offered at different configuration levels. All configuration levels are built upon one another. The functionality of the lower level is contained in the higher one.
...
The last criterion is the independence of the CANopen Library of the underlying hardware and operating system. It is easy to adapt the prepared driver modules to any target system. A further aim is to support a wide range of standard hardware products like CAN cards for PCs or micro controller modules.
Design flow
The CANopen Library is only one component in the design flow of the CANopen system development. The development of CANopen systems consists of the two tasks, implementation and integration. In the context of the CANopen Library the implementation task must always be done.
...
The next step is the device integration into a CANopen network, creating a distributed application. It is very convenient to use a configuration tool. This tool loads the EDS-files of the participants (devices). Then the communication channels can be built by distribution of CAN-IDs and PDO mapping. Further the application parameters can be changed. Afterwards a so-called Device Configuration File (DCF) is stored. The configuration data can be downloaded onto a control application, which configures the network after each boot-up. Afterwards the configuration tool is no longer necessary within the CANopen network, it will only fulfill maintenance requirements. A summary of the complete tool-set is shown in Figure 12.
CANopen Library structure
The structure of the CANopen Library is shown in Figure 13. The CANopen Library consists of a hardware-dependent section and a hardware-independent section. The two sections are joined by message buffers (CAN receive and CAN transmit buffer).
...
The structure is created this way, so that an update of the entire CANopen Library files is possible without modification of the application-specific code.
Object dictionary
The object dictionary is the data interface between the user’s application and the CANopen Library. It contains all variables that are necessary for the CANopen services and the application-specific variables that shall be accessible over the network. The implementation of the object dictionary by port consists of an array of element headers for each used index, see Figure 15.
...
Figure 15: structure of object dictionary list
Each element header contains five entries:
object dictionary index number,
number of elements for this object dictionary entry (number of sub-indices),
pointer to the data variable,
pointer to the description structure for the object
pointer to callback function for the object
The data object can be a simple variable, an array, a record or a domain entry and can be created with the object dictionary or by the user application (Figure 16).
Figure 16: object dictionary implementation
The description for each variable is a C-language record. It contains entries for the value ranges, the default value, the size, read/write permission flags, numeric and domain identification and PDO mapping permission.
With the multi-line CANopen Library version an object dictionary is available at each line. In this case all object dictionaries will be managed by an object dictionary manager. This manager is an array of pointers to the implemented object dictionaries (Figure 17).
...
Figure 17: structure of multi-line object dictionary
It is possible to define an interface for custom variables, structures and arrays. The index is the logical reference to one of these data containers. The elements of structures and arrays are reached via the sub-index. For simple variables the sub-index is always 0. If the size of the structures or arrays is bigger than 255 bytes (limit of sub-index), the user must split them. This means more than one index is needed to describe the structure/array within the object dictionary. The elements of the object dictionary have the type LIST_ELEMENT_T. An array of this type, sorted by the index, is the object dictionary. The description of the variables is an array of the type VALUE_DESC_T. Each array entry describes the properties of the corresponding sub-index.
Code Block | ||
---|---|---|
| ||
typedef struct {
UNSIGNED8 *pObj;
VALUE_DESC_T *pValDesc;
UNSIGNED16 index;
UNSIGNED8 numOfElem;
#ifdef CO_CONFIG_ENABLE_OBJ_CALLBACK
CO_OBJ_CB_T pObjCallback; /* obj function pointer */
#endif /* CO_CONFIG_ENABLE_OBJ_CALLBACK */
} LIST_ELEMENT_T; |
element name from LIST_ELEMENT_T | description |
index | index of the variable in the object dictionary |
numOfElem | number of elements of the variable |
pObj | pointer to the variable (array, structure, variable) |
pValDesc | pointer to an array of corresponding value descriptions |
pObjCallback | pointer to a callback function corresponding to the object |
Table 18: structure of object dictionary entry
Code Block | ||
---|---|---|
| ||
typedef struct {
UNSIGNED8 *pDefaultVal;
#ifdef CONFIG_LIMITS_CHECK
LIMIT_U8_T *pLimits;
#endif
UNSIGNED8 varType;
UNSIGNED16 attribute;
} VALUE_DESC_T;
|
element name from VALUE_DESC_T | description |
pDefaultVal | pointer to the default value of the variable, it will be used to initialize the variable after a reset (hard reset or communication reset), it depends on the variable type (see varType) |
pLimits | pointer to the lower and upper limits of the variable value, it depends on the variable type (see varType) |
varType | type of variable (Table 21) |
attribute | attributes of value (Table 20) |
Table 19: object’s properties description
attribute bit | property | description (bit value = 1) |
CO_MAP_PERM | PDO mapping permission | PDO mapping for this object is allowed |
CO_WRITE_PERM | write permission | object is writable |
CO_READ_PERM | read permission | object is readable |
CO_CONST_PERM | const value | object is constant and stored at ROM |
CO_SHORT_ARRAY_DESC | short description | description of sub-index 1 is also used for all higher sub-indices because sub-indices 1-n are identical |
CO_OBJ_ATTR_SAVE | nonvolatile storage marker | if this attribute is set, the object shall be stored in nonvolatile memory |
Table 20: attributes for object description
variable type | data type |
CO_TYPEDESC_BOOL | BOOL |
CO_TYPEDESC_UNSIGNED8 | unsigned char (8 bit) |
CO_TYPEDESC_UNSIGNED16 | unsigned int (16 bit) |
CO_TYPEDESC_UNSIGNED32 | unsigned long (32 bit) |
CO_TYPEDESC_UNSIGNED64 | unsigned long long (64 bit) |
CO_TYPEDESC_INTEGER8 | signed char (8 bit) |
CO_TYPEDESC_INTEGER16 | signed int (16 bit) |
CO_TYPEDESC_INTEGER32 | signed long (32 bit) |
CO_TYPEDESC_INTEGER64 | signed long long (64 bit) |
CO_TYPEDESC_VISSTRING | visible string |
CO_TYPEDESC_OCTETSTRING | octet string |
CO_TYPEDESC_DOMAIN | domain |
CO_TYPEDESC_REAL32 | real (32 bit) |
Table 21: variable types for object description
The pointers to the default value and to the limit structure are always pointers to the real data type of the variable and must be casted at VALUE_DESC_T type.
The CANopen Library does not interpret float values except if limit check is enabled. Please ensure that the initialization values are in the right order.
CANopen Library configuration
Configuration header
The CANopen Library can be used for many different hardware and compiler platforms. Furthermore the CANopen Library can be configured to reduce code size and run faster. Due to the complexity of this process, the design tool (available for both Microsoft Windows and UNIX-machines) will automate the creation of the configuration file cal_conf.h.
The entries of the file cal_conf.hdetermine the kind of compilation. All configuration compiler-define-directives used in that file have the prefix CONFIG_ or CO_CONFIG_.
The user can compile the CANopen Library code for a CANopen network master or for a CANopen slave application.
For the multi-line version the number of CAN lines can be configured. If the multi-line functionality is switched off no functions will use the line select function parameter canLine. In this way the multiline version of the CANopen Library can be used for single-line systems without the multi-line overhead.
Further it is possible to reduce the code size by selecting parts of the code by compiler #define directives. Many CANopen services can additionally be separated into client/consumer or into server/producer functionality. If the user needs only one functionality, he only has to define one of these e.g. CONFIG_SDO_SERVER.
Further the size of the CAN message buffer can be adjusted and the usage of FullCAN properties in hardware can be enabled, if the CAN controller is a Full-CAN type.
For compilers (processors) which do not support a byte alignment of data in the memory, an alignment definition CONFIG_ALIGNMENT has to be set in order to ensure a correct access to structures and arrays of the object dictionary.
Manual edits of the cal_conf.h are overwritten by the next code generation of the design tool.
Coding of 64-bit values
Some entries at the object dictionary are of type UNSIGNED64. If a compiler does not provide this data type, 64-bit variables can be simulated:
Code Block | ||
---|---|---|
| ||
typedef struct
{
char val[8];
} UNSIGNED64; |
The initialization in this case is done by the following macro:
Code Block | ||
---|---|---|
| ||
#define SET_U64(b1, b2, b3, b4, b5, b6, b7, b8) \
{ b8, b7, b6, b5, b4, b3, b2, b1 }; |
For all compilers providing this data type the initialization is done by:
Code Block | ||
---|---|---|
| ||
#define SET_U64(b1, b2, b3, b4, b5, b6, b7, b8) \
{ b1<<56|b2<<48|b3<<40|b4<<32|b5<<24|b6<<16|b7<<8|b8 }; |
CANopen Library return value
Many CANopen Library functions return a value of enumeration type RET_T to indicate the success or failure of the function execution. The values are described in /Ref_Man/. The enumeration type is defined in file co_type.h.
Additional parameter
Many CANopen Library functions have an additional parameter as a final argument. The meaning of the additional parameter depends on the used configuration of the CANopen Library, see Table 22.
configuration of the CANopen Library | meaning of additional parameter | ||
model | line feature | type of variables | |
Master/Slave | single-line | global | additional parameter does not exist |
Slave | |||
Master/Slave | multi-line | global | number of CAN line |
Slave | |||
Master/Slave | single-line | non-global | pointer to local object dictionary and CANopen Library variables |
Slave |
Table 22: additional parameter of CANopen Library functions