Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
E
etherlabmaster
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Jira
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
ICS Control System Infrastructure
etherlabmaster
Commits
41140db9
Commit
41140db9
authored
17 years ago
by
Florian Pose
Browse files
Options
Downloads
Patches
Plain Diff
Switched to tx socket buffer ring to avoid race conditions when multiple
instances call ec_device_send() in short intervals.
parent
f63ac455
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
master/device.c
+52
-26
52 additions, 26 deletions
master/device.c
master/device.h
+4
-2
4 additions, 2 deletions
master/device.h
with
56 additions
and
28 deletions
master/device.c
+
52
−
26
View file @
41140db9
...
...
@@ -69,6 +69,8 @@ int ec_device_init(ec_device_t *device, /**< EtherCAT device */
ec_master_t
*
master
/**< master owning the device */
)
{
unsigned
int
i
;
struct
ethhdr
*
eth
;
#ifdef EC_DEBUG_IF
char
ifname
[
10
];
char
mb
=
'x'
;
...
...
@@ -79,6 +81,7 @@ int ec_device_init(ec_device_t *device, /**< EtherCAT device */
#endif
device
->
master
=
master
;
device
->
tx_ring_index
=
0
;
#ifdef EC_DEBUG_IF
if
(
device
==
&
master
->
main_device
)
...
...
@@ -94,29 +97,33 @@ int ec_device_init(ec_device_t *device, /**< EtherCAT device */
}
#endif
if
(
!
(
device
->
tx_skb
=
dev_alloc_skb
(
ETH_FRAME_LEN
)))
{
EC_ERR
(
"Error allocating device socket buffer!
\n
"
)
;
#ifdef EC_DEBUG_IF
goto
out_debug
;
#else
goto
out_return
;
#endif
}
for
(
i
=
0
;
i
<
EC_TX_RING_SIZE
;
i
++
)
device
->
tx_skb
[
i
]
=
NULL
;
for
(
i
=
0
;
i
<
EC_TX_RING_SIZE
;
i
++
)
{
if
(
!
(
device
->
tx_skb
[
i
]
=
dev_alloc_skb
(
ETH_FRAME_LEN
)))
{
EC_ERR
(
"Error allocating device socket buffer!
\n
"
)
;
goto
out_tx_ring
;
}
// add Ethernet-II-header
skb_reserve
(
device
->
tx_skb
,
ETH_HLEN
);
device
->
eth
=
(
struct
ethhdr
*
)
skb_push
(
device
->
tx_skb
,
ETH_HLEN
);
device
->
eth
->
h_proto
=
htons
(
0x88A4
);
memset
(
device
->
eth
->
h_dest
,
0xFF
,
ETH_ALEN
);
// add Ethernet-II-header
skb_reserve
(
device
->
tx_skb
[
i
],
ETH_HLEN
);
eth
=
(
struct
ethhdr
*
)
skb_push
(
device
->
tx_skb
[
i
],
ETH_HLEN
);
eth
->
h_proto
=
htons
(
0x88A4
);
memset
(
eth
->
h_dest
,
0xFF
,
ETH_ALEN
);
}
ec_device_detach
(
device
);
// resets remaining fields
return
0
;
out_tx_ring:
for
(
i
=
0
;
i
<
EC_TX_RING_SIZE
;
i
++
)
if
(
device
->
tx_skb
[
i
])
dev_kfree_skb
(
device
->
tx_skb
[
i
]);
#ifdef EC_DEBUG_IF
out_debug:
ec_debug_clear
(
&
device
->
dbg
);
out_return:
#endif
out_return:
return
-
1
;
}
...
...
@@ -128,8 +135,11 @@ int ec_device_init(ec_device_t *device, /**< EtherCAT device */
void
ec_device_clear
(
ec_device_t
*
device
/**< EtherCAT device */
)
{
unsigned
int
i
;
if
(
device
->
open
)
ec_device_close
(
device
);
dev_kfree_skb
(
device
->
tx_skb
);
for
(
i
=
0
;
i
<
EC_TX_RING_SIZE
;
i
++
)
dev_kfree_skb
(
device
->
tx_skb
[
i
]);
#ifdef EC_DEBUG_IF
ec_debug_clear
(
&
device
->
dbg
);
#endif
...
...
@@ -147,14 +157,20 @@ void ec_device_attach(ec_device_t *device, /**< EtherCAT device */
struct
module
*
module
/**< the device's module */
)
{
unsigned
int
i
;
struct
ethhdr
*
eth
;
ec_device_detach
(
device
);
// resets fields
device
->
dev
=
net_dev
;
device
->
poll
=
poll
;
device
->
module
=
module
;
device
->
tx_skb
->
dev
=
net_dev
;
memcpy
(
device
->
eth
->
h_source
,
net_dev
->
dev_addr
,
ETH_ALEN
);
for
(
i
=
0
;
i
<
EC_TX_RING_SIZE
;
i
++
)
{
device
->
tx_skb
[
i
]
->
dev
=
net_dev
;
eth
=
(
struct
ethhdr
*
)
(
device
->
tx_skb
[
i
]
->
data
+
ETH_HLEN
);
memcpy
(
eth
->
h_source
,
net_dev
->
dev_addr
,
ETH_ALEN
);
}
}
/*****************************************************************************/
...
...
@@ -165,6 +181,8 @@ void ec_device_attach(ec_device_t *device, /**< EtherCAT device */
void
ec_device_detach
(
ec_device_t
*
device
/**< EtherCAT device */
)
{
unsigned
int
i
;
device
->
dev
=
NULL
;
device
->
poll
=
NULL
;
device
->
module
=
NULL
;
...
...
@@ -172,7 +190,8 @@ void ec_device_detach(ec_device_t *device /**< EtherCAT device */)
device
->
link_state
=
0
;
// down
device
->
tx_count
=
0
;
device
->
rx_count
=
0
;
device
->
tx_skb
->
dev
=
NULL
;
for
(
i
=
0
;
i
<
EC_TX_RING_SIZE
;
i
++
)
device
->
tx_skb
[
i
]
->
dev
=
NULL
;
}
/*****************************************************************************/
...
...
@@ -236,7 +255,12 @@ int ec_device_close(ec_device_t *device /**< EtherCAT device */)
uint8_t
*
ec_device_tx_data
(
ec_device_t
*
device
/**< EtherCAT device */
)
{
return
device
->
tx_skb
->
data
+
ETH_HLEN
;
/* cycle through socket buffers, because otherwise there is a race
* condition, if multiple frames are sent and the DMA is not scheduled in
* between. */
device
->
tx_ring_index
++
;
device
->
tx_ring_index
%=
EC_TX_RING_SIZE
;
return
device
->
tx_skb
[
device
->
tx_ring_index
]
->
data
+
ETH_HLEN
;
}
/*****************************************************************************/
...
...
@@ -251,27 +275,29 @@ void ec_device_send(ec_device_t *device, /**< EtherCAT device */
size_t
size
/**< number of bytes to send */
)
{
struct
sk_buff
*
skb
=
device
->
tx_skb
[
device
->
tx_ring_index
];
if
(
unlikely
(
!
device
->
link_state
))
// Link down
return
;
// set the right length for the data
device
->
tx_
skb
->
len
=
ETH_HLEN
+
size
;
skb
->
len
=
ETH_HLEN
+
size
;
if
(
unlikely
(
device
->
master
->
debug_level
>
1
))
{
EC_DBG
(
"sending frame:
\n
"
);
ec_print_data
(
device
->
tx_
skb
->
data
+
ETH_HLEN
,
size
);
ec_print_data
(
skb
->
data
+
ETH_HLEN
,
size
);
}
#ifdef EC_DEBUG_IF
ec_debug_send
(
&
device
->
dbg
,
device
->
tx_
skb
->
data
,
ETH_HLEN
+
size
);
ec_debug_send
(
&
device
->
dbg
,
skb
->
data
,
ETH_HLEN
+
size
);
#endif
#ifdef EC_DEBUG_RING
ec_device_debug_ring_append
(
device
,
TX
,
device
->
tx_
skb
->
data
+
ETH_HLEN
,
size
);
device
,
TX
,
skb
->
data
+
ETH_HLEN
,
size
);
#endif
// start sending
device
->
dev
->
hard_start_xmit
(
device
->
tx_
skb
,
device
->
dev
);
device
->
dev
->
hard_start_xmit
(
skb
,
device
->
dev
);
device
->
tx_count
++
;
}
...
...
@@ -389,7 +415,7 @@ void ecdev_receive(ec_device_t *device, /**< EtherCAT device */
if
(
unlikely
(
device
->
master
->
debug_level
>
1
))
{
EC_DBG
(
"Received frame:
\n
"
);
ec_print_data
_diff
(
device
->
tx_skb
->
data
+
ETH_HLEN
,
ec_data
,
ec_size
);
ec_print_data
(
ec_data
,
ec_size
);
}
#ifdef EC_DEBUG_IF
...
...
This diff is collapsed.
Click to expand it.
master/device.h
+
4
−
2
View file @
41140db9
...
...
@@ -47,6 +47,8 @@
#include
"../devices/ecdev.h"
#include
"globals.h"
#define EC_TX_RING_SIZE 2
#ifdef EC_DEBUG_IF
#include
"debug.h"
#endif
...
...
@@ -84,8 +86,8 @@ struct ec_device
struct
module
*
module
;
/**< pointer to the device's owning module */
uint8_t
open
;
/**< true, if the net_device has been opened */
uint8_t
link_state
;
/**< device link state */
struct
sk_buff
*
tx_skb
;
/**< transmit s
ocket buffer
*/
struct
ethhdr
*
eth
;
/**< pointer to ethernet header in socket buffer */
struct
sk_buff
*
tx_skb
[
EC_TX_RING_SIZE
]
;
/**< transmit s
kb ring
*/
unsigned
int
tx_ring_index
;
cycles_t
cycles_poll
;
/**< cycles of last poll */
#ifdef EC_DEBUG_RING
struct
timeval
timeval_poll
;
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment