SOEM
test
win32
red_test
win32/red_test/red_test.c
Go to the documentation of this file.
1
13
#include <stdio.h>
14
#include <stdlib.h>
15
#include <sys/time.h>
16
#include <unistd.h>
17
#include <sched.h>
18
#include <string.h>
19
#include <sys/time.h>
20
#include <time.h>
21
#include <pthread.h>
22
#include <math.h>
23
24
#include "
ethercat.h
"
25
26
#define NSEC_PER_SEC 1000000000
27
28
struct
sched_param
schedp
;
29
char
IOmap
[4096];
30
pthread_t
thread1
;
31
struct
timeval tv, t1,
t2
;
32
int
dorun
= 0;
33
int
deltat
,
tmax
= 0;
34
int64
toff
;
35
int
DCdiff
;
36
int
os
;
37
uint8
ob
;
38
uint16
ob2
;
39
pthread_cond_t
cond
= PTHREAD_COND_INITIALIZER;
40
pthread_mutex_t
mutex
= PTHREAD_MUTEX_INITIALIZER;
41
uint8
*
digout
= 0;
42
int
wcounter
;
43
44
void
redtest
(
char
*ifname,
char
*ifname2)
45
{
46
int
cnt, i,
j
, oloop, iloop;
47
48
printf(
"Starting Redundant test\n"
);
49
50
/* initialise SOEM, bind socket to ifname */
51
if
(
ec_init_redundant
(ifname, ifname2))
52
{
53
printf(
"ec_init on %s succeeded.\n"
,ifname);
54
/* find and auto-config slaves */
55
if
(
ec_config
(
FALSE
, &
IOmap
) > 0 )
56
{
57
printf(
"%d slaves found and configured.\n"
,
ec_slavecount
);
58
/* wait for all slaves to reach SAFE_OP state */
59
ec_statecheck
(0,
EC_STATE_SAFE_OP
,
EC_TIMEOUTSTATE
);
60
61
/* configure DC options for every DC capable slave found in the list */
62
ec_configdc
();
63
64
/* read indevidual slave state and store in ec_slave[] */
65
ec_readstate
();
66
for
(cnt = 1; cnt <=
ec_slavecount
; cnt++)
67
{
68
printf(
"Slave:%d Name:%s Output size:%3dbits Input size:%3dbits State:%2d delay:%d.%d\n"
,
69
cnt,
ec_slave
[cnt].name,
ec_slave
[cnt].Obits,
ec_slave
[cnt].Ibits,
70
ec_slave
[cnt].state, (
int
)
ec_slave
[cnt].pdelay,
ec_slave
[cnt].hasdc);
71
printf(
" Out:%8.8x,%4d In:%8.8x,%4d\n"
,
72
(
int
)
ec_slave
[cnt].outputs,
ec_slave
[cnt].Obytes, (
int
)
ec_slave
[cnt].inputs,
ec_slave
[cnt].Ibytes);
73
/* check for EL2004 or EL2008 */
74
if
( !
digout
&& ((
ec_slave
[cnt].eep_id == 0x07d43052) || (
ec_slave
[cnt].eep_id == 0x07d83052)))
75
{
76
digout
=
ec_slave
[cnt].
outputs
;
77
}
78
}
79
printf(
"Request operational state for all slaves\n"
);
80
ec_slave
[0].
state
=
EC_STATE_OPERATIONAL
;
81
/* request OP state for all slaves */
82
ec_writestate
(0);
83
/* wait for all slaves to reach OP state */
84
ec_statecheck
(0,
EC_STATE_OPERATIONAL
, 5 *
EC_TIMEOUTSTATE
);
85
oloop =
ec_slave
[0].
Obytes
;
86
if
((oloop == 0) && (
ec_slave
[0].Obits > 0)) oloop = 1;
87
if
(oloop > 8) oloop = 8;
88
iloop =
ec_slave
[0].
Ibytes
;
89
if
((iloop == 0) && (
ec_slave
[0].Ibits > 0)) iloop = 1;
90
if
(iloop > 8) iloop = 8;
91
if
(
ec_slave
[0].state ==
EC_STATE_OPERATIONAL
)
92
{
93
printf(
"Operational state reached for all slaves.\n"
);
94
dorun
= 1;
95
/* acyclic loop 5000 x 20ms = 10s */
96
for
(i = 1; i <= 5000; i++)
97
{
98
printf(
"Processdata cycle %5d , Wck %3d, DCtime %12lld, O:"
,
dorun
,
wcounter
,
ec_DCtime
);
99
for
(
j
= 0 ;
j
< oloop;
j
++)
100
{
101
printf(
" %2.2x"
, *(
ec_slave
[0].outputs +
j
));
102
}
103
printf(
" I:"
);
104
for
(
j
= 0 ;
j
< iloop;
j
++)
105
{
106
printf(
" %2.2x"
, *(
ec_slave
[0].inputs +
j
));
107
}
108
printf(
"\n"
);
109
usleep(20000);
110
}
111
dorun
= 0;
112
}
113
else
114
{
115
printf(
"Not all slaves reached operational state.\n"
);
116
}
117
printf(
"Request safe operational state for all slaves\n"
);
118
ec_slave
[0].
state
=
EC_STATE_SAFE_OP
;
119
/* request SAFE_OP state for all slaves */
120
ec_writestate
(0);
121
}
122
else
123
{
124
printf(
"No slaves found!\n"
);
125
}
126
printf(
"End redundant test, close socket\n"
);
127
/* stop SOEM, close socket */
128
ec_close
();
129
}
130
else
131
{
132
printf(
"No socket connection on %s\nExcecute as root\n"
,ifname);
133
}
134
}
135
136
/* add ns to timespec */
137
void
add_timespec
(
struct
timespec *ts,
int64
addtime)
138
{
139
int64
sec, nsec;
140
141
nsec = addtime %
NSEC_PER_SEC
;
142
sec = (addtime - nsec) /
NSEC_PER_SEC
;
143
ts->tv_sec += sec;
144
ts->tv_nsec += nsec;
145
if
( ts->tv_nsec >
NSEC_PER_SEC
)
146
{
147
nsec = ts->tv_nsec %
NSEC_PER_SEC
;
148
ts->tv_sec += (ts->tv_nsec - nsec) /
NSEC_PER_SEC
;
149
ts->tv_nsec = nsec;
150
}
151
}
152
153
/* PI calculation to get linux time synced to DC time */
154
void
ec_sync
(
int64
reftime,
int64
cycletime ,
int64
*offsettime)
155
{
156
static
int64
integral
= 0;
157
int64
delta;
158
/* set linux sync point 50us later than DC sync, just as example */
159
delta = (reftime - 50000) % cycletime;
160
if
(delta> (cycletime / 2)) { delta= delta - cycletime; }
161
if
(delta>0){
integral
++; }
162
if
(delta<0){
integral
--; }
163
*offsettime = -(delta / 100) - (
integral
/ 20);
164
}
165
166
/* RT EtherCAT thread */
167
void
ecatthread
(
void
*ptr )
168
{
169
struct
timespec ts;
170
struct
timeval tp;
171
int
rc;
172
int
ht;
173
int64
cycletime;
174
175
rc = pthread_mutex_lock(&
mutex
);
176
rc =
gettimeofday
(&tp, NULL);
177
178
/* Convert from timeval to timespec */
179
ts.tv_sec = tp.tv_sec;
180
ht = (tp.tv_usec / 1000) + 1;
/* round to nearest ms */
181
ts.tv_nsec = ht * 1000000;
182
cycletime = *(
int
*)ptr * 1000;
/* cycletime in ns */
183
toff
= 0;
184
dorun
= 0;
185
while
(1)
186
{
187
/* calculate next cycle start */
188
add_timespec
(&ts, cycletime +
toff
);
189
/* wait to cycle start */
190
rc = pthread_cond_timedwait(&
cond
, &
mutex
, &ts);
191
if
(
dorun
>0)
192
{
193
rc =
gettimeofday
(&tp, NULL);
194
195
ec_send_processdata
();
196
197
wcounter
=
ec_receive_processdata
(
EC_TIMEOUTRET
);
198
199
dorun
++;
200
/* if we have some digital output, cycle */
201
if
(
digout
) *
digout
= (
uint8
) ((
dorun
/ 16) & 0xff);
202
203
if
(
ec_slave
[0].hasdc)
204
{
205
/* calulate toff to get linux time and DC synced */
206
ec_sync
(
ec_DCtime
, cycletime, &
toff
);
207
}
208
}
209
}
210
}
211
212
int
main
(
int
argc,
char
*argv[])
213
{
214
int
iret1;
215
int
ctime;
216
struct
sched_param param;
217
int
policy = SCHED_OTHER;
218
219
printf(
"SOEM (Simple Open EtherCAT Master)\nRedundancy test\n"
);
220
221
memset(&
schedp
, 0,
sizeof
(
schedp
));
222
/* do not set priority above 49, otherwise sockets are starved */
223
schedp
.sched_priority = 30;
224
sched_setscheduler(0, SCHED_FIFO, &
schedp
);
225
226
do
227
{
228
usleep(1000);
229
}
230
while
(
dorun
);
231
232
if
(argc > 3)
233
{
234
dorun
= 1;
235
ctime = atoi(argv[3]);
236
/* create RT thread */
237
iret1 = pthread_create( &
thread1
, NULL, (
void
*) &
ecatthread
, (
void
*) &ctime);
238
memset(¶m, 0,
sizeof
(param));
239
/* give it higher priority */
240
param.sched_priority = 40;
241
iret1 = pthread_setschedparam(
thread1
, policy, ¶m);
242
243
/* start acyclic part */
244
redtest
(argv[1],argv[2]);
245
}
246
else
247
{
248
printf(
"Usage: red_test ifname1 ifname2 cycletime\nifname = eth0 for example\ncycletime in us\n"
);
249
}
250
251
schedp
.sched_priority = 0;
252
sched_setscheduler(0, SCHED_OTHER, &
schedp
);
253
254
printf(
"End program\n"
);
255
256
return
(0);
257
}
ec_configdc
boolean ec_configdc(void)
Definition:
ethercatdc.c:444
redtest
void redtest(char *ifname, char *ifname2)
Definition:
win32/red_test/red_test.c:44
ec_readstate
int ec_readstate(void)
Definition:
ethercatmain.c:2138
integral
int64 integral
Definition:
linux/ebox/ebox.c:77
ec_close
void ec_close(void)
Definition:
ethercatmain.c:2048
ec_init_redundant
int ec_init_redundant(const char *ifname, char *if2name)
Definition:
ethercatmain.c:2040
ec_slave::outputs
uint8 * outputs
Definition:
ethercatmain.h:131
ec_sync
void ec_sync(int64 reftime, int64 cycletime, int64 *offsettime)
Definition:
win32/red_test/red_test.c:154
ec_send_processdata
int ec_send_processdata(void)
Definition:
ethercatmain.c:2383
ethercat.h
Headerfile for all ethercat headers.
main
int main(int argc, char *argv[])
Definition:
win32/red_test/red_test.c:212
int64
int64_t int64
Definition:
osal.h:31
ec_slave::Ibytes
uint32 Ibytes
Definition:
ethercatmain.h:137
ec_config
int ec_config(uint8 usetable, void *pIOmap)
Definition:
ethercatconfig.c:1665
toff
int64 toff
Definition:
win32/red_test/red_test.c:34
ec_DCtime
int64 ec_DCtime
Definition:
ethercatmain.c:95
uint8
uint8_t uint8
Definition:
osal.h:28
EC_STATE_SAFE_OP
@ EC_STATE_SAFE_OP
Definition:
ethercattype.h:166
ob2
uint16 ob2
Definition:
win32/red_test/red_test.c:38
j
int j
Definition:
linux/firm_update/firm_update.c:31
thread1
pthread_t thread1
Definition:
win32/red_test/red_test.c:30
ec_slave::state
uint16 state
Definition:
ethercatmain.h:109
EC_TIMEOUTRET
#define EC_TIMEOUTRET
Definition:
ethercattype.h:64
uint16
uint16_t uint16
Definition:
osal.h:29
IOmap
char IOmap[4096]
Definition:
win32/red_test/red_test.c:29
tmax
int tmax
Definition:
win32/red_test/red_test.c:33
digout
uint8 * digout
Definition:
win32/red_test/red_test.c:41
ec_writestate
int ec_writestate(uint16 slave)
Definition:
ethercatmain.c:2149
ec_slave
Definition:
ethercatmain.h:106
FALSE
#define FALSE
Definition:
osal.h:22
ecatthread
void ecatthread(void *ptr)
Definition:
win32/red_test/red_test.c:167
DCdiff
int DCdiff
Definition:
win32/red_test/red_test.c:35
EC_TIMEOUTSTATE
#define EC_TIMEOUTSTATE
Definition:
ethercattype.h:76
schedp
struct sched_param schedp
Definition:
win32/red_test/red_test.c:28
dorun
int dorun
Definition:
win32/red_test/red_test.c:32
ec_slavecount
int ec_slavecount
Definition:
ethercatmain.c:69
NSEC_PER_SEC
#define NSEC_PER_SEC
Definition:
win32/red_test/red_test.c:26
ob
uint8 ob
Definition:
win32/red_test/red_test.c:37
t2
struct timeval tv t1 t2
Definition:
win32/red_test/red_test.c:31
cond
pthread_cond_t cond
Definition:
win32/red_test/red_test.c:39
add_timespec
void add_timespec(struct timespec *ts, int64 addtime)
Definition:
win32/red_test/red_test.c:137
ec_statecheck
uint16 ec_statecheck(uint16 slave, uint16 reqstate, int timeout)
Definition:
ethercatmain.c:2162
os
int os
Definition:
win32/red_test/red_test.c:36
ec_receive_processdata
int ec_receive_processdata(int timeout)
Definition:
ethercatmain.c:2393
gettimeofday
int gettimeofday(struct timeval *tp, void *tzp)
Definition:
rtk/osal.c:50
deltat
int deltat
Definition:
win32/red_test/red_test.c:33
ec_slave::Obytes
uint32 Obytes
Definition:
ethercatmain.h:129
mutex
pthread_mutex_t mutex
Definition:
win32/red_test/red_test.c:40
wcounter
int wcounter
Definition:
win32/red_test/red_test.c:42
EC_STATE_OPERATIONAL
@ EC_STATE_OPERATIONAL
Definition:
ethercattype.h:168
soem
Author(s): Arthur Ketels and M.J.G. van den Molengraft
autogenerated on Wed Mar 2 2022 01:01:49