aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32
diff options
context:
space:
mode:
authorTobias Naumann <[email protected]>2025-06-05 15:24:29 +0200
committerCorey Schuhen <[email protected]>2025-06-21 12:29:36 +1000
commite75b344089df76aa89d7fd4463a509c0bc58de2c (patch)
treefe504734560071000f42fe2fad52851f523984be /embassy-stm32
parentb2dcdad51db528e1242ef7ea6028341339a9d488 (diff)
Add TxGuard and RxGuard which impl RAII for the STM32 CAN reference counting
Diffstat (limited to 'embassy-stm32')
-rw-r--r--embassy-stm32/src/can/common.rs53
-rw-r--r--embassy-stm32/src/can/fdcan.rs85
2 files changed, 64 insertions, 74 deletions
diff --git a/embassy-stm32/src/can/common.rs b/embassy-stm32/src/can/common.rs
index 386d4467c..651fa12d5 100644
--- a/embassy-stm32/src/can/common.rs
+++ b/embassy-stm32/src/can/common.rs
@@ -25,7 +25,7 @@ pub(crate) struct FdBufferedTxInner {
25pub struct BufferedSender<'ch, FRAME> { 25pub struct BufferedSender<'ch, FRAME> {
26 pub(crate) tx_buf: embassy_sync::channel::SendDynamicSender<'ch, FRAME>, 26 pub(crate) tx_buf: embassy_sync::channel::SendDynamicSender<'ch, FRAME>,
27 pub(crate) waker: fn(), 27 pub(crate) waker: fn(),
28 pub(crate) internal_operation: fn(InternalOperation), 28 pub(crate) tx_guard: TxGuard,
29} 29}
30 30
31impl<'ch, FRAME> BufferedSender<'ch, FRAME> { 31impl<'ch, FRAME> BufferedSender<'ch, FRAME> {
@@ -50,28 +50,21 @@ impl<'ch, FRAME> BufferedSender<'ch, FRAME> {
50 50
51impl<'ch, FRAME> Clone for BufferedSender<'ch, FRAME> { 51impl<'ch, FRAME> Clone for BufferedSender<'ch, FRAME> {
52 fn clone(&self) -> Self { 52 fn clone(&self) -> Self {
53 (self.internal_operation)(InternalOperation::NotifySenderCreated);
54 Self { 53 Self {
55 tx_buf: self.tx_buf, 54 tx_buf: self.tx_buf,
56 waker: self.waker, 55 waker: self.waker,
57 internal_operation: self.internal_operation, 56 tx_guard: TxGuard::new(self.tx_guard.internal_operation),
58 } 57 }
59 } 58 }
60} 59}
61 60
62impl<'ch, FRAME> Drop for BufferedSender<'ch, FRAME> {
63 fn drop(&mut self) {
64 (self.internal_operation)(InternalOperation::NotifySenderDestroyed);
65 }
66}
67
68/// Sender that can be used for sending Classic CAN frames. 61/// Sender that can be used for sending Classic CAN frames.
69pub type BufferedCanSender = BufferedSender<'static, Frame>; 62pub type BufferedCanSender = BufferedSender<'static, Frame>;
70 63
71/// Receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver. 64/// Receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver.
72pub struct BufferedReceiver<'ch, ENVELOPE> { 65pub struct BufferedReceiver<'ch, ENVELOPE> {
73 pub(crate) rx_buf: embassy_sync::channel::SendDynamicReceiver<'ch, Result<ENVELOPE, BusError>>, 66 pub(crate) rx_buf: embassy_sync::channel::SendDynamicReceiver<'ch, Result<ENVELOPE, BusError>>,
74 pub(crate) internal_operation: fn(InternalOperation), 67 pub(crate) rx_guard: RxGuard,
75} 68}
76 69
77impl<'ch, ENVELOPE> BufferedReceiver<'ch, ENVELOPE> { 70impl<'ch, ENVELOPE> BufferedReceiver<'ch, ENVELOPE> {
@@ -106,19 +99,47 @@ impl<'ch, ENVELOPE> BufferedReceiver<'ch, ENVELOPE> {
106 99
107impl<'ch, ENVELOPE> Clone for BufferedReceiver<'ch, ENVELOPE> { 100impl<'ch, ENVELOPE> Clone for BufferedReceiver<'ch, ENVELOPE> {
108 fn clone(&self) -> Self { 101 fn clone(&self) -> Self {
109 (self.internal_operation)(InternalOperation::NotifyReceiverCreated);
110 Self { 102 Self {
111 rx_buf: self.rx_buf, 103 rx_buf: self.rx_buf,
112 internal_operation: self.internal_operation, 104 rx_guard: RxGuard::new(self.rx_guard.internal_operation),
113 } 105 }
114 } 106 }
115} 107}
116 108
117impl<'ch, ENVELOPE> Drop for BufferedReceiver<'ch, ENVELOPE> { 109/// A BufferedCanReceiver for Classic CAN frames.
110pub type BufferedCanReceiver = BufferedReceiver<'static, Envelope>;
111
112/// Implements RAII for the internal reference counting (TX side). Each TX type should contain one
113/// of these. The new method and the Drop impl will automatically call the reference counting
114/// function. Like this, the reference counting function does not need to be called manually for
115/// each TX type. Transceiver types (TX and RX) should contain one TxGuard and one RxGuard.
116pub(crate) struct TxGuard {
117 internal_operation: fn(InternalOperation),
118}
119impl TxGuard {
120 pub(crate) fn new(internal_operation: fn(InternalOperation)) -> Self {
121 internal_operation(InternalOperation::NotifySenderCreated);
122 Self { internal_operation }
123 }
124}
125impl Drop for TxGuard {
126 fn drop(&mut self) {
127 (self.internal_operation)(InternalOperation::NotifySenderDestroyed);
128 }
129}
130
131/// Implements RAII for the internal reference counting (RX side). See TxGuard for further doc.
132pub(crate) struct RxGuard {
133 internal_operation: fn(InternalOperation),
134}
135impl RxGuard {
136 pub(crate) fn new(internal_operation: fn(InternalOperation)) -> Self {
137 internal_operation(InternalOperation::NotifyReceiverCreated);
138 Self { internal_operation }
139 }
140}
141impl Drop for RxGuard {
118 fn drop(&mut self) { 142 fn drop(&mut self) {
119 (self.internal_operation)(InternalOperation::NotifyReceiverDestroyed); 143 (self.internal_operation)(InternalOperation::NotifyReceiverDestroyed);
120 } 144 }
121} 145}
122
123/// A BufferedCanReceiver for Classic CAN frames.
124pub type BufferedCanReceiver = BufferedReceiver<'static, Envelope>;
diff --git a/embassy-stm32/src/can/fdcan.rs b/embassy-stm32/src/can/fdcan.rs
index 97d22315a..2846fb44a 100644
--- a/embassy-stm32/src/can/fdcan.rs
+++ b/embassy-stm32/src/can/fdcan.rs
@@ -21,6 +21,7 @@ use self::fd::config::*;
21use self::fd::filter::*; 21use self::fd::filter::*;
22pub use self::fd::{config, filter}; 22pub use self::fd::{config, filter};
23pub use super::common::{BufferedCanReceiver, BufferedCanSender}; 23pub use super::common::{BufferedCanReceiver, BufferedCanSender};
24use super::common::{RxGuard, TxGuard};
24use super::enums::*; 25use super::enums::*;
25use super::frame::*; 26use super::frame::*;
26use super::util; 27use super::util;
@@ -171,6 +172,7 @@ pub struct CanConfigurator<'d> {
171 /// Reference to internals. 172 /// Reference to internals.
172 properties: Properties, 173 properties: Properties,
173 periph_clock: crate::time::Hertz, 174 periph_clock: crate::time::Hertz,
175 raii_guards: (TxGuard, RxGuard),
174} 176}
175 177
176impl<'d> CanConfigurator<'d> { 178impl<'d> CanConfigurator<'d> {
@@ -194,8 +196,6 @@ impl<'d> CanConfigurator<'d> {
194 s.borrow_mut().tx_pin_port = Some(tx.pin_port()); 196 s.borrow_mut().tx_pin_port = Some(tx.pin_port());
195 s.borrow_mut().rx_pin_port = Some(rx.pin_port()); 197 s.borrow_mut().rx_pin_port = Some(rx.pin_port());
196 }); 198 });
197 (info.internal_operation)(InternalOperation::NotifySenderCreated);
198 (info.internal_operation)(InternalOperation::NotifyReceiverCreated);
199 199
200 let mut config = crate::can::fd::config::FdCanConfig::default(); 200 let mut config = crate::can::fd::config::FdCanConfig::default();
201 config.timestamp_source = TimestampSource::Prescaler(TimestampPrescaler::_1); 201 config.timestamp_source = TimestampSource::Prescaler(TimestampPrescaler::_1);
@@ -214,6 +214,10 @@ impl<'d> CanConfigurator<'d> {
214 info, 214 info,
215 properties: Properties::new(T::info()), 215 properties: Properties::new(T::info()),
216 periph_clock: T::frequency(), 216 periph_clock: T::frequency(),
217 raii_guards: (
218 TxGuard::new(info.internal_operation),
219 RxGuard::new(info.internal_operation),
220 ),
217 } 221 }
218 } 222 }
219 223
@@ -267,14 +271,13 @@ impl<'d> CanConfigurator<'d> {
267 s.borrow_mut().ns_per_timer_tick = ns_per_timer_tick; 271 s.borrow_mut().ns_per_timer_tick = ns_per_timer_tick;
268 }); 272 });
269 self.info.regs.into_mode(self.config, mode); 273 self.info.regs.into_mode(self.config, mode);
270 (self.info.internal_operation)(InternalOperation::NotifySenderCreated);
271 (self.info.internal_operation)(InternalOperation::NotifyReceiverCreated);
272 Can { 274 Can {
273 _phantom: PhantomData, 275 _phantom: PhantomData,
274 config: self.config, 276 config: self.config,
275 info: self.info, 277 info: self.info,
276 _mode: mode, 278 _mode: mode,
277 properties: Properties::new(self.info), 279 properties: Properties::new(self.info),
280 raii_guards: self.raii_guards,
278 } 281 }
279 } 282 }
280 283
@@ -294,13 +297,6 @@ impl<'d> CanConfigurator<'d> {
294 } 297 }
295} 298}
296 299
297impl<'d> Drop for CanConfigurator<'d> {
298 fn drop(&mut self) {
299 (self.info.internal_operation)(InternalOperation::NotifySenderDestroyed);
300 (self.info.internal_operation)(InternalOperation::NotifyReceiverDestroyed);
301 }
302}
303
304/// FDCAN Instance 300/// FDCAN Instance
305pub struct Can<'d> { 301pub struct Can<'d> {
306 _phantom: PhantomData<&'d ()>, 302 _phantom: PhantomData<&'d ()>,
@@ -308,6 +304,7 @@ pub struct Can<'d> {
308 info: &'static Info, 304 info: &'static Info,
309 _mode: OperatingMode, 305 _mode: OperatingMode,
310 properties: Properties, 306 properties: Properties,
307 raii_guards: (TxGuard, RxGuard),
311} 308}
312 309
313impl<'d> Can<'d> { 310impl<'d> Can<'d> {
@@ -364,19 +361,19 @@ impl<'d> Can<'d> {
364 361
365 /// Split instance into separate portions: Tx(write), Rx(read), common properties 362 /// Split instance into separate portions: Tx(write), Rx(read), common properties
366 pub fn split(self) -> (CanTx<'d>, CanRx<'d>, Properties) { 363 pub fn split(self) -> (CanTx<'d>, CanRx<'d>, Properties) {
367 (self.info.internal_operation)(InternalOperation::NotifySenderCreated);
368 (self.info.internal_operation)(InternalOperation::NotifyReceiverCreated);
369 ( 364 (
370 CanTx { 365 CanTx {
371 _phantom: PhantomData, 366 _phantom: PhantomData,
372 info: self.info, 367 info: self.info,
373 config: self.config, 368 config: self.config,
374 _mode: self._mode, 369 _mode: self._mode,
370 tx_guard: self.raii_guards.0,
375 }, 371 },
376 CanRx { 372 CanRx {
377 _phantom: PhantomData, 373 _phantom: PhantomData,
378 info: self.info, 374 info: self.info,
379 _mode: self._mode, 375 _mode: self._mode,
376 rx_guard: self.raii_guards.1,
380 }, 377 },
381 Properties { 378 Properties {
382 info: self.properties.info, 379 info: self.properties.info,
@@ -385,14 +382,13 @@ impl<'d> Can<'d> {
385 } 382 }
386 /// Join split rx and tx portions back together 383 /// Join split rx and tx portions back together
387 pub fn join(tx: CanTx<'d>, rx: CanRx<'d>) -> Self { 384 pub fn join(tx: CanTx<'d>, rx: CanRx<'d>) -> Self {
388 (tx.info.internal_operation)(InternalOperation::NotifySenderCreated);
389 (tx.info.internal_operation)(InternalOperation::NotifyReceiverCreated);
390 Can { 385 Can {
391 _phantom: PhantomData, 386 _phantom: PhantomData,
392 config: tx.config, 387 config: tx.config,
393 info: tx.info, 388 info: tx.info,
394 _mode: rx._mode, 389 _mode: rx._mode,
395 properties: Properties::new(tx.info), 390 properties: Properties::new(tx.info),
391 raii_guards: (tx.tx_guard, rx.rx_guard),
396 } 392 }
397 } 393 }
398 394
@@ -415,13 +411,6 @@ impl<'d> Can<'d> {
415 } 411 }
416} 412}
417 413
418impl<'d> Drop for Can<'d> {
419 fn drop(&mut self) {
420 (self.info.internal_operation)(InternalOperation::NotifySenderDestroyed);
421 (self.info.internal_operation)(InternalOperation::NotifyReceiverDestroyed);
422 }
423}
424
425/// User supplied buffer for RX Buffering 414/// User supplied buffer for RX Buffering
426pub type RxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, Result<Envelope, BusError>, BUF_SIZE>; 415pub type RxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, Result<Envelope, BusError>, BUF_SIZE>;
427 416
@@ -436,6 +425,7 @@ pub struct BufferedCan<'d, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> {
436 tx_buf: &'static TxBuf<TX_BUF_SIZE>, 425 tx_buf: &'static TxBuf<TX_BUF_SIZE>,
437 rx_buf: &'static RxBuf<RX_BUF_SIZE>, 426 rx_buf: &'static RxBuf<RX_BUF_SIZE>,
438 properties: Properties, 427 properties: Properties,
428 _raii_guards: (TxGuard, RxGuard),
439} 429}
440 430
441impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCan<'d, TX_BUF_SIZE, RX_BUF_SIZE> { 431impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCan<'d, TX_BUF_SIZE, RX_BUF_SIZE> {
@@ -445,8 +435,6 @@ impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCan<'d,
445 tx_buf: &'static TxBuf<TX_BUF_SIZE>, 435 tx_buf: &'static TxBuf<TX_BUF_SIZE>,
446 rx_buf: &'static RxBuf<RX_BUF_SIZE>, 436 rx_buf: &'static RxBuf<RX_BUF_SIZE>,
447 ) -> Self { 437 ) -> Self {
448 (info.internal_operation)(InternalOperation::NotifySenderCreated);
449 (info.internal_operation)(InternalOperation::NotifyReceiverCreated);
450 BufferedCan { 438 BufferedCan {
451 _phantom: PhantomData, 439 _phantom: PhantomData,
452 info, 440 info,
@@ -454,6 +442,10 @@ impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCan<'d,
454 tx_buf, 442 tx_buf,
455 rx_buf, 443 rx_buf,
456 properties: Properties::new(info), 444 properties: Properties::new(info),
445 _raii_guards: (
446 TxGuard::new(info.internal_operation),
447 RxGuard::new(info.internal_operation),
448 ),
457 } 449 }
458 .setup() 450 .setup()
459 } 451 }
@@ -492,31 +484,22 @@ impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCan<'d,
492 484
493 /// Returns a sender that can be used for sending CAN frames. 485 /// Returns a sender that can be used for sending CAN frames.
494 pub fn writer(&self) -> BufferedCanSender { 486 pub fn writer(&self) -> BufferedCanSender {
495 (self.info.internal_operation)(InternalOperation::NotifySenderCreated);
496 BufferedCanSender { 487 BufferedCanSender {
497 tx_buf: self.tx_buf.sender().into(), 488 tx_buf: self.tx_buf.sender().into(),
498 waker: self.info.tx_waker, 489 waker: self.info.tx_waker,
499 internal_operation: self.info.internal_operation, 490 tx_guard: TxGuard::new(self.info.internal_operation),
500 } 491 }
501 } 492 }
502 493
503 /// Returns a receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver. 494 /// Returns a receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver.
504 pub fn reader(&self) -> BufferedCanReceiver { 495 pub fn reader(&self) -> BufferedCanReceiver {
505 (self.info.internal_operation)(InternalOperation::NotifyReceiverCreated);
506 BufferedCanReceiver { 496 BufferedCanReceiver {
507 rx_buf: self.rx_buf.receiver().into(), 497 rx_buf: self.rx_buf.receiver().into(),
508 internal_operation: self.info.internal_operation, 498 rx_guard: RxGuard::new(self.info.internal_operation),
509 } 499 }
510 } 500 }
511} 501}
512 502
513impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> Drop for BufferedCan<'d, TX_BUF_SIZE, RX_BUF_SIZE> {
514 fn drop(&mut self) {
515 (self.info.internal_operation)(InternalOperation::NotifySenderDestroyed);
516 (self.info.internal_operation)(InternalOperation::NotifyReceiverDestroyed);
517 }
518}
519
520/// User supplied buffer for RX Buffering 503/// User supplied buffer for RX Buffering
521pub type RxFdBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, Result<FdEnvelope, BusError>, BUF_SIZE>; 504pub type RxFdBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, Result<FdEnvelope, BusError>, BUF_SIZE>;
522 505
@@ -537,6 +520,7 @@ pub struct BufferedCanFd<'d, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>
537 tx_buf: &'static TxFdBuf<TX_BUF_SIZE>, 520 tx_buf: &'static TxFdBuf<TX_BUF_SIZE>,
538 rx_buf: &'static RxFdBuf<RX_BUF_SIZE>, 521 rx_buf: &'static RxFdBuf<RX_BUF_SIZE>,
539 properties: Properties, 522 properties: Properties,
523 _raii_guards: (TxGuard, RxGuard),
540} 524}
541 525
542impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCanFd<'d, TX_BUF_SIZE, RX_BUF_SIZE> { 526impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCanFd<'d, TX_BUF_SIZE, RX_BUF_SIZE> {
@@ -546,8 +530,6 @@ impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCanFd<'
546 tx_buf: &'static TxFdBuf<TX_BUF_SIZE>, 530 tx_buf: &'static TxFdBuf<TX_BUF_SIZE>,
547 rx_buf: &'static RxFdBuf<RX_BUF_SIZE>, 531 rx_buf: &'static RxFdBuf<RX_BUF_SIZE>,
548 ) -> Self { 532 ) -> Self {
549 (info.internal_operation)(InternalOperation::NotifySenderCreated);
550 (info.internal_operation)(InternalOperation::NotifyReceiverCreated);
551 BufferedCanFd { 533 BufferedCanFd {
552 _phantom: PhantomData, 534 _phantom: PhantomData,
553 info, 535 info,
@@ -555,6 +537,10 @@ impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCanFd<'
555 tx_buf, 537 tx_buf,
556 rx_buf, 538 rx_buf,
557 properties: Properties::new(info), 539 properties: Properties::new(info),
540 _raii_guards: (
541 TxGuard::new(info.internal_operation),
542 RxGuard::new(info.internal_operation),
543 ),
558 } 544 }
559 .setup() 545 .setup()
560 } 546 }
@@ -597,7 +583,7 @@ impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCanFd<'
597 BufferedFdCanSender { 583 BufferedFdCanSender {
598 tx_buf: self.tx_buf.sender().into(), 584 tx_buf: self.tx_buf.sender().into(),
599 waker: self.info.tx_waker, 585 waker: self.info.tx_waker,
600 internal_operation: self.info.internal_operation, 586 tx_guard: TxGuard::new(self.info.internal_operation),
601 } 587 }
602 } 588 }
603 589
@@ -606,23 +592,17 @@ impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCanFd<'
606 (self.info.internal_operation)(InternalOperation::NotifyReceiverCreated); 592 (self.info.internal_operation)(InternalOperation::NotifyReceiverCreated);
607 BufferedFdCanReceiver { 593 BufferedFdCanReceiver {
608 rx_buf: self.rx_buf.receiver().into(), 594 rx_buf: self.rx_buf.receiver().into(),
609 internal_operation: self.info.internal_operation, 595 rx_guard: RxGuard::new(self.info.internal_operation),
610 } 596 }
611 } 597 }
612} 598}
613 599
614impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> Drop for BufferedCanFd<'d, TX_BUF_SIZE, RX_BUF_SIZE> {
615 fn drop(&mut self) {
616 (self.info.internal_operation)(InternalOperation::NotifySenderDestroyed);
617 (self.info.internal_operation)(InternalOperation::NotifyReceiverDestroyed);
618 }
619}
620
621/// FDCAN Rx only Instance 600/// FDCAN Rx only Instance
622pub struct CanRx<'d> { 601pub struct CanRx<'d> {
623 _phantom: PhantomData<&'d ()>, 602 _phantom: PhantomData<&'d ()>,
624 info: &'static Info, 603 info: &'static Info,
625 _mode: OperatingMode, 604 _mode: OperatingMode,
605 rx_guard: RxGuard,
626} 606}
627 607
628impl<'d> CanRx<'d> { 608impl<'d> CanRx<'d> {
@@ -637,18 +617,13 @@ impl<'d> CanRx<'d> {
637 } 617 }
638} 618}
639 619
640impl<'d> Drop for CanRx<'d> {
641 fn drop(&mut self) {
642 (self.info.internal_operation)(InternalOperation::NotifyReceiverDestroyed);
643 }
644}
645
646/// FDCAN Tx only Instance 620/// FDCAN Tx only Instance
647pub struct CanTx<'d> { 621pub struct CanTx<'d> {
648 _phantom: PhantomData<&'d ()>, 622 _phantom: PhantomData<&'d ()>,
649 info: &'static Info, 623 info: &'static Info,
650 config: crate::can::fd::config::FdCanConfig, 624 config: crate::can::fd::config::FdCanConfig,
651 _mode: OperatingMode, 625 _mode: OperatingMode,
626 tx_guard: TxGuard,
652} 627}
653 628
654impl<'c, 'd> CanTx<'d> { 629impl<'c, 'd> CanTx<'d> {
@@ -669,12 +644,6 @@ impl<'c, 'd> CanTx<'d> {
669 } 644 }
670} 645}
671 646
672impl<'d> Drop for CanTx<'d> {
673 fn drop(&mut self) {
674 (self.info.internal_operation)(InternalOperation::NotifySenderDestroyed);
675 }
676}
677
678enum RxMode { 647enum RxMode {
679 NonBuffered(AtomicWaker), 648 NonBuffered(AtomicWaker),
680 ClassicBuffered(super::common::ClassicBufferedRxInner), 649 ClassicBuffered(super::common::ClassicBufferedRxInner),