The CANopen Library

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.

Figure 10: CANopen Library levels

Main difference between the Master/Slave and Slave Library is the inclusion of the NMT master functionality in the Master/Slave Library. Table 17 gives an overview about the supported CANopen services in the various configuration levels of the CANopen Library.

CANopen Service

Slave Library

Master/Slave Library

Extra Package

NMT master

 

P

 

NMT slave

P

P

 

SDO client

128

128

 

SDO server

128

128

 

SDO expedited transfer

P

P

 

SDO segmented transfer

P

P

 

SDO block transfer

 

 

P

SDO manager

 

 

P

SDO requesting device

 

 

P

PDO producer

512

512

 

PDO consumer

512

512

 

PDO dynamic mapping

P

P

 

PDO bit-wise mapping

P

P

 

MPDO source mode

 

 

P

MPDO destination mode

 

 

P

Heartbeat producer

P

P

 

Heartbeat consumer

128

128

 

Node Guarding master

 

P

 

Node Guarding slave

P

P

 

life guarding

P

P

 

EMCY producer

P

P

 

EMCY consumer

128

128

 

SYNC producer

 

P

 

SYNC consumer

P

P

 

TIME producer

 

P

 

TIME consumer

P

P

 

nonvolatile storage

P

P

 

NMT Startup manager

 

P

 

Flying Master

 

 

P

Configuration Manager

 

P

 

program download

P

P

 

redundancy support

 

 

P

LED indicators (CiA-303-3)

P

P

 

Safety communication (CiA-304)

 

 

P

LSS services (CiA-305)

P

P

 

CiA-401 framework

 

 

P

Table 17: CANopen service support by the CANopen Library

All multi-line versions can serve one or more physical CAN lines. Each CAN line operates completely independently of the other CAN lines. The network behavior (master/slave) can be different on every CAN line, i.e. each line can be initialized as network master or slave. Interaction between all the individual lines is possible.

Typical applications for multi-line versions are process data logger, human machine interfaces gateways, and devices which work with internal CANopen networks.

If it is necessary to implement additional properties (programmable device services, additional profiles, etc.), the user can enhance the CANopen Library with Extra Packages offered by port GmbH.

With all versions of the CANopen Library it is possible to use environments without an operating system, with single-tasking or multi-tasking systems with only rudimentary resource control mechanisms.

The CANopen Library consists of two main parts:

  • CANopen protocol services according to the CiA standards

  • hardware driver access to the users target hardware (especially CAN controller).

This division offers the following advantages:

  • hardware-independence (CAN controller, micro controller or both) of the main part of the protocol stack: Exchange target hardware while retaining the CANopen functionality by only replacing the hardware driver layer for the new target hardware.

  • comfortable development: Development of the CANopen functionality can take place on easy to treat hardware (i.e. PC with CAN interface) and development environment, afterwards only the device driver for the hardware has to be exchanged.

  • simple extensibility: Extension of the devices functionality without necessary modifications of the driver interface.

  • application with multi-tasking operating system: The division into different processes is already done by the separation into functional modules. Interprocess communication between driver and CANopen layer is already prepared.

The CANopen Library was developed in ANSI-C in order to obtain an easy portability. All hardware and operating system specific functions were separated in extra modules. These modules are the contents of the CANopen Driver Packages.

A further important point is the high scalability of the code size. The user can decide to compile a network master or slave device. Every CANopen service is located in its own module e.g. pdo.c, sdo.c. Therewith the user is able to select only the required modules. Additional it is possible to use compiler-defines in order to select several CANopen Library properties. The advantage of that is that code size grows only with the used CANopen functionalities.

For an easy configuration of the CANopen Library the user is supported by the interactive Industrial Communication Creator.

The CANopen Library contains all CANopen services in respect to CiA-301 and the important services in respect to CiA-302 (Table 17). For all of those many of the features have been implemented. A selection from these many features can be made to fit the developer’s needs.

Nevertheless, only a small subset is necessary to implement fully functional CANopen devices.

The SDO service can be used as both server SDO (SSDO) and client SDO (CSDO). It is possible to define up to 128 of each kind. The SDOs use the expedited transfer for data up to 4 bytes. For data larger than four bytes segmented transfer is used. With this service, data up to 127 bytes, and, if they are marked as domain, up to 231-1 bytes, can be exchanged. Furthermore a program upload and download to a device is possible.

For large data transfer the faster SDO block transfer was implemented. It can be used with or without CRC checksum polynomial, calculated on the run or per table and with variable SDO block size. Additional a fallback to the SDO segmented transfer is implemented.

The user can define up to 512 Transmit PDOs (TPDO) and 512 Receive PDOs (RPDO) in each device. Dynamic PDO mapping is possible and can be done bit-wise. Furthermore the PDO dummy mapping can be used. The PDOs are usable with all transmission types. Cyclic and acyclic, synchronous and asynchronous PDO are implemented. It is possible to change the transmission type during run-time. Additional transmit PDOs can be sent timer-driven. As a further feature it supports remote requests (RTR) also for Basic-CAN controllers. But note that RTR frames are not recommended by the CiA, see CiA-AN-802.

To save PDO identifier resources Multiplexed PDOs can be used in all defined modes (Source Address Mode (SAM) and Destination Address Mode (DAM)).

The EMCY services are available for both producer and consumer. One producer EMCY and up to 128 consumer EMCYs can be defined. Additional the CANopen Library handles the error history in object 1003h.

For SYNC and TIME services one producer and one consumer communication object per device is possible. An exception are devices with multiple CAN lines. They support one server and one client per line.

Heartbeat for producer and consumer is available. If the Heartbeat producer Time is set about object 1017h, Heartbeat starts immediately. If the Heartbeat consumers are active the application receives information when the boot-up message is received, an error occurs, or Heartbeat is restarted.

The Node Guarding protocol is implemented for both master and slave. Each of them checks the guarding time. If the guard time is elapsed, the application receives this information. The guarded slave can monitor if it is guarded within the expected time interval by a Node Guarding master.

Another aspect during the development of the CANopen Library was the convenience for the users. An easy interface for the usage of all services has been implemented. Furthermore checking functions for parameter limits, data sizes and access attributes are available. The communication behavior in respect to CiA-301 is done fully by the CANopen Library i.e. default CAN-ID distribution. The user has only to define his specific application behavior on certain communication events.

For devices which own a nonvolatile memory the save and restore parameter handling can be used.

The further criterion is the security. Many features have been included in the CANopen Library in order to build robust applications.

The application is informed about any CAN errors. Values can be checked before they are written to the object dictionary. Additional a resource security mechanism for multi-tasking systems and an interface for enabling/disabling of interrupts has been prepared.

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.

Implementation Tasks                                                                                   

  • implementation of CANopen application            

  • test of CANopen application

  • integration into the target system (hardware / operating system)

  • test of the whole device             

Integration Tasks

  • integration of devices into a network

  • configuration of devices

  • test of communication behavior for distributed application

  • downloading of configuration data to control the application

port provides a tool-based design flow for implementation and integration. The Industrial Communication Creator by port supports the implementation part, see Figure 11.

Figure 11: design flow for implementation

The Industrial Communication Creator (ICC) is a tool for creating and editing of CANopen device databases. These databases contain information about the device, which describes the interface to the CANopen network. These are in general the parameter, data, control and status information of the device accessible via CAN. These values are organized in the object dictionary. The device databases can be created from ready to use databases, which contain data of the standardized CANopen device profiles. The tasks of the Industrial Communication Creator are configuration of the CANopen Library, managing the device data in a database and generating an object dictionary implementation (C-code), an Electronic Data Sheet (EDS) and a documentation of the implemented objects. This tool takes over error-prone tasks and prevents repetitious jobs. It streamlines the job of the developer considerably.

The generated C-source code of the object dictionary is included by the application modules. This enables direct access to the variables via variable names. Objects can also be accessed via index and sub-index using a generalized API call to the object dictionary. The object dictionary serves as a data interface between the CANopen Library and the application.

A further output of the tool is an Electronic Data Sheet (EDS) according to standard CiA-306. The EDS shall be delivered with every CANopen device. It contains all relevant information about a device, which is used by configuration tools and control applications in order to integrate the device into a CANopen network.

The Industrial Communication Creator also generates a documentation of the implemented objects. Every parameter of the device is described in a table. It is also possible to design own object descriptions. Additional a short descriptive text provides information about the object content and usage. At the start of each CANopen device development this documentation can be used as a part of the device specification. Later it can be included in the user and sales documents.

An enhancement to this are templates. These are source code skeletons containing behavior descriptions.

If the target system is not yet available i.e. hardware is still under development, a cross development can be done. For that purpose a host development environment, using Windows™ or Linux has been developed. Under this system the whole application can be written without any hardware dependence. If no Linux system is available a common standard Windows ™ PC with a PC-CAN card can be used.

After the cross development, the application must be integrated into the target system. This is done by changing the CANopen Library driver modules. No changes are necessary in the application code modules provided that the hardware parts are coded using a hardware abstraction layer (HAL).

Commercial configuration tools and CAN analyzers can be used for the device tests.

Figure 12: CANopen tool set

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).

Figure 13: CANopen Library data flow

The hardware dependent section consists of the components:

  • CAN Driver

  • operation of the CAN controller (interrupt-controlled)

  • receipt of CAN messages and entry in CAN receive buffer

  • reading the transmit buffer and transmitting the CAN messages (interrupt-controlled)

  • monitoring the CAN controller (set error flags on errors)

  • timer interrupt

For all timing related tasks like Heartbeat producing and consuming, PDO inhibit time monitoring and others.

  • supply of a defined timer interval

  • setting appropriate timer flags

The hardware-independent section consists of the:

CANopen Library with FlushMbox

  • evaluation of the error flags of the CAN controller

  • evaluation of the timer flag and call of the timer-dependent services (SYNC, Node Guarding, Heartbeat)

  • calling of appropriate CANopen service routines depending on contents of messages received by CAN receive buffer

  • possibly calling callback functions of the CANopen Library containing application code

  • updating of object directory entries with new data

Callback Functions

  • called from the CANopen Library - application-specific reaction for CANopen services

  • are to be filled out by the user

User Application

  • application behavior

  • initializing CANopen services

  • call CANopen service requests

  • update object directory entries with user data

The structure of the CANopen Library is reflected in the file structure of the program components.

Figure 14: file structure of the CANopen Library

The configuration of the CANopen Library (device type, services, communication mechanisms, etc.) and the hardware characteristics such as CAN controller type, interrupt, operating system, is written to the header file cal_conf.h. It is stored in the application directory because it contains configuration data for all CANopen components of an application.

All hardware drivers (cpu.c, can.c) for the access to the CAN controller and the timer handling are stored in the subdirectory drivers.

The interface between the CANopen Library and the application consists of the callback functions and the object dictionary. The callback functions are supplied in the files usr_301.c, usr_302.c, usr_303.c, usr_30x.c..., and nmtslave.c and have to be filled out application-specific by the application programmer. The object dictionary contains data which are either application-specific or CANopen-specific. These interface functions belong to the application and are stored in the application directory. All CANopen Library files are stored in the directory path canopen/source.

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.

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

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.h determine 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:

typedef struct {    char val[8]; } UNSIGNED64;

The initialization in this case is done by the following macro:

For all compilers providing this data type the initialization is done by:

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