IgH EtherCAT Master  1.6.9
pdo.c
Go to the documentation of this file.
1/*****************************************************************************
2 *
3 * Copyright (C) 2006-2008 Florian Pose, Ingenieurgemeinschaft IgH
4 *
5 * This file is part of the IgH EtherCAT Master.
6 *
7 * The IgH EtherCAT Master is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License version 2, as
9 * published by the Free Software Foundation.
10 *
11 * The IgH EtherCAT Master is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
14 * Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with the IgH EtherCAT Master; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 *
20 ****************************************************************************/
21
26
27/****************************************************************************/
28
29#include <linux/slab.h>
30#include <linux/err.h>
31
32#include "pdo.h"
33
34/****************************************************************************/
35
39 ec_pdo_t *pdo
40 )
41{
42 pdo->sync_index = -1; // not assigned
43 pdo->name = NULL;
44 INIT_LIST_HEAD(&pdo->entries);
45}
46
47/****************************************************************************/
48
55 ec_pdo_t *pdo,
56 const ec_pdo_t *other_pdo
57 )
58{
59 int ret = 0;
60
61 pdo->index = other_pdo->index;
62 pdo->sync_index = other_pdo->sync_index;
63 pdo->name = NULL;
64 INIT_LIST_HEAD(&pdo->entries);
65
66 ret = ec_pdo_set_name(pdo, other_pdo->name);
67 if (ret < 0)
68 goto out_return;
69
70 ret = ec_pdo_copy_entries(pdo, other_pdo);
71 if (ret < 0)
72 goto out_clear;
73
74 return 0;
75
76out_clear:
77 ec_pdo_clear(pdo);
78out_return:
79 return ret;
80}
81
82/****************************************************************************/
83
87{
88 if (pdo->name)
89 kfree(pdo->name);
90
92}
93
94/****************************************************************************/
95
99{
100 ec_pdo_entry_t *entry, *next;
101
102 // free all PDO entries
103 list_for_each_entry_safe(entry, next, &pdo->entries, list) {
104 list_del(&entry->list);
105 ec_pdo_entry_clear(entry);
106 kfree(entry);
107 }
108}
109
110/****************************************************************************/
111
118 ec_pdo_t *pdo,
119 const char *name
120 )
121{
122 unsigned int len;
123
124 if (pdo->name && name && !strcmp(pdo->name, name))
125 return 0;
126
127 if (pdo->name)
128 kfree(pdo->name);
129
130 if (name && (len = strlen(name))) {
131 if (!(pdo->name = (char *) kmalloc(len + 1, GFP_KERNEL))) {
132 EC_ERR("Failed to allocate PDO name.\n");
133 return -ENOMEM;
134 }
135 memcpy(pdo->name, name, len + 1);
136 } else {
137 pdo->name = NULL;
138 }
139
140 return 0;
141}
142
143/****************************************************************************/
144
150 ec_pdo_t *pdo,
151 uint16_t index,
152 uint8_t subindex,
153 uint8_t bit_length
154 )
155{
156 ec_pdo_entry_t *entry;
157
158 if (!(entry = kmalloc(sizeof(ec_pdo_entry_t), GFP_KERNEL))) {
159 EC_ERR("Failed to allocate memory for PDO entry.\n");
160 return ERR_PTR(-ENOMEM);
161 }
162
163 ec_pdo_entry_init(entry);
164 entry->index = index;
165 entry->subindex = subindex;
166 entry->bit_length = bit_length;
167 list_add_tail(&entry->list, &pdo->entries);
168 return entry;
169}
170
171/****************************************************************************/
172
179 ec_pdo_t *pdo,
180 const ec_pdo_t *other
181 )
182{
183 ec_pdo_entry_t *entry, *other_entry;
184 int ret;
185
187
188 list_for_each_entry(other_entry, &other->entries, list) {
189 if (!(entry = (ec_pdo_entry_t *)
190 kmalloc(sizeof(ec_pdo_entry_t), GFP_KERNEL))) {
191 EC_ERR("Failed to allocate memory for PDO entry copy.\n");
192 return -ENOMEM;
193 }
194
195 ret = ec_pdo_entry_init_copy(entry, other_entry);
196 if (ret < 0) {
197 kfree(entry);
198 return ret;
199 }
200
201 list_add_tail(&entry->list, &pdo->entries);
202 }
203
204 return 0;
205}
206
207/****************************************************************************/
208
215 const ec_pdo_t *pdo1,
216 const ec_pdo_t *pdo2
217 )
218{
219 const struct list_head *head1, *head2, *item1, *item2;
220 const ec_pdo_entry_t *entry1, *entry2;
221
222 head1 = item1 = &pdo1->entries;
223 head2 = item2 = &pdo2->entries;
224
225 while (1) {
226 item1 = item1->next;
227 item2 = item2->next;
228
229 if ((item1 == head1) ^ (item2 == head2)) // unequal lengths
230 return 0;
231 if (item1 == head1) // both finished
232 break;
233
234 entry1 = list_entry(item1, ec_pdo_entry_t, list);
235 entry2 = list_entry(item2, ec_pdo_entry_t, list);
236 if (!ec_pdo_entry_equal(entry1, entry2))
237 return 0;
238 }
239
240 return 1;
241}
242
243/****************************************************************************/
244
250 const ec_pdo_t *pdo
251 )
252{
253 const ec_pdo_entry_t *entry;
254 unsigned int num = 0;
255
256 list_for_each_entry(entry, &pdo->entries, list) {
257 num++;
258 }
259
260 return num;
261}
262
263/****************************************************************************/
264
272 const ec_pdo_t *pdo,
273 unsigned int pos
274 )
275{
276 const ec_pdo_entry_t *entry;
277
278 list_for_each_entry(entry, &pdo->entries, list) {
279 if (pos--)
280 continue;
281 return entry;
282 }
283
284 return NULL;
285}
286
287/****************************************************************************/
288
292 const ec_pdo_t *pdo
293 )
294{
295 const ec_pdo_entry_t *entry;
296
297 if (list_empty(&pdo->entries)) {
298 printk(KERN_CONT "(none)");
299 } else {
300 list_for_each_entry(entry, &pdo->entries, list) {
301 printk(KERN_CONT "0x%04X:%02X/%u",
302 entry->index, entry->subindex, entry->bit_length);
303 if (entry->list.next != &pdo->entries)
304 printk(KERN_CONT " ");
305 }
306 }
307}
308
309/****************************************************************************/
#define EC_ERR(fmt, args...)
Convenience macro for printing EtherCAT-specific errors to syslog.
Definition globals.h:224
void ec_pdo_init(ec_pdo_t *pdo)
PDO constructor.
Definition pdo.c:38
int ec_pdo_equal_entries(const ec_pdo_t *pdo1, const ec_pdo_t *pdo2)
Compares the entries of two PDOs.
Definition pdo.c:214
void ec_pdo_clear(ec_pdo_t *pdo)
PDO destructor.
Definition pdo.c:86
int ec_pdo_copy_entries(ec_pdo_t *pdo, const ec_pdo_t *other)
Copy PDO entries from another PDO.
Definition pdo.c:178
void ec_pdo_clear_entries(ec_pdo_t *pdo)
Clear PDO entry list.
Definition pdo.c:98
void ec_pdo_print_entries(const ec_pdo_t *pdo)
Outputs the PDOs in the list.
Definition pdo.c:291
ec_pdo_entry_t * ec_pdo_add_entry(ec_pdo_t *pdo, uint16_t index, uint8_t subindex, uint8_t bit_length)
Add a new PDO entry to the configuration.
Definition pdo.c:149
int ec_pdo_set_name(ec_pdo_t *pdo, const char *name)
Set PDO name.
Definition pdo.c:117
int ec_pdo_init_copy(ec_pdo_t *pdo, const ec_pdo_t *other_pdo)
PDO copy constructor.
Definition pdo.c:54
const ec_pdo_entry_t * ec_pdo_find_entry_by_pos_const(const ec_pdo_t *pdo, unsigned int pos)
Finds a PDO entry via its position in the list.
Definition pdo.c:271
unsigned int ec_pdo_entry_count(const ec_pdo_t *pdo)
Get the number of PDO entries.
Definition pdo.c:249
EtherCAT Process data object structure.
void ec_pdo_entry_clear(ec_pdo_entry_t *entry)
PDO entry destructor.
Definition pdo_entry.c:68
void ec_pdo_entry_init(ec_pdo_entry_t *entry)
PDO entry constructor.
Definition pdo_entry.c:37
int ec_pdo_entry_init_copy(ec_pdo_entry_t *entry, const ec_pdo_entry_t *other)
PDO entry copy constructor.
Definition pdo_entry.c:51
int ec_pdo_entry_equal(const ec_pdo_entry_t *entry1, const ec_pdo_entry_t *entry2)
Compares two PDO entries.
Definition pdo_entry.c:114
PDO entry description.
Definition pdo_entry.h:40
struct list_head list
list item
Definition pdo_entry.h:41
uint8_t bit_length
entry length in bit
Definition pdo_entry.h:45
uint8_t subindex
PDO entry subindex.
Definition pdo_entry.h:43
uint16_t index
PDO entry index.
Definition pdo_entry.h:42
PDO description.
Definition pdo.h:41
struct list_head entries
List of PDO entries.
Definition pdo.h:46
int8_t sync_index
Assigned sync manager.
Definition pdo.h:44
uint16_t index
PDO index.
Definition pdo.h:43
char * name
PDO name.
Definition pdo.h:45