-
Notifications
You must be signed in to change notification settings - Fork 3
/
md_tutorial_2README.html
253 lines (249 loc) · 19.7 KB
/
md_tutorial_2README.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.11.0"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>CANopenDemo: CANopenNode Tutorial</title>
<link rel="icon" href="CANopenNode.png" type="image/x-icon" />
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<script type="text/javascript" src="clipboard.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="cookie.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectlogo"><img alt="Logo" src="CANopenNode.png"/></td>
<td id="projectalign">
<div id="projectname">CANopenDemo
</div>
<div id="projectbrief">CANopenNode demo, tutorial and testing</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.11.0 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search/",'.html');
/* @license-end */
</script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */
$(function() { codefold.init(0); });
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */
$(function() {
initMenu('',true,false,'search.php','Search',false);
$(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */
$(function(){ initResizable(false); });
/* @license-end */
</script>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<div id="MSearchResults">
<div class="SRPage">
<div id="SRIndex">
<div id="SRResults"></div>
<div class="SRStatus" id="Loading">Loading...</div>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
</div>
</div>
</div>
</div>
</div><!-- top -->
<div id="doc-content">
<div><div class="header">
<div class="headertitle"><div class="title">CANopenNode Tutorial</div></div>
</div><!--header-->
<div class="contents">
<div class="textblock"><h1><a class="anchor" id="autotoc_md92"></a>
CANopen</h1>
<p>Before starting tutorial with CANopenNode you should be familiar with the CANopen. CANopen is the internationally standardized CAN-based higher-layer protocol for embedded control system. It is specified by CiA301 (or by EN 50325-4) standard. It can be freely downloaded from <a href="https://can-cia.org/groups/specifications/">https://can-cia.org/groups/specifications/</a>. Some information about CAN and CANopen can be found on <a href="https://can-cia.org/can-knowledge/">https://can-cia.org/can-knowledge/</a> website. Very efficient way to get familiar with CANopen is by reading a book, for example <a href="https://can-newsletter.org/engineering/engineering-miscellaneous/nr_e_cia_can_books_3-2008_emb_can_pfeiffer_120529">Embedded Networking with CAN and CANopen</a>.</p>
<p>CANopen itself is not a typical master/slave protocol (or commander/responder protocol in the new terminology). It is more like producer/consumer protocol. It is also possible to operate CANopen network without a commander. For example, pre-configured process data objects (PDO) are transmitted from producers. Each PDO may be consumed by multiple nodes. Other useful CANopen functionalities of each CANopen device are also: Heartbeat producer and consumer, Emergency producer, Sync producer or consumer, Time producer or consumer, SDO server (Service data objects - serve variables from Object dictionary), NMT slave (network management - start or stop parts of communication), LSS slave (configuration of Node-Id and Bitrate).</p>
<p>CANopen network usually has one device with commander functionalities for network configuration, such as: NMT master, LSS master, SDO client, Emergency consumer. Commander functionalities in CANopenNode are implemented with Ascii command line interface according to standard CiA309-3.</p>
<h1><a class="anchor" id="autotoc_md93"></a>
Environment</h1>
<p>The only requirement for this tutorial is computer with Linux. Examples will run from several windows of Command Line Interface. There are many other CANopen tools available for configuration and working with CANopen network. Some of them have GUI, some can import electronic data sheet of particular device, etc. Here we will use CLI tools from CANopenNode for most basic demonstration of CANopen principles.</p>
<h2><a class="anchor" id="autotoc_md94"></a>
CANopen devices</h2>
<p>Two CANopen devices will be used, both based on CANopenNode:</p><ol type="1">
<li><code>canopend</code> from CANopenLinux repository will be a commander device with CANopen ASCII command interface. It will run with CANopen NodeId = 1. Application <code>cocomm</code> will be used for sending commands to <code>canopend</code>. For information on compiling and installing those two applications see CANopenLinux repository.</li>
<li>CANopen <a class="el" href="md_demo_2README.html">demoDevice</a> from demo directory. It will run with CANopen NodeId = 4. It can use any target platform listed there. Prepare the device according to the instructions.</li>
</ol>
<h2><a class="anchor" id="autotoc_md95"></a>
CANopen network</h2>
<p>If you don't have CAN interface and both devices are Linux based, then virtual CAN interface can be used, which runs internally. Otherwise connect CANopen devices with wires: </p><pre class="fragment">+-------------------+ +-------------------+
| Node-id = 1 | | Node-id = 4 |
| | | |
| canopend | | demoDevice |
+-------------------+ +-------------------+
| CAN + transceiver | | CAN + transceiver |
+-----+---+---+-----+ +-----+---+---+-----+
| | | | | |
| | | can-hi | | |
+-------|---+---------------------------------------------|---+-----+
120Ω | | can-lo | | 120Ω
+-------+-------------------------------------------------+---------+
| gnd |
+-------------------------------------------------+
</pre> <h3><a class="anchor" id="autotoc_md96"></a>
Start CANopen network</h3>
<p>Start CAN interface in Linux according to instructions in the CANopenLinux repository or according to specifications of your CAN interface. By default network runs with 250kbps.</p>
<p>Alternatively enable virtual CAN interface (named <code>can0</code>): </p><pre class="fragment">sudo modprobe vcan
sudo ip link add dev can0 type vcan
sudo ip link set up can0
</pre> <h2><a class="anchor" id="autotoc_md97"></a>
candump</h2>
<p>Run a tool, which will display raw CAN messages, for example <code>candump</code> from <code>can-utils</code> package. Run from own terminal window: </p><pre class="fragment">sudo apt-get install can-utils
candump -td can0
</pre> <h2><a class="anchor" id="autotoc_md98"></a>
Start devices</h2>
<p>This is an example, devices may also be started different way.</p>
<h3><a class="anchor" id="autotoc_md99"></a>
canopend</h3>
<p>Use own terminal window: </p><pre class="fragment">cd CANopenLinux
make
rm *.persist
./canopend can0 -i 1 -c "local-/tmp/CO_command_socket"
</pre> <h3><a class="anchor" id="autotoc_md100"></a>
demoDevice</h3>
<p>If demoDevice is not Linux device skip this chapter and run it as necessary. If it is a Linux device, then run in own terminal window: </p><pre class="fragment">cd demo
make
rm *.persist
./demoLinuxDevice can0
</pre><p> As set by application, startup Node-ID for demoDevice is 4. It can be changed by LSS.</p>
<h2><a class="anchor" id="autotoc_md101"></a>
cocomm</h2>
<p>Make sure, utility <a class="elRef" href="CANopenLinux/md_cocomm_2README.html">cocomm</a> is working properly. Use another terminal window and display help (help string is received from canopend): </p><pre class="fragment">cocomm "help"
</pre><h1><a class="anchor" id="autotoc_md102"></a>
First steps</h1>
<p>candump shows the following raw CAN messages: </p><pre class="fragment">can0 701 [1] 00 # Boot-up message from canopend
can0 081 [8] 00 50 01 2F 14 00 00 00 # Emergency from canopend
can0 704 [1] 00 # Boot-up message from demoDevice
can0 084 [8] 00 50 01 2F 74 00 00 00 # Emergency from demoDevice
</pre><p> Second column is 11-bit standard CAN identifier. See <a class="elRef" href="CANopenNode/group__CO__Default__CAN__ID__t.html">Default CANopen identifiers</a> for information, how it is used in CANopen. Bootup message has the same 11-bit CAN ID as Heartbeat: 0x700 + CANopen Node-ID.</p>
<p>There are no more messages from CANopen devices, because nothing is configured.</p>
<h2><a class="anchor" id="autotoc_md103"></a>
Emergency messages</h2>
<p>Both devices sends Emergency message after the boot-up. Contents of emergency message is:</p><ul>
<li>bytes 0..1: <a class="elRef" href="CANopenNode/group__CO__EM__errorCode__t.html">CANopen Error code</a>, in our case 0x5000 (Device Hardware) (mind that CANopen is little endian).</li>
<li>byte 2: <a class="elRef" href="CANopenNode/group__CO__errorRegister__t.html">CANopen Error register</a>, in our case 0x01 (generic error).</li>
<li>byte 3: Index of error condition from <a class="elRef" href="CANopenNode/group__CO__EM__errorStatusBits__t.html">Error status bits</a>, in our case 0x2F (CO_EM_NON_VOLATILE_MEMORY - Error with access to non volatile device memory).</li>
<li>bytes 4..7: Additional informative argument, in our case 0x00000014 or 0x00000074.</li>
</ul>
<p>Emergency messages are triggered internally by <a class="elRef" href="CANopenNode/group__CO__Emergency.html#gab66d4a6daa5f7492704b56a46b135f71">CO_errorReport()</a> function. You may seek inside source code for <code>CO_EM_NON_VOLATILE_MEMORY</code> to find source of the emergency message.</p>
<p><code>CO_EM_NON_VOLATILE_MEMORY</code> is generic, critical error, which by default sets the CANopen Error Register. If error register is different than zero, then node may be prohibited to enter NMT operational state and PDOs can not be exchanged with it.</p>
<h2><a class="anchor" id="autotoc_md104"></a>
Basic SDO communication and Heartbeat message</h2>
<p>A SDO (Service Data Object) is providing direct access to object entries of a CANopen device's object dictionary. As these object entries may contain data of arbitrary size and data type. SDOs may be used to transfer multiple data sets (each containing an arbitrary large block of data) from a client to a server and vice versa. The client shall control via a multiplexer (index and sub-index of the object dictionary) which data set shall be transferred. The content of the data set is defined within the object dictionary.</p>
<p>See <a class="el" href="md_demo_2demoDevice.html">demo/demoDevice.md</a> for CANopen device documentation of demoDevice with description of all parameters accessible via SDO.</p>
<p>First configure parameter 0x1017 - Producer heartbeat time. Read current value on demoDevice: </p><pre class="fragment">cocomm "4 read 0x1017 0 u16"
</pre><p> Command requested SDO read from device with CANopen Node-ID = 4. Parameter 0x1017 is accessed at sub-index = 0. Data should be displayed as 16bit unsigned integer. Command returns value <code>0</code>, which means, heartbeat producer is disabled.</p>
<p>candump shows this communication cycle: </p><pre class="fragment">can0 604 [8] 40 17 10 00 00 00 00 00
can0 584 [8] 4B 17 10 00 00 00 00 00
</pre><p> First message is client request. In our case client is canopend device, to which cocomm establishes a connection. Second message is server response from demoDevice. It is not necessary to know the details of SDO messages, for more information see <a class="elRef" href="CANopenNode/group__CO__SDOserver.html#ga0b0e614dadcc1c005185b8bc9a7fec11">CO_SDO_state_t</a>.</p>
<p>For more information on cocomm commands type: </p><pre class="fragment">cocomm "help"
cocomm "help datatype"
</pre><p> Now set parameter 0x1017 to 1000 milliseconds on both devices: </p><pre class="fragment">cocomm "1 write 0x1017 0 u16 1000"
cocomm "4 write 0x1017 0 u16 1000"
</pre><p> candump shows: </p><pre class="fragment">can0 701 [1] 7F
can0 604 [8] 2B 17 10 00 E8 03 00 00
can0 584 [8] 60 17 10 00 00 00 00 00
can0 704 [1] 7F
can0 701 [1] 7F
</pre><p> Now there are heartbeat messages from each device in one second intervals. 7F means device is in NMT pre-operational state, see <a class="elRef" href="CANopenNode/group__CO__NMT__Heartbeat.html#ga1e8c2a6c0fd4a33183503d25a7c6d744">CO_NMT_internalState_t</a>. There is also one SDO communication cycle with demoDevice. SDO communication cycle with canopend is not visible, because it executes internally.</p>
<h2><a class="anchor" id="autotoc_md105"></a>
Network management - NMT</h2>
<p>CANopen NMT messages have highest priority and are sent from NMT master, canopend in our case. They can be sent to specific node or all nodes. They can reset device, communication or set internal state of the remote device to operational, pre-operational(PDO disabled) or stopped(only heartbeat producer and NMT consumer enabled). </p><pre class="fragment">cocomm "4 reset communication"
cocomm "4 start"
cocomm "0 reset node"
</pre><p> Observe CAN messages in candump. Second command does not work, because there is critical emergency which sets error register. Third command resets our devices, so go to their terminal windows and restart them.</p>
<h2><a class="anchor" id="autotoc_md106"></a>
Non-volatile storage</h2>
<p>Emergency message, error register and NMT pre-operational state have source in uninitialized non-volatile storage. Objects 0x1010 and 0x1011 are used to store and restore the data, usually from CANopen Object Dictionary.</p>
<p>Restore all non-volatile storage on both devices and reset them: </p><pre class="fragment">cocomm "1 w 0x1011 1 vs load"
cocomm "4 w 0x1011 1 vs load"
cocomm "0 reset node"
# re-run devices in their terminals
</pre><p> candump is now without emergency messages and there are two additional PDO messages, because devices are now in NMT operational state. Heartbeat messages are gone: </p><pre class="fragment">can0 701 [1] 00
can0 704 [1] 00
can0 184 [2] 00 00
can0 284 [8] 00 00 00 00 00 00 00 00
</pre><p> Configure heartbeats, observe candump, then reset and re-run devices. Heartbeat messages are gone again: </p><pre class="fragment">cocomm "1 write 0x1017 0 u16 1000"
cocomm "4 write 0x1017 0 u16 1000"
cocomm "0 reset node"
# re-run devices in their terminals
</pre><p> Configure heartbeats, store all parameters, then reset and re-run devices. Heartbeat configuration has been stored, no more future configuration is necessary, devices are autonomous: </p><pre class="fragment">cocomm "1 write 0x1017 0 u16 1000"
cocomm "4 write 0x1017 0 u16 1000"
cocomm "1 w 0x1010 1 vs save"
cocomm "4 w 0x1010 1 vs save"
cocomm "0 reset node"
# re-run devices in their terminals
</pre><p> Parameters from CANopen Object Dictionary are sorted into several storage groups. This is configured by Object dictionary editor. See <a class="el" href="md_demo_2demoDevice.html">demo/demoDevice.md</a> for storage group for each OD object.</p>
<p>Storage groups are configured for storage with array of <a class="elRef" href="CANopenNode/structCO__storage__entry__t.html">CO_storage_entry_t</a> objects. (For initialization in Linux devices see CANopenLinux/CO_main_basic.c and demo/linux/CO_driver_custom.h files.)</p>
<h3><a class="anchor" id="autotoc_md107"></a>
Default storage groups for demoDevice</h3>
<ul>
<li><code>RAM</code> is never stored</li>
<li><code>PERSITS_COMM</code> is used for store-able communication parameters. Group is assigned to sub-index 2 of the 0x1010 and 0x1011 objects.</li>
<li><code>PERSIST_APP</code> is demoDevice specific and is used for its store-able parameters. Group is assigned to sub-index 5 of the 0x1010 and 0x1011 objects.</li>
<li><code>PERSIST_APP_AUTO</code> is demoDevice specific and is used for its parameters, which are stored automatically. Group is assigned to sub-index 6 of the 0x1010 and 0x1011 objects.</li>
<li>Internal data block used by mainline, which is stored automatically. Block is assigned to sub-index 4 of the 0x1010 and 0x1011 objects.</li>
<li>Sub-index 1 of the 0x1010 and 0x1011 stores/restores all parameters.</li>
</ul>
<h1><a class="anchor" id="autotoc_md108"></a>
Next steps</h1>
<ul>
<li><a class="el" href="md_tutorial_2LSS.html">tutorial/LSS.md</a> - Assigning Node-ID or CAN bitrate to devices, which support LSS configuration.</li>
<li><a class="el" href="md_tutorial_2SDO.html">tutorial/SDO.md</a> - Further SDO access to the <a class="el" href="md_demo_2README.html">demoDevice</a> parameters.</li>
<li><a class="el" href="md_tutorial_2PDO.html">tutorial/PDO.md</a> - Demonstration of Process Data Objects</li>
<li><a class="el" href="md_test_2README.html">test/README.md</a> - Automatic tests on demoDevice in running CANopen network.</li>
<li>Learn other CANopen functionalities like Heartbeat consumer, Time stamp, Sync, etc. Read CiA301 standard, CANopen book or <a class="el" href="md_demo_2demoDevice.html">demo/demoDevice.md</a>.</li>
<li>Experiment with <a class="el" href="md_demo_2README.html">demoDevice</a> on available platforms or create your own. Create own Object Dictionary.</li>
<li>For own CANopen device with own microcontroller, see <code>CANopenNode/doc/deviceSupport.md</code>.</li>
<li>Search many very useful and high quality specifications for different <a href="http://www.can-cia.org/standardization/specifications/">device profiles</a>, some of them are public and free to download, for example <a href="https://www.can-cia.org/can-knowledge/canopen/cia401/">CiA401</a>.</li>
<li>There are many other CANopen tools, both commercial and free, for example <a href="https://github.com/christiansandberg/canopen">CANopen for Python</a>.</li>
<li>Keep control, safety and responsibility on your devices.</li>
<li>Read the <a href="https://can-newsletter.org/">CAN Newsletter</a>. </li>
</ul>
</div></div><!-- contents -->
</div><!-- PageDoc -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.11.0
</small></address>
</div><!-- doc-content -->
</body>
</html>