Embedded Networking With CANopen
By Olaf Pfieffer, first published in Circuit Cellar
When it comes to Embedded Networking, Embedded Internetworking seems to be a trend and the only topic around these days. Although the idea of having all our embedded devices accessible via the Internet is tempting, for many embedded applications, Internet access does not solve the real communication requirements often set within the device.
Selecting a Communication Protocol
The requirements for more internal communication come from another trend: adding more intelligence to many machines, appliances and other devices. The side effect of this trend is, that more communication between I/O points or distributed control systems is required. For machine internal communication, TCP/IP is usually a complete overkill, especially if the embedded controllers are on the low end of the performance scale. More cost efficient solutions are serial protocols. Standard serial interfaces like UARTs, I2C or CAN are available on-chip with many microcontrollers in the 8-bit and 16-bit arena, allowing for an easy connection of several nodes.
One of the problems with implementing Embedded Networking solutions based on these serial protocols is, that by themselves they do not have a standardized application layer specifying how the data exchanged is structured and how or when it is exchanged. They usually just cover the Physical and Data Link Layers of the standard communication reference model.
That leaves anybody implementing an Embedded Network with these protocols most likely ending up with a proprietary solution. An internal communication specification has to be generated and most likely all the network nodes are built in-house. Outsourcing is difficult, due to the lack of available communication standards. Without higher layer communication standards it is not easily possible for third parties to build efficient off-the-shelf plug-and-play components.
However, the availability of off-the-shelf components for Embedded Internetworking becomes presently more and more important. In all industries we do feel the constant pressure to further shorten the development time and to cut the development costs.
Instead of developing all components from scratch a manufacturer of any machine could choose off-the-shelf sensors and actuators with a standardized networking interface, allowing the development focus to be on system integration and development of the components that bring the companies true IP into the product.
From all the on-chip communication interfaces available with many microcontrollers these days, CAN is the one that gets us closest to the scenario outlined above. Existing standards based around CAN allow for the availability of off-the-shelf components like generic analog and digital I/O devices and can still provide the network designer with enough freedom to optimize the overall system to best meet the communication requirements of a specific application.
Higher Layer Protocols
A variety of standardized higher layer protocols are available based on CAN. Today, the most significant ones are DeviceNet and CANopen. DeviceNet was developed for factory automation and is strongest in the arena of material handling. Although it offers a very high level of off-the-shelf plug-and-play product availability, there is a price to pay: DeviceNet does leave only minimal room for customization, optimization and other tweaking of the network. For all applications where customization is desired, CANopen is the better alternative.
The basic idea behind CANopen is simple: CANopen standardizes the way the communicated data is structured and exchanged. In addition several Device Profiles for CANopen are standardized and new ones get constantly added. Device Profiles specify the data sets and communication models supported by modules such as Generic I/O, Encoders, Drives, etc. The way the CANopen standards work, it also supports building off-the-shelf modules for plug-and-play system configurations, however it leaves plenty freedom for customizing nodes and communication paths. This allows manufacturers of devices with internal Embedded Networking to take advantage of off-the-shelf components where suitable, and still be able to tweak the system for optimized price/performance of the system to be able to keep a competitive edge.
The Object Dictionary Concept
The core of any CANopen node is the Object Dictionary, a lookup table with a 16-bit index and an 8-bit sub-index. This allows for up to 255 sub-entries at each index. Each entry can be variable in type and length.
All process and communication related information/data is stored as entries in pre-defined locations of the object dictionary. Unused entries do not need to be implemented.
From the network, object dictionary data of any node can be accessed in a point-to-point communication mode by issuing read or write requests to the node's object dictionary. Messages that contain requests or answers to/from the object dictionary are called Service Data Objects (SDO). As both process and configuration data are part of the object dictionary, this communication scheme immediately allows for configuring nodes and/or getting access to the process data.
Point-to-Point? Variable length? More than 8 bytes?
Those of you familiar with CAN probably have these questions after reading the previous paragraphs, as CAN itself does not really support these features - so how does CANopen do it?
Any message sent on CAN is a broadcast to all nodes. Which message IDs get used by which node is not part of the CAN specification and is usually determined by the application.
To allow for peer-to-peer communication, CANopen introduces a node ID that gets embedded into the SDO requests to the object dictionary. Each CANopen module on the network must have a unique node ID in the range from 1 to 127.
The default scenario is, that any node has two CAN identifiers reserved for SDO requests to and SDO replies from the object dictionary. The default CAN ID for the Receive Service Data Object (RSDO - used to send requests to a node) is a base address of 600h plus the node ID number. The ID for the Transmit Service Data Object (TSDO - used by a node to reply to requests) is a base address of 580h plus the node ID number. In this scenario, RSDOs may only be used by one node (usually the master, sometimes a configuration tool), to avoid conflicts/collisions arising from multiple nodes potentially trying to access a specific object dictionary at the same time.
The master or configuration tool can now scan for connected devices by sending 127 RSDO requests for the identity object - one to each potential node. All nodes present will respond with their TSDO containing the identification data from their object dictionary.
In case an object dictionary entry does not fit into one message (CAN has a limit of 8 bytes per message), the data transfer gets automatically fragmented. In this case, the first data byte is used as a control byte for handling the fragmentation. The remaining 7 bytes can be used for data transmitted with each fragment.
Although the object dictionary concept allows for structuring the data that needs to be communicated, there is still something missing: Which entry in the dictionary is used for what? The dictionary is far too big that we could allow the master to take "wild guesses" and simply try to access certain areas of the dictionary to see if they are supported.
The solution is simple: First of all, there are a few mandatory entries that all CANopen nodes must support. These include the identity object with which a node can identify itself and an error object to report a potential error state. Additional entries are specified by device profiles. Device profiles describe all the communication parameters and object dictionary entries that are supported by a certain type of CANopen modules. Such profiles are available for generic I/O modules, encoders and other devices.
A master or configuration tool can read-access the identity object of any slave node using a SDO. As a reply, it receives a SDO with the information about which device profile a module conforms to. Assuming the master knows which object entries are defined for a particular device profile, it now knows which object dictionary entries are supported and can access them directly.
CANopen is open! If an application requires the implementation of non-standardized, manufacturer specific object dictionary entries, then that is not a problem. Adding entries that disable/enable a certain functionality that is not covered by one of the existing device profiles can be implemented to any device, as long as they conform to the structural layout of the object dictionary.
Electronic Data Sheets
Electronic Data Sheets (EDS) offer a standardized way on specifying supported object dictionary entries. Any manufacturer of a CANopen module delivers such a file with the module, which in layout is similar to the ".ini" files used on Microsoft Windows operating systems.
A CANopen master or configuration tool running on a PC with a CAN card can directly load the EDS into its set of recognized devices. Once a device is found on the network, the master or configuration tool will try to find the matching EDS. Once found, all supported object dictionary entries are known by the master / configuration tool.
Figure 2 shows the relation between Device Profiles and Electronic Data Sheets. The Device Profile specifies the minimum entries that need to be supported by a device conforming to the profile. In addition, the EDS might specify objects that are specific to a certain manufacturer or sub-type of modules.
Increased Performance With Process Data Objects
So far, we structured the configuration and process data in a way, that a master could easily access it. From the process point of view, the following operating mode would be possible: polling all inputs, work on the data and then write to all outputs. For most applications, this would not be an efficient communication model. As CAN supports the multi-master concept (any node could send a message at any time, collisions are resolved by ID priority), we can expect a more direct, higher priority access to the process data.
A Process Data Object (PDO) is a "shortcut" to the process data in the object dictionary. Via PDO mapping (all done through object dictionary entries), any dictionary entry can be mapped to data in a PDO, to a maximum of 8 bytes per PDO.
Let's have a look at the example of figure PDO Mapping: A CANopen input node supports 2 digital inputs of 8-bits each and 2 analog inputs of 12-bits each. In conformance with the Device Profile for Generic I/O modules, an object dictionary entry at 6000h stores the 2 digital inputs of 8-bits each and an entry at 6401h stores the 2 analog inputs as 2 words.
The object dictionary entry at 1A00h specifies the PDO mapping - which bits of which object dictionary entries are used in the Transmit PDO 1 (TPDO1), filling the TPDO bit-by-bit. Note that this mapping can really be done on a bit-level. Each entry starts using the first available, free bit in the PDO and occupies as many bits as it requires.
The first sub-index entry at 1A00h maps object 6000h, sub-index 1, 8 bits to the first bits of the TPDO1. The next sub-index entry at 1A00h maps object 6000h, sub-index 1, 8 bits to the next free bits of the TPDO1, and so on. In this example the remaining bits of TPDO1 (data bytes 6-8) remain unmapped and unused.
Which PDOs are predefined and what default mapping is used is also specified in the Device Profile. If the mapping does not change during operation we call that static mapping. Dynamic mapping is the process of re-mapping a PDO during run-time. Obviously, dynamic mapping is more complex and adds more overhead to the PDO processing time.
Now that we have a shortcut to several dictionaries entries in one message, what are our options to trigger a PDO? CANopen supports a total of 4 trigger modes:
- Event driven: If the input device recognizes a change-of-state (COS) on any of its inputs, it updates the data in the object dictionary and the PDO and transmits the PDO. This mode allows for some of the fastest response times.
- Time driven: A PDO can be configured to transmit itself on a fixed time basis, for instance every 50 milliseconds. This mode helps to make the total busload more predictable.
- Polling: Using a regular CAN feature, the remote request frame, a PDO only gets transmitted if the data was specially requested by another node.
- Synchronized: A special mode allowing for a synchronized polling as required by many motion control applications.
When it comes to the communication partners involved, we have a similar arrangement as with the SDOs. The default is that the master is the only node that receives Transmit Process Data Objects (TPDO). And only the master may send Receive Process Data Objects (RPDO) to the slaves. In other words, we ensure that a pre-defined connection set is usable by default, as we assign unique CAN message identifiers to each supported PDO - one unique ID for each TPDO and one for each RPDO.
During the initialization and configuration cycle, the PDO linking can be changed. A master could inform one or multiple output modules that they should directly listen to a specific TPDO of an input module. Again, a TPDO correlates to a unique CAN message identifier. So we basically just inform a node to which message frames it should listen and which ones it can ignore.
Once these new linking settings are made and the network goes into the operational mode, the master would not need to get involved into the process data communication and could focus on other things like network management.