mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-22 11:33:33 +08:00
Superrefactoring - all time values were replaced with new safer classes from uavcan/time.hpp; generated types were moved away from anonymous namespaces because this makes it impossible to use a type from different compilation units. Some less vital fixes are to follow - see the next few commits
This commit is contained in:
@@ -25,16 +25,11 @@ namespace uavcan
|
||||
template <typename DataSpec, typename DataStruct>
|
||||
class GenericPublisher
|
||||
{
|
||||
public:
|
||||
enum { DefaultTxTimeoutUsec = 2500 }; // 2500 ms --> 400Hz max
|
||||
enum { MinTxTimeoutUsec = 200 };
|
||||
|
||||
private:
|
||||
enum { Qos = (DataTypeKind(DataSpec::DataTypeKind) == DataTypeKindMessage) ?
|
||||
CanTxQueue::Volatile : CanTxQueue::Persistent };
|
||||
|
||||
const uint64_t max_transfer_interval_; // TODO: memory usage can be reduced
|
||||
uint64_t tx_timeout_;
|
||||
const MonotonicDuration max_transfer_interval_; // TODO: memory usage can be reduced
|
||||
MonotonicDuration tx_timeout_;
|
||||
Scheduler& scheduler_;
|
||||
IMarshalBufferProvider& buffer_provider_;
|
||||
LazyConstructor<TransferSender> sender_;
|
||||
@@ -54,12 +49,12 @@ private:
|
||||
UAVCAN_TRACE("GenericPublisher", "Type [%s] is not registered", DataSpec::getDataTypeFullName());
|
||||
return false;
|
||||
}
|
||||
sender_.template construct<Dispatcher&, const DataTypeDescriptor&, CanTxQueue::Qos, uint64_t>
|
||||
sender_.template construct<Dispatcher&, const DataTypeDescriptor&, CanTxQueue::Qos, MonotonicDuration>
|
||||
(scheduler_.getDispatcher(), *descr, CanTxQueue::Qos(Qos), max_transfer_interval_);
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64_t getTxDeadline() const { return scheduler_.getMonotonicTimestamp() + tx_timeout_; }
|
||||
MonotonicTime getTxDeadline() const { return scheduler_.getMonotonicTimestamp() + tx_timeout_; }
|
||||
|
||||
IMarshalBuffer* getBuffer()
|
||||
{
|
||||
@@ -67,7 +62,7 @@ private:
|
||||
}
|
||||
|
||||
int genericPublish(const DataStruct& message, TransferType transfer_type, NodeID dst_node_id,
|
||||
TransferID* tid, uint64_t monotonic_blocking_deadline)
|
||||
TransferID* tid, MonotonicTime blocking_deadline)
|
||||
{
|
||||
if (!checkInit())
|
||||
return -1;
|
||||
@@ -89,20 +84,20 @@ private:
|
||||
if (tid)
|
||||
{
|
||||
return sender_->send(buf->getDataPtr(), buf->getDataLength(), getTxDeadline(),
|
||||
monotonic_blocking_deadline, transfer_type, dst_node_id, *tid);
|
||||
blocking_deadline, transfer_type, dst_node_id, *tid);
|
||||
}
|
||||
else
|
||||
{
|
||||
return sender_->send(buf->getDataPtr(), buf->getDataLength(), getTxDeadline(),
|
||||
monotonic_blocking_deadline, transfer_type, dst_node_id);
|
||||
blocking_deadline, transfer_type, dst_node_id);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
GenericPublisher(Scheduler& scheduler, IMarshalBufferProvider& buffer_provider,
|
||||
uint64_t max_transfer_interval = TransferSender::DefaultMaxTransferInterval)
|
||||
MonotonicDuration max_transfer_interval = TransferSender::getDefaultMaxTransferInterval())
|
||||
: max_transfer_interval_(max_transfer_interval)
|
||||
, tx_timeout_(DefaultTxTimeoutUsec)
|
||||
, tx_timeout_(getDefaultTxTimeout())
|
||||
, scheduler_(scheduler)
|
||||
, buffer_provider_(buffer_provider)
|
||||
{ }
|
||||
@@ -110,22 +105,25 @@ protected:
|
||||
~GenericPublisher() { }
|
||||
|
||||
int publish(const DataStruct& message, TransferType transfer_type, NodeID dst_node_id,
|
||||
uint64_t monotonic_blocking_deadline = 0)
|
||||
MonotonicTime blocking_deadline = MonotonicTime())
|
||||
{
|
||||
return genericPublish(message, transfer_type, dst_node_id, NULL, monotonic_blocking_deadline);
|
||||
return genericPublish(message, transfer_type, dst_node_id, NULL, blocking_deadline);
|
||||
}
|
||||
|
||||
int publish(const DataStruct& message, TransferType transfer_type, NodeID dst_node_id, TransferID tid,
|
||||
uint64_t monotonic_blocking_deadline = 0)
|
||||
MonotonicTime blocking_deadline = MonotonicTime())
|
||||
{
|
||||
return genericPublish(message, transfer_type, dst_node_id, &tid, monotonic_blocking_deadline);
|
||||
return genericPublish(message, transfer_type, dst_node_id, &tid, blocking_deadline);
|
||||
}
|
||||
|
||||
public:
|
||||
uint64_t getTxTimeout() const { return tx_timeout_; }
|
||||
void setTxTimeout(uint64_t usec)
|
||||
static MonotonicDuration getDefaultTxTimeout() { return MonotonicDuration::fromUSec(2500); }// 2500ms --> 400Hz max
|
||||
static MonotonicDuration getMinTxTimeout() { return MonotonicDuration::fromUSec(200); }
|
||||
|
||||
MonotonicDuration getTxTimeout() const { return tx_timeout_; }
|
||||
void setTxTimeout(MonotonicDuration tx_timeout)
|
||||
{
|
||||
tx_timeout_ = std::max(usec, uint64_t(MinTxTimeoutUsec));
|
||||
tx_timeout_ = std::max(tx_timeout, getMinTxTimeout());
|
||||
}
|
||||
|
||||
Scheduler& getScheduler() const { return scheduler_; }
|
||||
|
||||
@@ -45,8 +45,11 @@ protected:
|
||||
public:
|
||||
typedef DataType_ DataType;
|
||||
|
||||
uint64_t getMonotonicTimestamp() const { return safeget<uint64_t, &IncomingTransfer::getMonotonicTimestamp>(); }
|
||||
uint64_t getUtcTimestamp() const { return safeget<uint64_t, &IncomingTransfer::getUtcTimestamp>(); }
|
||||
MonotonicTime getMonotonicTimestamp() const
|
||||
{
|
||||
return safeget<MonotonicTime, &IncomingTransfer::getMonotonicTimestamp>();
|
||||
}
|
||||
UtcTime getUtcTimestamp() const { return safeget<UtcTime, &IncomingTransfer::getUtcTimestamp>(); }
|
||||
TransferType getTransferType() const { return safeget<TransferType, &IncomingTransfer::getTransferType>(); }
|
||||
TransferID getTransferID() const { return safeget<TransferID, &IncomingTransfer::getTransferID>(); }
|
||||
NodeID getSrcNodeID() const { return safeget<NodeID, &IncomingTransfer::getSrcNodeID>(); }
|
||||
|
||||
@@ -14,29 +14,28 @@ class Scheduler;
|
||||
|
||||
class MonotonicDeadlineHandler : public LinkedListNode<MonotonicDeadlineHandler>, Noncopyable
|
||||
{
|
||||
uint64_t monotonic_deadline_;
|
||||
MonotonicTime deadline_;
|
||||
|
||||
protected:
|
||||
Scheduler& scheduler_;
|
||||
|
||||
explicit MonotonicDeadlineHandler(Scheduler& scheduler)
|
||||
: monotonic_deadline_(0)
|
||||
, scheduler_(scheduler)
|
||||
: scheduler_(scheduler)
|
||||
{ }
|
||||
|
||||
virtual ~MonotonicDeadlineHandler() { stop(); }
|
||||
|
||||
public:
|
||||
virtual void handleMonotonicDeadline(uint64_t monotonic_timestamp) = 0;
|
||||
virtual void handleDeadline(MonotonicTime current_timestamp) = 0;
|
||||
|
||||
void startWithDeadline(uint64_t monotonic_deadline);
|
||||
void startWithDelay(uint64_t delay_usec);
|
||||
void startWithDeadline(MonotonicTime deadline);
|
||||
void startWithDelay(MonotonicDuration delay);
|
||||
|
||||
void stop();
|
||||
|
||||
bool isRunning() const;
|
||||
|
||||
uint64_t getMonotonicDeadline() const { return monotonic_deadline_; }
|
||||
MonotonicTime getDeadline() const { return deadline_; }
|
||||
Scheduler& getScheduler() const { return scheduler_; }
|
||||
};
|
||||
|
||||
@@ -51,8 +50,8 @@ public:
|
||||
bool doesExist(const MonotonicDeadlineHandler* mdh) const;
|
||||
unsigned int getNumHandlers() const { return handlers_.getLength(); }
|
||||
|
||||
uint64_t pollAndGetMonotonicTimestamp(ISystemClock& sysclock);
|
||||
uint64_t getEarliestDeadline() const;
|
||||
MonotonicTime pollAndGetMonotonicTimestamp(ISystemClock& sysclock);
|
||||
MonotonicTime getEarliestDeadline() const;
|
||||
};
|
||||
|
||||
|
||||
@@ -68,45 +67,45 @@ class Scheduler : Noncopyable
|
||||
|
||||
MonotonicDeadlineScheduler deadline_scheduler_;
|
||||
Dispatcher dispatcher_;
|
||||
uint64_t prev_cleanup_ts_;
|
||||
uint64_t monotonic_deadline_resolution_;
|
||||
uint64_t cleanup_period_;
|
||||
MonotonicTime prev_cleanup_ts_;
|
||||
MonotonicDuration deadline_resolution_;
|
||||
MonotonicDuration cleanup_period_;
|
||||
|
||||
uint64_t computeDispatcherSpinDeadline(uint64_t spin_deadline) const;
|
||||
void pollCleanup(uint64_t mono_ts, uint32_t num_frames_processed_with_last_spin);
|
||||
MonotonicTime computeDispatcherSpinDeadline(MonotonicTime spin_deadline) const;
|
||||
void pollCleanup(MonotonicTime mono_ts, uint32_t num_frames_processed_with_last_spin);
|
||||
|
||||
public:
|
||||
Scheduler(ICanDriver& can_driver, IAllocator& allocator, ISystemClock& sysclock, IOutgoingTransferRegistry& otr,
|
||||
NodeID self_node_id)
|
||||
: dispatcher_(can_driver, allocator, sysclock, otr, self_node_id)
|
||||
, prev_cleanup_ts_(sysclock.getMonotonicMicroseconds())
|
||||
, monotonic_deadline_resolution_(DefaultMonotonicDeadlineResolutionMs * 1000)
|
||||
, cleanup_period_(DefaultCleanupPeriodMs * 1000)
|
||||
, prev_cleanup_ts_(sysclock.getMonotonic())
|
||||
, deadline_resolution_(MonotonicDuration::fromMSec(DefaultMonotonicDeadlineResolutionMs))
|
||||
, cleanup_period_(MonotonicDuration::fromMSec(DefaultCleanupPeriodMs))
|
||||
{ }
|
||||
|
||||
int spin(uint64_t monotonic_deadline);
|
||||
int spin(MonotonicTime deadline);
|
||||
|
||||
MonotonicDeadlineScheduler& getMonotonicDeadlineScheduler() { return deadline_scheduler_; }
|
||||
Dispatcher& getDispatcher() { return dispatcher_; }
|
||||
|
||||
ISystemClock& getSystemClock() { return dispatcher_.getSystemClock(); }
|
||||
uint64_t getMonotonicTimestamp() const { return dispatcher_.getSystemClock().getMonotonicMicroseconds(); }
|
||||
uint64_t getUtcTimestamp() const { return dispatcher_.getSystemClock().getUtcMicroseconds(); }
|
||||
ISystemClock& getSystemClock() { return dispatcher_.getSystemClock(); }
|
||||
MonotonicTime getMonotonicTimestamp() const { return dispatcher_.getSystemClock().getMonotonic(); }
|
||||
UtcTime getUtcTimestamp() const { return dispatcher_.getSystemClock().getUtc(); }
|
||||
|
||||
uint64_t getMonotonicDeadlineResolution() const { return monotonic_deadline_resolution_; }
|
||||
void setMonotonicDeadlineResolution(uint64_t res_usec)
|
||||
MonotonicDuration getMonotonicDeadlineResolution() const { return deadline_resolution_; }
|
||||
void setMonotonicDeadlineResolution(MonotonicDuration res)
|
||||
{
|
||||
res_usec = std::min(res_usec, MaxMonotonicDeadlineResolutionMs * uint64_t(1000));
|
||||
res_usec = std::max(res_usec, MinMonotonicDeadlineResolutionMs * uint64_t(1000));
|
||||
monotonic_deadline_resolution_ = res_usec;
|
||||
res = std::min(res, MonotonicDuration::fromMSec(MaxMonotonicDeadlineResolutionMs));
|
||||
res = std::max(res, MonotonicDuration::fromMSec(MinMonotonicDeadlineResolutionMs));
|
||||
deadline_resolution_ = res;
|
||||
}
|
||||
|
||||
uint64_t getCleanupPeriod() const { return cleanup_period_; }
|
||||
void setCleanupPeriod(uint64_t period_usec)
|
||||
MonotonicDuration getCleanupPeriod() const { return cleanup_period_; }
|
||||
void setCleanupPeriod(MonotonicDuration period)
|
||||
{
|
||||
period_usec = std::min(period_usec, MaxCleanupPeriodMs * uint64_t(1000));
|
||||
period_usec = std::max(period_usec, MinCleanupPeriodMs * uint64_t(1000));
|
||||
cleanup_period_ = period_usec;
|
||||
period = std::min(period, MonotonicDuration::fromMSec(MaxCleanupPeriodMs));
|
||||
period = std::max(period, MonotonicDuration::fromMSec(MinCleanupPeriodMs));
|
||||
cleanup_period_ = period;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user