mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-19 08:43: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:
@@ -10,6 +10,7 @@
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <uavcan/internal/impl_constants.hpp>
|
||||
#include <uavcan/system_clock.hpp>
|
||||
|
||||
namespace uavcan
|
||||
{
|
||||
@@ -87,10 +88,10 @@ public:
|
||||
|
||||
/**
|
||||
* Non-blocking transmission.
|
||||
* If the frame wasn't transmitted upon TX timeout expiration, the driver should discard it.
|
||||
* If the frame wasn't transmitted upon TX deadline, the driver should discard it.
|
||||
* @return 1 = one frame transmitted, 0 = TX buffer full, negative for error.
|
||||
*/
|
||||
virtual int send(const CanFrame& frame, uint64_t tx_timeout_usec) = 0;
|
||||
virtual int send(const CanFrame& frame, MonotonicTime tx_deadline) = 0;
|
||||
|
||||
/**
|
||||
* Non-blocking reception.
|
||||
@@ -100,11 +101,11 @@ public:
|
||||
* UTC timestamp is optional, if available it will be used for precise time synchronization;
|
||||
* must be set to zero if not available.
|
||||
* Refer to @ref ISystemClock to learn more about timestamps.
|
||||
* @param [out] out_ts_monotonic_usec Monotonic timestamp, usec, mandatory.
|
||||
* @param [out] out_ts_utc_usec UTC timestamp, usec, optional, zero if unknown.
|
||||
* @param [out] out_ts_monotonic Monotonic timestamp, mandatory.
|
||||
* @param [out] out_ts_utc UTC timestamp, optional, zero if unknown.
|
||||
* @return 1 = one frame received, 0 = RX buffer empty, negative for error.
|
||||
*/
|
||||
virtual int receive(CanFrame& out_frame, uint64_t& out_ts_monotonic_usec, uint64_t& out_ts_utc_usec) = 0;
|
||||
virtual int receive(CanFrame& out_frame, MonotonicTime& out_ts_monotonic, UtcTime& out_ts_utc) = 0;
|
||||
|
||||
/**
|
||||
* Configure the hardware CAN filters. @ref CanFilterConfig.
|
||||
@@ -142,15 +143,15 @@ public:
|
||||
virtual int getNumIfaces() const = 0;
|
||||
|
||||
/**
|
||||
* Block until the blocking timeout expires, or one of the specified interfaces becomes available for read or write.
|
||||
* Block until the deadline, or one of the specified interfaces becomes available for read or write.
|
||||
* Iface masks will be modified by the driver to indicate which exactly interfaces are available for IO.
|
||||
* Bit position in the masks defines interface index.
|
||||
* @param [in,out] inout_write_iface_mask Mask indicating which interfaces are needed/available to write.
|
||||
* @param [in,out] inout_read_iface_mask Same as above for reading.
|
||||
* @param [in] timeout_usec Zero means non-blocking operation.
|
||||
* @param [in] blocking_deadline Zero means non-blocking operation.
|
||||
* @return Positive number of ready interfaces or negative error code.
|
||||
*/
|
||||
virtual int select(int& inout_write_iface_mask, int& inout_read_iface_mask, uint64_t timeout_usec) = 0;
|
||||
virtual int select(int& inout_write_iface_mask, int& inout_read_iface_mask, MonotonicTime blocking_deadline) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -8,12 +8,13 @@
|
||||
#include <cstring>
|
||||
#include <stdint.h>
|
||||
#include <algorithm>
|
||||
#include <uavcan/internal/transport/crc.hpp>
|
||||
#include <uavcan/internal/transport/transfer.hpp>
|
||||
|
||||
namespace uavcan
|
||||
{
|
||||
|
||||
class TransferCRC;
|
||||
|
||||
enum DataTypeKind
|
||||
{
|
||||
DataTypeKindService,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -13,20 +13,19 @@
|
||||
#include <uavcan/util/compile_time.hpp>
|
||||
#include <uavcan/can_driver.hpp>
|
||||
#include <uavcan/system_clock.hpp>
|
||||
#include <uavcan/time.hpp>
|
||||
|
||||
namespace uavcan
|
||||
{
|
||||
|
||||
struct CanRxFrame : public CanFrame
|
||||
{
|
||||
uint64_t ts_monotonic;
|
||||
uint64_t ts_utc;
|
||||
MonotonicTime ts_mono;
|
||||
UtcTime ts_utc;
|
||||
uint8_t iface_index;
|
||||
|
||||
CanRxFrame()
|
||||
: ts_monotonic(0)
|
||||
, ts_utc(0)
|
||||
, iface_index(0)
|
||||
: iface_index(0)
|
||||
{ }
|
||||
|
||||
std::string toString(StringRepresentation mode = StrTight) const;
|
||||
@@ -40,12 +39,12 @@ public:
|
||||
|
||||
struct Entry : public LinkedListNode<Entry> // Not required to be packed - fits the block in any case
|
||||
{
|
||||
uint64_t monotonic_deadline;
|
||||
MonotonicTime deadline;
|
||||
CanFrame frame;
|
||||
uint8_t qos;
|
||||
|
||||
Entry(const CanFrame& frame, uint64_t monotonic_deadline, Qos qos)
|
||||
: monotonic_deadline(monotonic_deadline)
|
||||
Entry(const CanFrame& frame, MonotonicTime deadline, Qos qos)
|
||||
: deadline(deadline)
|
||||
, frame(frame)
|
||||
, qos(uint8_t(qos))
|
||||
{
|
||||
@@ -55,7 +54,7 @@ public:
|
||||
|
||||
static void destroy(Entry*& obj, IAllocator& allocator);
|
||||
|
||||
bool isExpired(uint64_t monotonic_timestamp) const { return monotonic_timestamp > monotonic_deadline; }
|
||||
bool isExpired(MonotonicTime timestamp) const { return timestamp > deadline; }
|
||||
|
||||
bool qosHigherThan(const CanFrame& rhs_frame, Qos rhs_qos) const;
|
||||
bool qosLowerThan(const CanFrame& rhs_frame, Qos rhs_qos) const;
|
||||
@@ -100,7 +99,7 @@ public:
|
||||
|
||||
~CanTxQueue();
|
||||
|
||||
void push(const CanFrame& frame, uint64_t monotonic_tx_deadline, Qos qos);
|
||||
void push(const CanFrame& frame, MonotonicTime tx_deadline, Qos qos);
|
||||
|
||||
Entry* peek(); // Modifier
|
||||
void remove(Entry*& entry);
|
||||
@@ -128,10 +127,9 @@ private:
|
||||
CanIOManager(CanIOManager&);
|
||||
CanIOManager& operator=(CanIOManager&);
|
||||
|
||||
int sendToIface(int iface_index, const CanFrame& frame, uint64_t monotonic_tx_deadline);
|
||||
int sendToIface(int iface_index, const CanFrame& frame, MonotonicTime tx_deadline);
|
||||
int sendFromTxQueue(int iface_index);
|
||||
int makePendingTxMask() const;
|
||||
uint64_t getTimeUntilMonotonicDeadline(uint64_t monotonic_deadline) const;
|
||||
|
||||
public:
|
||||
CanIOManager(ICanDriver& driver, IAllocator& allocator, ISystemClock& sysclock)
|
||||
@@ -157,9 +155,9 @@ public:
|
||||
* 1+ - sent/received
|
||||
* negative - failure
|
||||
*/
|
||||
int send(const CanFrame& frame, uint64_t monotonic_tx_deadline, uint64_t monotonic_blocking_deadline,
|
||||
int send(const CanFrame& frame, MonotonicTime tx_deadline, MonotonicTime blocking_deadline,
|
||||
int iface_mask, CanTxQueue::Qos qos);
|
||||
int receive(CanRxFrame& frame, uint64_t monotonic_blocking_deadline);
|
||||
int receive(CanRxFrame& frame, MonotonicTime blocking_deadline);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ class Dispatcher : Noncopyable
|
||||
|
||||
bool add(TransferListenerBase* listener, Mode mode);
|
||||
void remove(TransferListenerBase* listener);
|
||||
void cleanup(uint64_t ts_monotonic);
|
||||
void cleanup(MonotonicTime ts);
|
||||
void handleFrame(const RxFrame& frame);
|
||||
|
||||
int getNumEntries() const { return list_.getLength(); }
|
||||
@@ -64,15 +64,14 @@ public:
|
||||
, self_node_id_(self_node_id)
|
||||
{ }
|
||||
|
||||
int spin(uint64_t monotonic_deadline);
|
||||
int spin(MonotonicTime deadline);
|
||||
|
||||
/**
|
||||
* Refer to CanIOManager::send() for the parameter description
|
||||
*/
|
||||
int send(const Frame& frame, uint64_t monotonic_tx_deadline, uint64_t monotonic_blocking_deadline,
|
||||
CanTxQueue::Qos qos);
|
||||
int send(const Frame& frame, MonotonicTime tx_deadline, MonotonicTime blocking_deadline, CanTxQueue::Qos qos);
|
||||
|
||||
void cleanup(uint64_t ts_monotonic);
|
||||
void cleanup(MonotonicTime ts);
|
||||
|
||||
bool registerMessageListener(TransferListenerBase* listener);
|
||||
bool registerServiceRequestListener(TransferListenerBase* listener);
|
||||
|
||||
@@ -54,8 +54,8 @@ class IOutgoingTransferRegistry
|
||||
{
|
||||
public:
|
||||
virtual ~IOutgoingTransferRegistry() { }
|
||||
virtual TransferID* accessOrCreate(const OutgoingTransferRegistryKey& key, uint64_t new_monotonic_deadline) = 0;
|
||||
virtual void cleanup(uint64_t monotonic_deadline) = 0;
|
||||
virtual TransferID* accessOrCreate(const OutgoingTransferRegistryKey& key, MonotonicTime new_deadline) = 0;
|
||||
virtual void cleanup(MonotonicTime deadline) = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -65,26 +65,25 @@ class OutgoingTransferRegistry : public IOutgoingTransferRegistry, Noncopyable
|
||||
UAVCAN_PACKED_BEGIN
|
||||
struct Value
|
||||
{
|
||||
uint64_t monotonic_deadline;
|
||||
MonotonicTime deadline;
|
||||
TransferID tid;
|
||||
Value() : monotonic_deadline(0) { }
|
||||
};
|
||||
UAVCAN_PACKED_END
|
||||
|
||||
class DeadlineExpiredPredicate
|
||||
{
|
||||
const uint64_t ts_monotonic_;
|
||||
const MonotonicTime ts_;
|
||||
|
||||
public:
|
||||
DeadlineExpiredPredicate(uint64_t ts_monotonic)
|
||||
: ts_monotonic_(ts_monotonic)
|
||||
DeadlineExpiredPredicate(MonotonicTime ts)
|
||||
: ts_(ts)
|
||||
{ }
|
||||
|
||||
bool operator()(const OutgoingTransferRegistryKey& key, const Value& value) const
|
||||
{
|
||||
(void)key;
|
||||
assert(value.monotonic_deadline > 0);
|
||||
return value.monotonic_deadline <= ts_monotonic_;
|
||||
assert(!value.deadline.isZero());
|
||||
return value.deadline <= ts_;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -95,21 +94,21 @@ public:
|
||||
: map_(allocator)
|
||||
{ }
|
||||
|
||||
TransferID* accessOrCreate(const OutgoingTransferRegistryKey& key, uint64_t new_monotonic_deadline)
|
||||
TransferID* accessOrCreate(const OutgoingTransferRegistryKey& key, MonotonicTime new_deadline)
|
||||
{
|
||||
assert(new_monotonic_deadline > 0);
|
||||
assert(!new_deadline.isZero());
|
||||
Value* p = map_.access(key);
|
||||
if (p == NULL)
|
||||
p = map_.insert(key, Value());
|
||||
if (p == NULL)
|
||||
return NULL;
|
||||
p->monotonic_deadline = new_monotonic_deadline;
|
||||
p->deadline = new_deadline;
|
||||
return &p->tid;
|
||||
}
|
||||
|
||||
void cleanup(uint64_t ts_monotonic)
|
||||
void cleanup(MonotonicTime ts)
|
||||
{
|
||||
map_.removeWhere(DeadlineExpiredPredicate(ts_monotonic));
|
||||
map_.removeWhere(DeadlineExpiredPredicate(ts));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -7,11 +7,13 @@
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <uavcan/internal/transport/can_io.hpp>
|
||||
#include <uavcan/can_driver.hpp>
|
||||
|
||||
namespace uavcan
|
||||
{
|
||||
|
||||
struct CanRxFrame;
|
||||
|
||||
enum { MaxTransferPayloadLen = 439 }; ///< According to the standard
|
||||
|
||||
enum { MaxSingleFrameTransferPayloadLen = 7 };
|
||||
@@ -175,37 +177,27 @@ public:
|
||||
|
||||
class RxFrame : public Frame
|
||||
{
|
||||
uint64_t ts_monotonic_;
|
||||
uint64_t ts_utc_;
|
||||
MonotonicTime ts_mono_;
|
||||
UtcTime ts_utc_;
|
||||
uint8_t iface_index_;
|
||||
|
||||
public:
|
||||
RxFrame()
|
||||
: ts_monotonic_(0)
|
||||
, ts_utc_(0)
|
||||
, iface_index_(0)
|
||||
: iface_index_(0)
|
||||
{ }
|
||||
|
||||
RxFrame(const Frame& frame, uint64_t ts_monotonic, uint64_t ts_utc, uint8_t iface_index)
|
||||
: ts_monotonic_(ts_monotonic)
|
||||
RxFrame(const Frame& frame, MonotonicTime ts_mono, UtcTime ts_utc, uint8_t iface_index)
|
||||
: ts_mono_(ts_mono)
|
||||
, ts_utc_(ts_utc)
|
||||
, iface_index_(iface_index)
|
||||
{
|
||||
*static_cast<Frame*>(this) = frame;
|
||||
}
|
||||
|
||||
bool parse(const CanRxFrame& can_frame)
|
||||
{
|
||||
if (!Frame::parse(can_frame))
|
||||
return false;
|
||||
ts_monotonic_ = can_frame.ts_monotonic;
|
||||
ts_utc_ = can_frame.ts_utc;
|
||||
iface_index_ = can_frame.iface_index;
|
||||
return true;
|
||||
}
|
||||
bool parse(const CanRxFrame& can_frame);
|
||||
|
||||
uint64_t getMonotonicTimestamp() const { return ts_monotonic_; }
|
||||
uint64_t getUtcTimestamp() const { return ts_utc_; }
|
||||
MonotonicTime getMonotonicTimestamp() const { return ts_mono_; }
|
||||
UtcTime getUtcTimestamp() const { return ts_utc_; }
|
||||
|
||||
uint8_t getIfaceIndex() const { return iface_index_; }
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <limits>
|
||||
#include <uavcan/internal/transport/transfer.hpp>
|
||||
#include <uavcan/internal/linked_list.hpp>
|
||||
#include <uavcan/internal/dynamic_memory.hpp>
|
||||
#include <uavcan/internal/impl_constants.hpp>
|
||||
#include <uavcan/internal/debug.hpp>
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@ namespace uavcan
|
||||
*/
|
||||
class IncomingTransfer : public ITransferBuffer
|
||||
{
|
||||
uint64_t ts_monotonic_;
|
||||
uint64_t ts_utc_;
|
||||
MonotonicTime ts_mono_;
|
||||
UtcTime ts_utc_;
|
||||
TransferType transfer_type_;
|
||||
TransferID transfer_id_;
|
||||
NodeID src_node_id_;
|
||||
@@ -31,9 +31,9 @@ class IncomingTransfer : public ITransferBuffer
|
||||
int write(unsigned int offset, const uint8_t* data, unsigned int len);
|
||||
|
||||
protected:
|
||||
IncomingTransfer(uint64_t ts_monotonic, uint64_t ts_utc, TransferType transfer_type,
|
||||
IncomingTransfer(MonotonicTime ts_mono, UtcTime ts_utc, TransferType transfer_type,
|
||||
TransferID transfer_id, NodeID source_node_id)
|
||||
: ts_monotonic_(ts_monotonic)
|
||||
: ts_mono_(ts_mono)
|
||||
, ts_utc_(ts_utc)
|
||||
, transfer_type_(transfer_type)
|
||||
, transfer_id_(transfer_id)
|
||||
@@ -46,11 +46,11 @@ public:
|
||||
*/
|
||||
virtual void release() { }
|
||||
|
||||
uint64_t getMonotonicTimestamp() const { return ts_monotonic_; }
|
||||
uint64_t getUtcTimestamp() const { return ts_utc_; }
|
||||
TransferType getTransferType() const { return transfer_type_; }
|
||||
TransferID getTransferID() const { return transfer_id_; }
|
||||
NodeID getSrcNodeID() const { return src_node_id_; }
|
||||
MonotonicTime getMonotonicTimestamp() const { return ts_mono_; }
|
||||
UtcTime getUtcTimestamp() const { return ts_utc_; }
|
||||
TransferType getTransferType() const { return transfer_type_; }
|
||||
TransferID getTransferID() const { return transfer_id_; }
|
||||
NodeID getSrcNodeID() const { return src_node_id_; }
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -72,7 +72,7 @@ class MultiFrameIncomingTransfer : public IncomingTransfer, Noncopyable
|
||||
{
|
||||
TransferBufferAccessor& buf_acc_;
|
||||
public:
|
||||
MultiFrameIncomingTransfer(uint64_t ts_monotonic, uint64_t ts_utc, const RxFrame& last_frame,
|
||||
MultiFrameIncomingTransfer(MonotonicTime ts_mono, UtcTime ts_utc, const RxFrame& last_frame,
|
||||
TransferBufferAccessor& tba);
|
||||
int read(unsigned int offset, uint8_t* data, unsigned int len) const;
|
||||
void release() { buf_acc_.remove(); }
|
||||
@@ -104,7 +104,7 @@ public:
|
||||
const DataTypeDescriptor& getDataTypeDescriptor() const { return data_type_; }
|
||||
|
||||
virtual void handleFrame(const RxFrame& frame) = 0;
|
||||
virtual void cleanup(uint64_t ts_monotonic) = 0;
|
||||
virtual void cleanup(MonotonicTime ts) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -141,18 +141,18 @@ class TransferListener : public TransferListenerBase, Noncopyable
|
||||
|
||||
class TimedOutReceiverPredicate
|
||||
{
|
||||
const uint64_t ts_monotonic_;
|
||||
const MonotonicTime ts_;
|
||||
BufferManager& bufmgr_;
|
||||
|
||||
public:
|
||||
TimedOutReceiverPredicate(uint64_t ts_monotonic, BufferManager& bufmgr)
|
||||
: ts_monotonic_(ts_monotonic)
|
||||
TimedOutReceiverPredicate(MonotonicTime ts, BufferManager& bufmgr)
|
||||
: ts_(ts)
|
||||
, bufmgr_(bufmgr)
|
||||
{ }
|
||||
|
||||
bool operator()(const TransferBufferManagerKey& key, const TransferReceiver& value) const
|
||||
{
|
||||
if (value.isTimedOut(ts_monotonic_))
|
||||
if (value.isTimedOut(ts_))
|
||||
{
|
||||
UAVCAN_TRACE("TransferListener", "Timed out receiver: %s", key.toString().c_str());
|
||||
/*
|
||||
@@ -168,9 +168,9 @@ class TransferListener : public TransferListenerBase, Noncopyable
|
||||
}
|
||||
};
|
||||
|
||||
void cleanup(uint64_t ts_monotonic)
|
||||
void cleanup(MonotonicTime ts)
|
||||
{
|
||||
receivers_.removeWhere(TimedOutReceiverPredicate(ts_monotonic, bufmgr_));
|
||||
receivers_.removeWhere(TimedOutReceiverPredicate(ts, bufmgr_));
|
||||
assert(receivers_.isEmpty() ? bufmgr_.isEmpty() : 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,18 +17,25 @@ class TransferReceiver
|
||||
public:
|
||||
enum ResultCode { ResultNotComplete, ResultComplete, ResultSingleFrame };
|
||||
|
||||
static const uint32_t DefaultTransferInterval = 500 * 1000UL;
|
||||
static const uint32_t MinTransferInterval = 1 * 1000UL;
|
||||
static const uint32_t MaxTransferInterval = 10 * 1000 * 1000UL;
|
||||
static const uint32_t DefaultTransferIntervalUSec = 500 * 1000UL;
|
||||
static const uint32_t MinTransferIntervalUSec = 1 * 1000UL;
|
||||
static const uint32_t MaxTransferIntervalUSec = 10 * 1000 * 1000UL;
|
||||
|
||||
static MonotonicDuration getDefaultTransferInterval()
|
||||
{
|
||||
return MonotonicDuration::fromUSec(DefaultTransferIntervalUSec);
|
||||
}
|
||||
static MonotonicDuration getMinTransferInterval() { return MonotonicDuration::fromUSec(MinTransferIntervalUSec); }
|
||||
static MonotonicDuration getMaxTransferInterval() { return MonotonicDuration::fromUSec(MaxTransferIntervalUSec); }
|
||||
|
||||
private:
|
||||
enum TidRelation { TidSame, TidRepeat, TidFuture };
|
||||
enum { IfaceIndexNotSet = 0xFF };
|
||||
|
||||
uint64_t prev_transfer_ts_monotonic_;
|
||||
uint64_t this_transfer_ts_monotonic_;
|
||||
uint64_t first_frame_ts_utc_;
|
||||
uint32_t transfer_interval_;
|
||||
MonotonicTime prev_transfer_ts_;
|
||||
MonotonicTime this_transfer_ts_;
|
||||
UtcTime first_frame_ts_;
|
||||
uint32_t transfer_interval_usec_;
|
||||
uint16_t this_transfer_crc_;
|
||||
uint16_t buffer_write_pos_;
|
||||
TransferID tid_;
|
||||
@@ -48,26 +55,23 @@ private:
|
||||
|
||||
public:
|
||||
TransferReceiver()
|
||||
: prev_transfer_ts_monotonic_(0)
|
||||
, this_transfer_ts_monotonic_(0)
|
||||
, first_frame_ts_utc_(0)
|
||||
, transfer_interval_(DefaultTransferInterval)
|
||||
: transfer_interval_usec_(DefaultTransferIntervalUSec)
|
||||
, this_transfer_crc_(0)
|
||||
, buffer_write_pos_(0)
|
||||
, iface_index_(IfaceIndexNotSet)
|
||||
, next_frame_index_(0)
|
||||
{ }
|
||||
|
||||
bool isTimedOut(uint64_t ts_monotonic) const;
|
||||
bool isTimedOut(MonotonicTime current_ts) const;
|
||||
|
||||
ResultCode addFrame(const RxFrame& frame, TransferBufferAccessor& tba);
|
||||
|
||||
uint64_t getLastTransferTimestampMonotonic() const { return prev_transfer_ts_monotonic_; }
|
||||
uint64_t getLastTransferTimestampUtc() const { return first_frame_ts_utc_; }
|
||||
MonotonicTime getLastTransferTimestampMonotonic() const { return prev_transfer_ts_; }
|
||||
UtcTime getLastTransferTimestampUtc() const { return first_frame_ts_; }
|
||||
|
||||
uint16_t getLastTransferCrc() const { return this_transfer_crc_; }
|
||||
|
||||
uint32_t getInterval() const { return transfer_interval_; }
|
||||
MonotonicDuration getInterval() const { return MonotonicDuration::fromUSec(transfer_interval_usec_); }
|
||||
};
|
||||
UAVCAN_PACKED_END
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace uavcan
|
||||
|
||||
class TransferSender
|
||||
{
|
||||
const uint64_t max_transfer_interval_;
|
||||
const MonotonicDuration max_transfer_interval_;
|
||||
const DataTypeDescriptor& data_type_;
|
||||
const CanTxQueue::Qos qos_;
|
||||
const TransferCRC crc_base_;
|
||||
@@ -24,10 +24,13 @@ class TransferSender
|
||||
Dispatcher& dispatcher_;
|
||||
|
||||
public:
|
||||
static const uint64_t DefaultMaxTransferInterval = 60 * 1000 * 1000;
|
||||
static MonotonicDuration getDefaultMaxTransferInterval()
|
||||
{
|
||||
return MonotonicDuration::fromMSec(60 * 1000);
|
||||
}
|
||||
|
||||
TransferSender(Dispatcher& dispatcher, const DataTypeDescriptor& data_type, CanTxQueue::Qos qos,
|
||||
uint64_t max_transfer_interval = DefaultMaxTransferInterval)
|
||||
MonotonicDuration max_transfer_interval = getDefaultMaxTransferInterval())
|
||||
: max_transfer_interval_(max_transfer_interval)
|
||||
, data_type_(data_type)
|
||||
, qos_(qos)
|
||||
@@ -39,16 +42,16 @@ public:
|
||||
* Send with explicit Transfer ID.
|
||||
* Should be used only for service responses, where response TID should match request TID.
|
||||
*/
|
||||
int send(const uint8_t* payload, int payload_len, uint64_t monotonic_tx_deadline,
|
||||
uint64_t monotonic_blocking_deadline, TransferType transfer_type, NodeID dst_node_id,
|
||||
int send(const uint8_t* payload, int payload_len, MonotonicTime tx_deadline,
|
||||
MonotonicTime blocking_deadline, TransferType transfer_type, NodeID dst_node_id,
|
||||
TransferID tid);
|
||||
|
||||
/**
|
||||
* Send with automatic Transfer ID.
|
||||
* TID is managed by OutgoingTransferRegistry.
|
||||
*/
|
||||
int send(const uint8_t* payload, int payload_len, uint64_t monotonic_tx_deadline,
|
||||
uint64_t monotonic_blocking_deadline, TransferType transfer_type, NodeID dst_node_id);
|
||||
int send(const uint8_t* payload, int payload_len, MonotonicTime tx_deadline,
|
||||
MonotonicTime blocking_deadline, TransferType transfer_type, NodeID dst_node_id);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -18,11 +18,11 @@ public:
|
||||
typedef DataType_ DataType;
|
||||
|
||||
Publisher(Scheduler& scheduler, IMarshalBufferProvider& buffer_provider,
|
||||
uint64_t tx_timeout_usec = BaseType::DefaultTxTimeoutUsec,
|
||||
uint64_t max_transfer_interval = TransferSender::DefaultMaxTransferInterval)
|
||||
MonotonicDuration tx_timeout = BaseType::getDefaultTxTimeout(),
|
||||
MonotonicDuration max_transfer_interval = TransferSender::getDefaultMaxTransferInterval())
|
||||
: BaseType(scheduler, buffer_provider, max_transfer_interval)
|
||||
{
|
||||
BaseType::setTxTimeout(tx_timeout_usec);
|
||||
BaseType::setTxTimeout(tx_timeout);
|
||||
StaticAssert<DataTypeKind(DataType::DataTypeKind) == DataTypeKindMessage>::check();
|
||||
}
|
||||
|
||||
|
||||
@@ -6,9 +6,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <uavcan/internal/impl_constants.hpp>
|
||||
#include <uavcan/time.hpp>
|
||||
|
||||
namespace uavcan
|
||||
{
|
||||
|
||||
/**
|
||||
* System clock interface - monotonic and UTC.
|
||||
* Note that this library uses microseconds for all time related values (timestamps, deadlines, delays),
|
||||
@@ -21,19 +24,19 @@ public:
|
||||
virtual ~ISystemClock() { }
|
||||
|
||||
/**
|
||||
* Monototic system clock in microseconds.
|
||||
* Monototic system clock.
|
||||
* This shall never jump during UTC timestamp adjustments; the base time is irrelevant.
|
||||
* On POSIX systems use clock_gettime() with CLOCK_MONOTONIC.
|
||||
*/
|
||||
virtual uint64_t getMonotonicMicroseconds() const = 0;
|
||||
virtual MonotonicTime getMonotonic() const = 0;
|
||||
|
||||
/**
|
||||
* UTC clock in microseconds.
|
||||
* UTC clock.
|
||||
* This can jump when the UTC timestamp is being adjusted.
|
||||
* Return 0 if the UTC time is not available yet (e.g. the device just started up with no battery clock).
|
||||
* On POSIX systems use gettimeofday().
|
||||
*/
|
||||
virtual uint64_t getUtcMicroseconds() const = 0;
|
||||
virtual UtcTime getUtc() const = 0;
|
||||
|
||||
/**
|
||||
* Set the UTC system clock.
|
||||
@@ -41,7 +44,7 @@ public:
|
||||
* @param [in] offset Current UTC time error. More precise than just timestamp, use it if possible.
|
||||
* For POSIX refer to adjtime(), settimeofday().
|
||||
*/
|
||||
virtual void adjustUtcMicroseconds(uint64_t new_timestamp_usec, int64_t offset_usec) = 0;
|
||||
virtual void adjustUtc(UtcTime new_time, UtcDuration offset) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -10,7 +10,15 @@
|
||||
#include <sstream>
|
||||
#include <cstdio>
|
||||
#include <uavcan/util/compile_time.hpp>
|
||||
#include <uavcan/Timestamp.hpp>
|
||||
|
||||
// TODO: Fix inclusion loops!
|
||||
namespace uavcan
|
||||
{
|
||||
|
||||
struct Timestamp_;
|
||||
typedef Timestamp_ Timestamp;
|
||||
|
||||
}
|
||||
|
||||
namespace uavcan
|
||||
{
|
||||
@@ -27,6 +35,8 @@ public:
|
||||
StaticAssert<(sizeof(D) == 8)>::check();
|
||||
}
|
||||
|
||||
static D getInfinite() { return fromUSec(std::numeric_limits<int64_t>::max()); }
|
||||
|
||||
static D fromUSec(int64_t us)
|
||||
{
|
||||
D d;
|
||||
@@ -95,6 +105,8 @@ public:
|
||||
StaticAssert<(sizeof(D) == 8)>::check();
|
||||
}
|
||||
|
||||
static T getMax() { return fromUSec(std::numeric_limits<uint64_t>::max()); }
|
||||
|
||||
static T fromUSec(uint64_t us)
|
||||
{
|
||||
T d;
|
||||
@@ -120,15 +132,15 @@ public:
|
||||
{
|
||||
if (r.isNegative())
|
||||
{
|
||||
if (uint64_t(r.getAbs().usec_) > usec_)
|
||||
if (uint64_t(r.getAbs().toUSec()) > usec_)
|
||||
return fromUSec(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (uint64_t(usec_ + r.usec_) < usec_)
|
||||
if (uint64_t(usec_ + r.toUSec()) < usec_)
|
||||
return fromUSec(std::numeric_limits<uint64_t>::max());
|
||||
}
|
||||
return fromUSec(usec_ + r.usec_);
|
||||
return fromUSec(usec_ + r.toUSec());
|
||||
}
|
||||
|
||||
T operator-(const D& r) const
|
||||
@@ -154,36 +166,25 @@ public:
|
||||
std::string toString() const;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Monotonic
|
||||
*/
|
||||
class MonotonicDuration : public DurationBase<MonotonicDuration> { };
|
||||
|
||||
class MonotonicTime : public TimeBase<MonotonicTime, MonotonicDuration> { };
|
||||
|
||||
|
||||
/*
|
||||
* UTC
|
||||
*/
|
||||
class UtcDuration : public DurationBase<UtcDuration> { };
|
||||
|
||||
class UtcTime : public TimeBase<UtcTime, UtcDuration>
|
||||
{
|
||||
public:
|
||||
UtcTime() { }
|
||||
|
||||
UtcTime(const Timestamp& ts) // Implicit
|
||||
{
|
||||
operator=(ts);
|
||||
}
|
||||
|
||||
UtcTime& operator=(const Timestamp& ts)
|
||||
{
|
||||
*this = fromUSec(ts.husec * Timestamp::USEC_PER_LSB);
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator Timestamp() const
|
||||
{
|
||||
Timestamp ts;
|
||||
ts.husec = toUSec() / Timestamp::USEC_PER_LSB;
|
||||
return ts;
|
||||
}
|
||||
UtcTime(const Timestamp& ts); // Implicit
|
||||
UtcTime& operator=(const Timestamp& ts);
|
||||
operator Timestamp() const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -17,13 +17,13 @@ class Timer;
|
||||
|
||||
struct TimerEvent
|
||||
{
|
||||
uint64_t scheduled_monotonic_deadline;
|
||||
uint64_t monotonic_timestamp;
|
||||
MonotonicTime scheduled_deadline;
|
||||
MonotonicTime current_timestamp;
|
||||
Timer* timer;
|
||||
|
||||
TimerEvent(Timer* timer, uint64_t scheduled_monotonic_deadline, uint64_t monotonic_timestamp)
|
||||
: scheduled_monotonic_deadline(scheduled_monotonic_deadline)
|
||||
, monotonic_timestamp(monotonic_timestamp)
|
||||
TimerEvent(Timer* timer, MonotonicTime scheduled_deadline, MonotonicTime current_timestamp)
|
||||
: scheduled_deadline(scheduled_deadline)
|
||||
, current_timestamp(current_timestamp)
|
||||
, timer(timer)
|
||||
{ }
|
||||
};
|
||||
@@ -31,28 +31,26 @@ struct TimerEvent
|
||||
|
||||
class Timer : private MonotonicDeadlineHandler
|
||||
{
|
||||
uint64_t period_;
|
||||
MonotonicDuration period_;
|
||||
|
||||
void handleMonotonicDeadline(uint64_t monotonic_timestamp);
|
||||
void handleDeadline(MonotonicTime current_timestamp);
|
||||
|
||||
public:
|
||||
static const uint64_t InfinitePeriod = 0xFFFFFFFFFFFFFFFFUL;
|
||||
|
||||
using MonotonicDeadlineHandler::stop;
|
||||
using MonotonicDeadlineHandler::isRunning;
|
||||
using MonotonicDeadlineHandler::getMonotonicDeadline;
|
||||
using MonotonicDeadlineHandler::getDeadline;
|
||||
using MonotonicDeadlineHandler::getScheduler;
|
||||
|
||||
explicit Timer(Scheduler& scheduler)
|
||||
: MonotonicDeadlineHandler(scheduler)
|
||||
, period_(InfinitePeriod)
|
||||
, period_(MonotonicDuration::getInfinite())
|
||||
{ }
|
||||
|
||||
void startOneShotWithDeadline(uint64_t monotonic_deadline);
|
||||
void startOneShotWithDelay(uint64_t delay_usec);
|
||||
void startPeriodic(uint64_t period_usec);
|
||||
void startOneShotWithDeadline(MonotonicTime deadline);
|
||||
void startOneShotWithDelay(MonotonicDuration delay);
|
||||
void startPeriodic(MonotonicDuration period);
|
||||
|
||||
uint64_t getPeriod() const { return period_; }
|
||||
MonotonicDuration getPeriod() const { return period_; }
|
||||
|
||||
virtual void handleTimerEvent(const TimerEvent& event) = 0;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user