mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-13 18:33:33 +08:00
CanIOFlagAbortOnError - automatically enforced by TransferSender if the node is in passive mode
This commit is contained in:
@@ -114,9 +114,17 @@ struct UAVCAN_EXPORT CanSelectMasks
|
||||
|
||||
/**
|
||||
* Special IO flags.
|
||||
*
|
||||
* @ref CanIOFlagLoopback - Send the frame back to RX with true TX timestamps.
|
||||
*
|
||||
* @ref CanIOFlagAbortOnError - Abort transmission on first bus error instead of retransmitting. This does not
|
||||
* affect the case of arbitration loss, in which case the retransmission will work
|
||||
* as usual. This flag is used together with anonymous messages which allows to
|
||||
* implement CSMA bus access. Read the spec for details.
|
||||
*/
|
||||
typedef uint16_t CanIOFlags;
|
||||
static const CanIOFlags CanIOFlagLoopback = 1; ///< Send the frame back to RX with true TX timestamps
|
||||
static const CanIOFlags CanIOFlagLoopback = 1;
|
||||
static const CanIOFlags CanIOFlagAbortOnError = 2;
|
||||
|
||||
/**
|
||||
* Single non-blocking CAN interface.
|
||||
|
||||
@@ -100,6 +100,10 @@ public:
|
||||
|
||||
/**
|
||||
* Send with automatic Transfer ID.
|
||||
*
|
||||
* Note that as long as the local node operates in passive mode, the
|
||||
* flag @ref CanIOFlagAbortOnError will be set implicitly for all outgoing frames.
|
||||
*
|
||||
* TID is managed by OutgoingTransferRegistry.
|
||||
*/
|
||||
int send(const uint8_t* payload, unsigned payload_len, MonotonicTime tx_deadline,
|
||||
|
||||
@@ -69,10 +69,15 @@ int TransferSender::send(const uint8_t* payload, unsigned payload_len, Monotonic
|
||||
frame.setEndOfTransfer(true);
|
||||
UAVCAN_ASSERT(frame.isStartOfTransfer() && frame.isEndOfTransfer() && !frame.getToggle());
|
||||
|
||||
return dispatcher_.send(frame, tx_deadline, blocking_deadline, qos_, flags_, iface_mask_);
|
||||
const CanIOFlags flags = frame.getSrcNodeID().isUnicast() ? flags_ : (flags_ | CanIOFlagAbortOnError);
|
||||
|
||||
return dispatcher_.send(frame, tx_deadline, blocking_deadline, qos_, flags, iface_mask_);
|
||||
}
|
||||
else // Multi Frame Transfer
|
||||
{
|
||||
UAVCAN_ASSERT(!dispatcher_.isPassiveMode());
|
||||
UAVCAN_ASSERT(frame.getSrcNodeID().isUnicast());
|
||||
|
||||
int offset = 0;
|
||||
{
|
||||
TransferCRC crc = crc_base_;
|
||||
|
||||
@@ -23,21 +23,25 @@ public:
|
||||
uavcan::CanFrame frame;
|
||||
uavcan::MonotonicTime time;
|
||||
uavcan::UtcTime time_utc;
|
||||
uavcan::CanIOFlags flags;
|
||||
|
||||
FrameWithTime(const uavcan::CanFrame& frame, uavcan::MonotonicTime time)
|
||||
: frame(frame)
|
||||
, time(time)
|
||||
, flags(0)
|
||||
{ }
|
||||
|
||||
FrameWithTime(const uavcan::CanFrame& frame, uavcan::MonotonicTime time, uavcan::UtcTime time_utc)
|
||||
: frame(frame)
|
||||
, time(time)
|
||||
, time_utc(time_utc)
|
||||
, flags(0)
|
||||
{ }
|
||||
|
||||
FrameWithTime(const uavcan::CanFrame& frame, uint64_t time_usec)
|
||||
: frame(frame)
|
||||
, time(uavcan::MonotonicTime::fromUSec(time_usec))
|
||||
, flags(0)
|
||||
{ }
|
||||
};
|
||||
|
||||
@@ -115,6 +119,7 @@ public:
|
||||
return 0;
|
||||
}
|
||||
tx.push(FrameWithTime(frame, tx_deadline));
|
||||
tx.back().flags = flags;
|
||||
if (flags & uavcan::CanIOFlagLoopback)
|
||||
{
|
||||
loopback.push(FrameWithTime(frame, iclock.getMonotonic()));
|
||||
@@ -126,7 +131,6 @@ public:
|
||||
uavcan::UtcTime& out_ts_utc, uavcan::CanIOFlags& out_flags)
|
||||
{
|
||||
assert(this);
|
||||
out_flags = uavcan::CanIOFlags();
|
||||
if (loopback.empty())
|
||||
{
|
||||
EXPECT_TRUE(rx.size()); // Shall never be called when not readable
|
||||
@@ -143,6 +147,7 @@ public:
|
||||
out_frame = frame.frame;
|
||||
out_ts_monotonic = frame.time;
|
||||
out_ts_utc = frame.time_utc;
|
||||
out_flags = frame.flags;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -151,6 +156,7 @@ public:
|
||||
loopback.pop();
|
||||
out_frame = frame.frame;
|
||||
out_ts_monotonic = frame.time;
|
||||
out_ts_utc = frame.time_utc;
|
||||
}
|
||||
|
||||
// Let's just all pretend that this code is autogenerated, instead of being carefully designed by a human.
|
||||
|
||||
@@ -257,6 +257,10 @@ TEST(TransferSender, PassiveMode)
|
||||
sender.send(Payload, sizeof(Payload), tsMono(1000), uavcan::MonotonicTime(),
|
||||
uavcan::TransferTypeServiceRequest, uavcan::NodeID(42)));
|
||||
|
||||
// Making sure the abort flag is set
|
||||
ASSERT_FALSE(driver.ifaces.at(0).tx.empty());
|
||||
ASSERT_EQ(uavcan::CanIOFlagAbortOnError, driver.ifaces.at(0).tx.front().flags);
|
||||
|
||||
EXPECT_EQ(0, dispatcher.getTransferPerfCounter().getErrorCount());
|
||||
EXPECT_EQ(1, dispatcher.getTransferPerfCounter().getTxTransferCount());
|
||||
EXPECT_EQ(0, dispatcher.getTransferPerfCounter().getRxTransferCount());
|
||||
|
||||
Reference in New Issue
Block a user