mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-11 09:33:34 +08:00
Lazy initialization of TransferSender removed
This commit is contained in:
@@ -9,7 +9,6 @@
|
||||
#include <uavcan/node/abstract_node.hpp>
|
||||
#include <uavcan/data_type.hpp>
|
||||
#include <uavcan/node/global_data_type_registry.hpp>
|
||||
#include <uavcan/util/lazy_constructor.hpp>
|
||||
#include <uavcan/debug.hpp>
|
||||
#include <uavcan/transport/transfer_sender.hpp>
|
||||
#include <uavcan/marshal/scalar_codec.hpp>
|
||||
@@ -20,15 +19,14 @@ namespace uavcan
|
||||
|
||||
class GenericPublisherBase : Noncopyable
|
||||
{
|
||||
const MonotonicDuration max_transfer_interval_; // TODO: memory usage can be reduced
|
||||
TransferSender sender_;
|
||||
MonotonicDuration tx_timeout_;
|
||||
INode& node_;
|
||||
LazyConstructor<TransferSender> sender_;
|
||||
|
||||
protected:
|
||||
GenericPublisherBase(INode& node, MonotonicDuration tx_timeout,
|
||||
MonotonicDuration max_transfer_interval)
|
||||
: max_transfer_interval_(max_transfer_interval)
|
||||
: sender_(node.getDispatcher(), max_transfer_interval)
|
||||
, tx_timeout_(tx_timeout)
|
||||
, node_(node)
|
||||
{
|
||||
@@ -51,7 +49,8 @@ protected:
|
||||
int genericPublish(const IMarshalBuffer& buffer, TransferType transfer_type, NodeID dst_node_id,
|
||||
TransferID* tid, MonotonicTime blocking_deadline);
|
||||
|
||||
TransferSender* getTransferSender();
|
||||
TransferSender& getTransferSender() { return sender_; }
|
||||
const TransferSender& getTransferSender() const { return sender_; }
|
||||
|
||||
public:
|
||||
static MonotonicDuration getMinTxTimeout() { return MonotonicDuration::fromUSec(200); }
|
||||
@@ -66,7 +65,7 @@ public:
|
||||
*/
|
||||
void allowAnonymousTransfers()
|
||||
{
|
||||
sender_->allowAnonymousTransfers();
|
||||
sender_.allowAnonymousTransfers();
|
||||
}
|
||||
|
||||
INode& getNode() const { return node_; }
|
||||
@@ -124,12 +123,6 @@ public:
|
||||
{
|
||||
return genericPublish(message, transfer_type, dst_node_id, &tid, blocking_deadline);
|
||||
}
|
||||
|
||||
TransferSender* getTransferSender()
|
||||
{
|
||||
(void)checkInit();
|
||||
return GenericPublisherBase::getTransferSender();
|
||||
}
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
@@ -81,46 +81,20 @@ public:
|
||||
|
||||
/**
|
||||
* Returns priority of outgoing transfers.
|
||||
* TODO: Make const.
|
||||
*/
|
||||
TransferPriority getPriority()
|
||||
TransferPriority getPriority() const
|
||||
{
|
||||
// TODO probably TransferSender must be transformed into regular field?
|
||||
TransferSender* const ts = getTransferSender();
|
||||
if (ts != NULL)
|
||||
{
|
||||
return ts->getPriority();
|
||||
}
|
||||
else
|
||||
{
|
||||
return TransferPriorityNormal; // This is default
|
||||
}
|
||||
return BaseType::getTransferSender().getPriority();
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to change the priority of outgoing transfers.
|
||||
* Note that only High, Normal and Low priorities can be used; Service priority is not available for messages.
|
||||
* Returns negative error code if priority cannot be set, non-negative on success.
|
||||
* If the priority value is invalid, an assertion failure will be generated, and the value will not be updated.
|
||||
*/
|
||||
int setPriority(const TransferPriority prio)
|
||||
void setPriority(const TransferPriority prio)
|
||||
{
|
||||
if (prio < NumTransferPriorities && prio != TransferPriorityService)
|
||||
{
|
||||
TransferSender* const ts = getTransferSender(); // TODO: Static TransferSender?
|
||||
if (ts != NULL)
|
||||
{
|
||||
ts->setPriority(prio);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -ErrLogic;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return -ErrInvalidParam;
|
||||
}
|
||||
BaseType::getTransferSender().setPriority(prio);
|
||||
}
|
||||
|
||||
static MonotonicDuration getDefaultTxTimeout() { return MonotonicDuration::fromMSec(10); }
|
||||
|
||||
@@ -51,16 +51,9 @@ class UAVCAN_EXPORT GlobalTimeSyncMaster : protected LoopbackFrameListenerBase
|
||||
const int res = pub_.init();
|
||||
if (res >= 0)
|
||||
{
|
||||
TransferSender* const ts = pub_.getTransferSender();
|
||||
UAVCAN_ASSERT(ts != NULL);
|
||||
ts->setIfaceMask(uint8_t(1 << iface_index_));
|
||||
ts->setCanIOFlags(CanIOFlagLoopback);
|
||||
|
||||
const int prio_res = pub_.setPriority(TransferPriorityHigh); // Fixed priority
|
||||
if (prio_res < 0)
|
||||
{
|
||||
return prio_res;
|
||||
}
|
||||
pub_.getTransferSender().setIfaceMask(uint8_t(1 << iface_index_));
|
||||
pub_.getTransferSender().setCanIOFlags(CanIOFlagLoopback);
|
||||
pub_.setPriority(TransferPriorityHigh); // Fixed priority
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@@ -84,8 +77,8 @@ class UAVCAN_EXPORT GlobalTimeSyncMaster : protected LoopbackFrameListenerBase
|
||||
|
||||
int publish(TransferID tid, MonotonicTime current_time)
|
||||
{
|
||||
UAVCAN_ASSERT(pub_.getTransferSender()->getCanIOFlags() == CanIOFlagLoopback);
|
||||
UAVCAN_ASSERT(pub_.getTransferSender()->getIfaceMask() == (1 << iface_index_));
|
||||
UAVCAN_ASSERT(pub_.getTransferSender().getCanIOFlags() == CanIOFlagLoopback);
|
||||
UAVCAN_ASSERT(pub_.getTransferSender().getIfaceMask() == (1 << iface_index_));
|
||||
|
||||
const MonotonicDuration since_prev_pub = current_time - iface_prev_pub_mono_;
|
||||
iface_prev_pub_mono_ = current_time;
|
||||
|
||||
@@ -101,7 +101,8 @@ public:
|
||||
{
|
||||
return res;
|
||||
}
|
||||
return logmsg_pub_.setPriority(TransferPriorityLow); // Fixed priority
|
||||
logmsg_pub_.setPriority(TransferPriorityLow); // Fixed priority
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,10 +20,10 @@ namespace uavcan
|
||||
class UAVCAN_EXPORT TransferSender
|
||||
{
|
||||
const MonotonicDuration max_transfer_interval_;
|
||||
const DataTypeDescriptor& data_type_;
|
||||
DataTypeID data_type_id_;
|
||||
TransferPriority priority_;
|
||||
const CanTxQueue::Qos qos_;
|
||||
const TransferCRC crc_base_;
|
||||
CanTxQueue::Qos qos_;
|
||||
TransferCRC crc_base_;
|
||||
CanIOFlags flags_;
|
||||
uint8_t iface_mask_;
|
||||
bool allow_anonymous_transfers_;
|
||||
@@ -43,16 +43,30 @@ public:
|
||||
TransferSender(Dispatcher& dispatcher, const DataTypeDescriptor& data_type, CanTxQueue::Qos qos,
|
||||
MonotonicDuration max_transfer_interval = getDefaultMaxTransferInterval())
|
||||
: max_transfer_interval_(max_transfer_interval)
|
||||
, data_type_(data_type)
|
||||
, priority_(TransferPriorityNormal)
|
||||
, qos_(qos)
|
||||
, crc_base_(data_type.getSignature().toTransferCRC())
|
||||
, qos_(CanTxQueue::Qos())
|
||||
, flags_(CanIOFlags(0))
|
||||
, iface_mask_(AllIfacesMask)
|
||||
, allow_anonymous_transfers_(false)
|
||||
, dispatcher_(dispatcher)
|
||||
{
|
||||
init(data_type, qos);
|
||||
}
|
||||
|
||||
TransferSender(Dispatcher& dispatcher, MonotonicDuration max_transfer_interval = getDefaultMaxTransferInterval())
|
||||
: max_transfer_interval_(max_transfer_interval)
|
||||
, priority_(TransferPriorityNormal)
|
||||
, qos_(CanTxQueue::Qos())
|
||||
, flags_(CanIOFlags(0))
|
||||
, iface_mask_(AllIfacesMask)
|
||||
, allow_anonymous_transfers_(false)
|
||||
, dispatcher_(dispatcher)
|
||||
{ }
|
||||
|
||||
void init(const DataTypeDescriptor& dtid, CanTxQueue::Qos qos);
|
||||
|
||||
bool isInitialized() const { return data_type_id_ != DataTypeID(); }
|
||||
|
||||
CanIOFlags getCanIOFlags() const { return flags_; }
|
||||
void setCanIOFlags(CanIOFlags flags) { flags_ = flags; }
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace uavcan
|
||||
|
||||
bool GenericPublisherBase::isInited() const
|
||||
{
|
||||
return bool(sender_);
|
||||
return sender_.isInitialized();
|
||||
}
|
||||
|
||||
int GenericPublisherBase::doInit(DataTypeKind dtkind, const char* dtname, CanTxQueue::Qos qos)
|
||||
@@ -22,13 +22,14 @@ int GenericPublisherBase::doInit(DataTypeKind dtkind, const char* dtname, CanTxQ
|
||||
GlobalDataTypeRegistry::instance().freeze();
|
||||
|
||||
const DataTypeDescriptor* const descr = GlobalDataTypeRegistry::instance().find(dtkind, dtname);
|
||||
if (!descr)
|
||||
if (descr == NULL)
|
||||
{
|
||||
UAVCAN_TRACE("GenericPublisher", "Type [%s] is not registered", dtname);
|
||||
return -ErrUnknownDataType;
|
||||
}
|
||||
sender_.construct<Dispatcher&, const DataTypeDescriptor&, CanTxQueue::Qos, MonotonicDuration>
|
||||
(node_.getDispatcher(), *descr, qos, max_transfer_interval_);
|
||||
|
||||
sender_.init(*descr, qos);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -47,21 +48,16 @@ int GenericPublisherBase::genericPublish(const IMarshalBuffer& buffer, TransferT
|
||||
{
|
||||
if (tid)
|
||||
{
|
||||
return sender_->send(buffer.getDataPtr(), buffer.getMaxWritePos(), getTxDeadline(),
|
||||
blocking_deadline, transfer_type, dst_node_id, *tid);
|
||||
return sender_.send(buffer.getDataPtr(), buffer.getMaxWritePos(), getTxDeadline(),
|
||||
blocking_deadline, transfer_type, dst_node_id, *tid);
|
||||
}
|
||||
else
|
||||
{
|
||||
return sender_->send(buffer.getDataPtr(), buffer.getMaxWritePos(), getTxDeadline(),
|
||||
blocking_deadline, transfer_type, dst_node_id);
|
||||
return sender_.send(buffer.getDataPtr(), buffer.getMaxWritePos(), getTxDeadline(),
|
||||
blocking_deadline, transfer_type, dst_node_id);
|
||||
}
|
||||
}
|
||||
|
||||
TransferSender* GenericPublisherBase::getTransferSender()
|
||||
{
|
||||
return sender_.isConstructed() ? static_cast<TransferSender*>(sender_) : NULL;
|
||||
}
|
||||
|
||||
void GenericPublisherBase::setTxTimeout(MonotonicDuration tx_timeout)
|
||||
{
|
||||
tx_timeout = max(tx_timeout, getMinTxTimeout());
|
||||
|
||||
@@ -160,11 +160,7 @@ int DynamicNodeIDClient::start(const protocol::HardwareVersion& hardware_version
|
||||
return res;
|
||||
}
|
||||
dnida_pub_.allowAnonymousTransfers();
|
||||
res = dnida_pub_.setPriority(transfer_priority);
|
||||
if (res < 0)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
dnida_pub_.setPriority(transfer_priority);
|
||||
|
||||
res = dnida_sub_.start(AllocationCallback(this, &DynamicNodeIDClient::handleAllocation));
|
||||
if (res < 0)
|
||||
|
||||
@@ -71,11 +71,7 @@ int NodeStatusProvider::startAndPublish(TransferPriority priority)
|
||||
|
||||
int res = -1;
|
||||
|
||||
res = node_status_pub_.setPriority(priority);
|
||||
if (res < 0)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
node_status_pub_.setPriority(priority);
|
||||
|
||||
if (!getNode().isPassiveMode())
|
||||
{
|
||||
|
||||
@@ -15,6 +15,15 @@ void TransferSender::registerError() const
|
||||
dispatcher_.getTransferPerfCounter().addError();
|
||||
}
|
||||
|
||||
void TransferSender::init(const DataTypeDescriptor& dtid, CanTxQueue::Qos qos)
|
||||
{
|
||||
UAVCAN_ASSERT(!isInitialized());
|
||||
|
||||
qos_ = qos;
|
||||
data_type_id_ = dtid.getID();
|
||||
crc_base_ = dtid.getSignature().toTransferCRC();
|
||||
}
|
||||
|
||||
int TransferSender::send(const uint8_t* payload, unsigned payload_len, MonotonicTime tx_deadline,
|
||||
MonotonicTime blocking_deadline, TransferType transfer_type, NodeID dst_node_id,
|
||||
TransferID tid) const
|
||||
@@ -24,7 +33,7 @@ int TransferSender::send(const uint8_t* payload, unsigned payload_len, Monotonic
|
||||
return -ErrTransferTooLong;
|
||||
}
|
||||
|
||||
Frame frame(data_type_.getID(), transfer_type, dispatcher_.getNodeID(), dst_node_id, 0, tid);
|
||||
Frame frame(data_type_id_, transfer_type, dispatcher_.getNodeID(), dst_node_id, 0, tid);
|
||||
if (transfer_type == TransferTypeMessageBroadcast ||
|
||||
transfer_type == TransferTypeMessageUnicast)
|
||||
{
|
||||
@@ -143,7 +152,7 @@ int TransferSender::send(const uint8_t* payload, unsigned payload_len, Monotonic
|
||||
/*
|
||||
* TODO: TID is not needed for anonymous transfers, this part of the code can be skipped?
|
||||
*/
|
||||
const OutgoingTransferRegistryKey otr_key(data_type_.getID(), transfer_type, dst_node_id);
|
||||
const OutgoingTransferRegistryKey otr_key(data_type_id_, transfer_type, dst_node_id);
|
||||
|
||||
UAVCAN_ASSERT(!tx_deadline.isZero());
|
||||
const MonotonicTime otr_deadline = tx_deadline + max_transfer_interval_;
|
||||
@@ -151,8 +160,8 @@ int TransferSender::send(const uint8_t* payload, unsigned payload_len, Monotonic
|
||||
TransferID* const tid = dispatcher_.getOutgoingTransferRegistry().accessOrCreate(otr_key, otr_deadline);
|
||||
if (tid == NULL)
|
||||
{
|
||||
UAVCAN_TRACE("TransferSender", "OTR access failure, dtd=%s tt=%i",
|
||||
data_type_.toString().c_str(), int(transfer_type));
|
||||
UAVCAN_TRACE("TransferSender", "OTR access failure, dtid=%d tt=%i",
|
||||
int(data_type_id_.get()), int(transfer_type));
|
||||
return -ErrMemory;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@ TEST(Publisher, Basic)
|
||||
|
||||
uavcan::Publisher<uavcan::mavlink::Message> publisher(node);
|
||||
|
||||
ASSERT_FALSE(publisher.getTransferSender().isInitialized());
|
||||
|
||||
std::cout <<
|
||||
"sizeof(uavcan::Publisher<uavcan::mavlink::Message>): " <<
|
||||
sizeof(uavcan::Publisher<uavcan::mavlink::Message>) << std::endl;
|
||||
@@ -110,18 +112,5 @@ TEST(Publisher, Basic)
|
||||
* Misc
|
||||
*/
|
||||
ASSERT_TRUE(uavcan::GlobalDataTypeRegistry::instance().isFrozen());
|
||||
ASSERT_TRUE(publisher.getTransferSender());
|
||||
}
|
||||
|
||||
|
||||
TEST(Publisher, ImplicitInitialization)
|
||||
{
|
||||
SystemClockMock clock_mock(100);
|
||||
CanDriverMock can_driver(2, clock_mock);
|
||||
TestNode node(can_driver, clock_mock, 1);
|
||||
|
||||
uavcan::Publisher<uavcan::mavlink::Message> publisher(node);
|
||||
|
||||
// Will be initialized ad-hoc
|
||||
ASSERT_TRUE(publisher.getTransferSender());
|
||||
ASSERT_TRUE(publisher.getTransferSender().isInitialized());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user