Skip to content

Commit 2338b9c

Browse files
committed
fixed random delays in frame sending
1 parent c1dded0 commit 2338b9c

File tree

1 file changed

+20
-8
lines changed

1 file changed

+20
-8
lines changed

src/rawmaster.rs

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ pub struct RawMaster {
6767
// synchronization signal for multitask reception
6868
received: Notify,
6969
sendable: Condvar,
70-
send: Condvar,
7170
sent: Notify,
7271

7372
// communication state
@@ -80,7 +79,7 @@ pub struct RawMaster {
8079
struct PduState {
8180
last_start: usize,
8281
last_end: usize,
83-
last_time: Instant,
82+
ready: bool,
8483
/// send buffer, it contains one ethercat frame
8584
send: [u8; MAX_ETHERCAT_FRAME],
8685
/// reception destination, each containing a reception buffer and additional infos
@@ -102,13 +101,12 @@ impl RawMaster {
102101
socket: Box::new(socket),
103102
received: Notify::new(),
104103
sendable: Condvar::new(),
105-
send: Condvar::new(),
106104
sent: Notify::new(),
107105

108106
pdu_state: Mutex::new(PduState {
109107
last_start: EthercatHeader::packed_size(),
110108
last_end: 0,
111-
last_time: Instant::now(),
109+
ready: false,
112110
send: [0; MAX_ETHERCAT_FRAME],
113111
receive: [0; 2*MAX_ETHERCAT_PDU].map(|_| None),
114112
free: (0 .. 2*MAX_ETHERCAT_PDU).collect(),
@@ -273,8 +271,8 @@ impl RawMaster {
273271
+ data.len()
274272
+ PduHeader::packed_size()
275273
+ PduFooter::packed_size(), "data too big for an ethercat frame");
274+
state.ready = true;
276275
self.sendable.notify_one();
277-
self.send.notify_one();
278276
let notification = self.sent.notified();
279277
drop(state);
280278
notification.await;
@@ -303,7 +301,6 @@ impl RawMaster {
303301
header.pack(place).unwrap();
304302
}
305303
else {
306-
state.last_time = Instant::now();
307304
state.last_end = state.last_start;
308305
}
309306

@@ -352,6 +349,13 @@ impl RawMaster {
352349
state.receive[token].as_ref().unwrap().answers
353350
}
354351

352+
/// trigger sending the buffered PDUs, they will be sent as soon as possible by [Self::send] instead of waiting for the frame to be full or for the timeout
353+
fn flush(&self) {
354+
let mut state = self.pdu_state.lock().unwrap();
355+
state.ready = true;
356+
self.sendable.notify_one();
357+
}
358+
355359
/// extract a received frame of PDUs and buffer each for reception by an eventual `self.pdu()` future waiting for it.
356360
fn pdu_receive(&self, state: &mut PduState, frame: &[u8]) {
357361
let mut frame = Cursor::new(frame);
@@ -404,9 +408,16 @@ impl RawMaster {
404408
/// this is the socket sending handler
405409
pub fn send(&self) {
406410
let mut state = self.pdu_state.lock().unwrap();
407-
if state.last_end == 0
411+
// wait indefinitely if no data to send
412+
while state.last_end == 0
408413
{state = self.sendable.wait(state).unwrap();}
409-
state = self.send.wait_timeout(state, self.pdu_merge_time).unwrap().0;
414+
// wait for more data until a timeout once data is present
415+
if ! state.ready
416+
{state = self.sendable.wait_timeout_while(
417+
state,
418+
self.pdu_merge_time,
419+
|state| ! state.ready,
420+
).unwrap().0;}
410421

411422
// check header
412423
EthercatHeader::new(
@@ -419,6 +430,7 @@ impl RawMaster {
419430
// we assume it is not a long operation to copy those data into the system buffer
420431
self.socket.send(&state.send[.. state.last_end]).unwrap();
421432
// reset state
433+
state.ready = false;
422434
state.last_end = 0;
423435
state.last_start = EthercatHeader::packed_size();
424436
self.sent.notify_waiters();

0 commit comments

Comments
 (0)