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:
Pavel Kirienko
2014-03-11 14:41:48 +04:00
parent 633fa9d8bd
commit 65a4dcc2cf
48 changed files with 654 additions and 565 deletions
+1
View File
@@ -7,6 +7,7 @@
#include <iomanip>
#include <cassert>
#include <uavcan/data_type.hpp>
#include <uavcan/internal/transport/crc.hpp>
namespace uavcan
{
+33 -34
View File
@@ -3,7 +3,6 @@
*/
#include <cassert>
#include <limits>
#include <uavcan/internal/node/scheduler.hpp>
#include <uavcan/internal/debug.hpp>
@@ -12,17 +11,17 @@ namespace uavcan
/*
* MonotonicDeadlineHandler
*/
void MonotonicDeadlineHandler::startWithDeadline(uint64_t monotonic_deadline)
void MonotonicDeadlineHandler::startWithDeadline(MonotonicTime deadline)
{
assert(monotonic_deadline > 0);
assert(!deadline.isZero());
stop();
monotonic_deadline_ = monotonic_deadline;
deadline_ = deadline;
scheduler_.getMonotonicDeadlineScheduler().add(this);
}
void MonotonicDeadlineHandler::startWithDelay(uint64_t delay_usec)
void MonotonicDeadlineHandler::startWithDelay(MonotonicDuration delay)
{
startWithDeadline(scheduler_.getMonotonicTimestamp() + delay_usec);
startWithDeadline(scheduler_.getMonotonicTimestamp() + delay);
}
void MonotonicDeadlineHandler::stop()
@@ -40,18 +39,18 @@ bool MonotonicDeadlineHandler::isRunning() const
*/
struct MonotonicDeadlineHandlerInsertionComparator
{
const uint64_t ts;
MonotonicDeadlineHandlerInsertionComparator(uint64_t ts) : ts(ts) { }
const MonotonicTime ts;
MonotonicDeadlineHandlerInsertionComparator(MonotonicTime ts) : ts(ts) { }
bool operator()(const MonotonicDeadlineHandler* t) const
{
return t->getMonotonicDeadline() > ts;
return t->getDeadline() > ts;
}
};
void MonotonicDeadlineScheduler::add(MonotonicDeadlineHandler* mdh)
{
assert(mdh);
handlers_.insertBefore(mdh, MonotonicDeadlineHandlerInsertionComparator(mdh->getMonotonicDeadline()));
handlers_.insertBefore(mdh, MonotonicDeadlineHandlerInsertionComparator(mdh->getDeadline()));
}
void MonotonicDeadlineScheduler::remove(MonotonicDeadlineHandler* mdh)
@@ -65,14 +64,14 @@ bool MonotonicDeadlineScheduler::doesExist(const MonotonicDeadlineHandler* mdh)
assert(mdh);
const MonotonicDeadlineHandler* p = handlers_.get();
#if UAVCAN_DEBUG
uint64_t prev_deadline = 0;
MonotonicTime prev_deadline;
#endif
while (p)
{
#if UAVCAN_DEBUG
if (prev_deadline > p->getMonotonicDeadline()) // Self check
if (prev_deadline > p->getDeadline()) // Self check
std::abort();
prev_deadline = p->getMonotonicDeadline();
prev_deadline = p->getDeadline();
#endif
if (p == mdh)
return true;
@@ -81,56 +80,56 @@ bool MonotonicDeadlineScheduler::doesExist(const MonotonicDeadlineHandler* mdh)
return false;
}
uint64_t MonotonicDeadlineScheduler::pollAndGetMonotonicTimestamp(ISystemClock& sysclock)
MonotonicTime MonotonicDeadlineScheduler::pollAndGetMonotonicTimestamp(ISystemClock& sysclock)
{
while (true)
{
MonotonicDeadlineHandler* const mdh = handlers_.get();
if (!mdh)
return sysclock.getMonotonicMicroseconds();
return sysclock.getMonotonic();
#if UAVCAN_DEBUG
if (mdh->getNextListNode()) // Order check
assert(mdh->getMonotonicDeadline() <= mdh->getNextListNode()->getMonotonicDeadline());
assert(mdh->getDeadline() <= mdh->getNextListNode()->getDeadline());
#endif
const uint64_t ts = sysclock.getMonotonicMicroseconds();
if (ts < mdh->getMonotonicDeadline())
const MonotonicTime ts = sysclock.getMonotonic();
if (ts < mdh->getDeadline())
return ts;
handlers_.remove(mdh);
mdh->handleMonotonicDeadline(ts); // This handler can be re-registered immediately
mdh->handleDeadline(ts); // This handler can be re-registered immediately
}
assert(0);
return 0;
return MonotonicTime();
}
uint64_t MonotonicDeadlineScheduler::getEarliestDeadline() const
MonotonicTime MonotonicDeadlineScheduler::getEarliestDeadline() const
{
const MonotonicDeadlineHandler* const mdh = handlers_.get();
if (mdh)
return mdh->getMonotonicDeadline();
return std::numeric_limits<uint64_t>::max();
return mdh->getDeadline();
return MonotonicTime::getMax();
}
/*
* Scheduler
*/
uint64_t Scheduler::computeDispatcherSpinDeadline(uint64_t spin_deadline) const
MonotonicTime Scheduler::computeDispatcherSpinDeadline(MonotonicTime spin_deadline) const
{
const uint64_t earliest = std::min(deadline_scheduler_.getEarliestDeadline(), spin_deadline);
const uint64_t ts = getMonotonicTimestamp();
const MonotonicTime earliest = std::min(deadline_scheduler_.getEarliestDeadline(), spin_deadline);
const MonotonicTime ts = getMonotonicTimestamp();
if (earliest > ts)
{
if (ts - earliest > monotonic_deadline_resolution_)
return ts + monotonic_deadline_resolution_;
if (ts - earliest > deadline_resolution_)
return ts + deadline_resolution_;
}
return earliest;
}
void Scheduler::pollCleanup(uint64_t mono_ts, uint32_t num_frames_processed_with_last_spin)
void Scheduler::pollCleanup(MonotonicTime mono_ts, uint32_t num_frames_processed_with_last_spin)
{
// cleanup will be performed less frequently if the stack handles more frames per second
const uint64_t deadline = prev_cleanup_ts_ + cleanup_period_ * (num_frames_processed_with_last_spin + 1);
const MonotonicTime deadline = prev_cleanup_ts_ + cleanup_period_ * (num_frames_processed_with_last_spin + 1);
if (mono_ts > deadline)
{
UAVCAN_TRACE("Scheduler", "Cleanup with %u processed frames", num_frames_processed_with_last_spin);
@@ -139,19 +138,19 @@ void Scheduler::pollCleanup(uint64_t mono_ts, uint32_t num_frames_processed_with
}
}
int Scheduler::spin(uint64_t monotonic_deadline)
int Scheduler::spin(MonotonicTime deadline)
{
int retval = 0;
while (true)
{
const uint64_t dl = computeDispatcherSpinDeadline(monotonic_deadline);
const MonotonicTime dl = computeDispatcherSpinDeadline(deadline);
retval = dispatcher_.spin(dl);
if (retval < 0)
break;
const uint64_t ts = deadline_scheduler_.pollAndGetMonotonicTimestamp(getSystemClock());
const MonotonicTime ts = deadline_scheduler_.pollAndGetMonotonicTimestamp(getSystemClock());
pollCleanup(ts, retval);
if (ts >= monotonic_deadline)
if (ts >= deadline)
break;
}
return retval;
+23 -32
View File
@@ -19,7 +19,7 @@ std::string CanRxFrame::toString(StringRepresentation mode) const
{
std::ostringstream os;
os << CanFrame::toString(mode)
<< " ts_m=" << ts_monotonic << " ts_utc=" << ts_utc << " iface=" << int(iface_index);
<< " ts_m=" << ts_mono << " ts_utc=" << ts_utc << " iface=" << int(iface_index);
return os.str();
}
@@ -88,11 +88,11 @@ void CanTxQueue::registerRejectedFrame()
rejected_frames_cnt_++;
}
void CanTxQueue::push(const CanFrame& frame, uint64_t monotonic_tx_deadline, Qos qos)
void CanTxQueue::push(const CanFrame& frame, MonotonicTime tx_deadline, Qos qos)
{
const uint64_t timestamp = sysclock_->getMonotonicMicroseconds();
const MonotonicTime timestamp = sysclock_->getMonotonic();
if (timestamp >= monotonic_tx_deadline)
if (timestamp >= tx_deadline)
{
UAVCAN_TRACE("CanTxQueue", "Push rejected: already expired");
registerRejectedFrame();
@@ -147,14 +147,14 @@ void CanTxQueue::push(const CanFrame& frame, uint64_t monotonic_tx_deadline, Qos
if (praw == NULL)
return; // Seems that there is no memory at all.
Entry* entry = new (praw) Entry(frame, monotonic_tx_deadline, qos);
Entry* entry = new (praw) Entry(frame, tx_deadline, qos);
assert(entry);
queue_.insertBefore(entry, PriorityInsertionComparator(frame));
}
CanTxQueue::Entry* CanTxQueue::peek()
{
const uint64_t timestamp = sysclock_->getMonotonicMicroseconds();
const MonotonicTime timestamp = sysclock_->getMonotonic();
Entry* p = queue_.get();
while (p)
{
@@ -194,7 +194,7 @@ bool CanTxQueue::topPriorityHigherOrEqual(const CanFrame& rhs_frame) const
/*
* CanIOManager
*/
int CanIOManager::sendToIface(int iface_index, const CanFrame& frame, uint64_t monotonic_tx_deadline)
int CanIOManager::sendToIface(int iface_index, const CanFrame& frame, MonotonicTime tx_deadline)
{
assert(iface_index >= 0 && iface_index < MaxIfaces);
ICanIface* const iface = driver_.getIface(iface_index);
@@ -203,9 +203,7 @@ int CanIOManager::sendToIface(int iface_index, const CanFrame& frame, uint64_t m
assert(0); // Nonexistent interface
return -1;
}
const uint64_t timestamp = sysclock_.getMonotonicMicroseconds();
const uint64_t timeout = (timestamp >= monotonic_tx_deadline) ? 0 : (monotonic_tx_deadline - timestamp);
const int res = iface->send(frame, timeout);
const int res = iface->send(frame, tx_deadline);
if (res != 1)
{
UAVCAN_TRACE("CanIOManager", "Send failed: code %i, iface %i, frame %s",
@@ -220,7 +218,7 @@ int CanIOManager::sendFromTxQueue(int iface_index)
CanTxQueue::Entry* entry = tx_queues_[iface_index].peek();
if (entry == NULL)
return 0;
const int res = sendToIface(iface_index, entry->frame, entry->monotonic_deadline);
const int res = sendToIface(iface_index, entry->frame, entry->deadline);
if (res > 0)
tx_queues_[iface_index].remove(entry);
return res;
@@ -237,12 +235,6 @@ int CanIOManager::makePendingTxMask() const
return write_mask;
}
uint64_t CanIOManager::getTimeUntilMonotonicDeadline(uint64_t monotonic_deadline) const
{
const uint64_t timestamp = sysclock_.getMonotonicMicroseconds();
return (timestamp >= monotonic_deadline) ? 0 : (monotonic_deadline - timestamp);
}
int CanIOManager::getNumIfaces() const
{
const int num = driver_.getNumIfaces();
@@ -261,7 +253,7 @@ uint64_t CanIOManager::getNumErrors(int iface_index) const
return iface->getNumErrors() + tx_queues_[iface_index].getNumRejectedFrames();
}
int CanIOManager::send(const CanFrame& frame, uint64_t monotonic_tx_deadline, uint64_t monotonic_blocking_deadline,
int CanIOManager::send(const CanFrame& frame, MonotonicTime tx_deadline, MonotonicTime blocking_deadline,
int iface_mask, CanTxQueue::Qos qos)
{
const int num_ifaces = getNumIfaces();
@@ -270,8 +262,8 @@ int CanIOManager::send(const CanFrame& frame, uint64_t monotonic_tx_deadline, ui
assert((iface_mask & ~all_ifaces_mask) == 0);
iface_mask &= all_ifaces_mask;
if (monotonic_blocking_deadline > monotonic_tx_deadline)
monotonic_blocking_deadline = monotonic_tx_deadline;
if (blocking_deadline > tx_deadline)
blocking_deadline = tx_deadline;
int retval = 0;
@@ -280,11 +272,9 @@ int CanIOManager::send(const CanFrame& frame, uint64_t monotonic_tx_deadline, ui
if (iface_mask == 0)
break;
int write_mask = iface_mask | makePendingTxMask();
const uint64_t timeout = getTimeUntilMonotonicDeadline(monotonic_blocking_deadline);
{
int read_mask = 0;
const int select_res = driver_.select(write_mask, read_mask, timeout);
const int select_res = driver_.select(write_mask, read_mask, blocking_deadline);
if (select_res < 0)
return select_res;
}
@@ -303,7 +293,7 @@ int CanIOManager::send(const CanFrame& frame, uint64_t monotonic_tx_deadline, ui
}
if (res <= 0)
{
res = sendToIface(i, frame, monotonic_tx_deadline);
res = sendToIface(i, frame, tx_deadline);
if (res > 0)
iface_mask &= ~(1 << i); // Mark transmitted
}
@@ -318,9 +308,10 @@ int CanIOManager::send(const CanFrame& frame, uint64_t monotonic_tx_deadline, ui
}
// Timeout. Enqueue the frame if wasn't transmitted and leave.
if (write_mask == 0 || timeout == 0)
const bool timed_out = sysclock_.getMonotonic() >= blocking_deadline;
if (write_mask == 0 || timed_out)
{
if ((timeout > 0) && (sysclock_.getMonotonicMicroseconds() < monotonic_blocking_deadline))
if (!timed_out)
{
UAVCAN_TRACE("CanIOManager", "Send: Premature timeout in select(), will try again");
continue;
@@ -328,7 +319,7 @@ int CanIOManager::send(const CanFrame& frame, uint64_t monotonic_tx_deadline, ui
for (int i = 0; i < num_ifaces; i++)
{
if (iface_mask & (1 << i))
tx_queues_[i].push(frame, monotonic_tx_deadline, qos);
tx_queues_[i].push(frame, tx_deadline, qos);
}
break;
}
@@ -336,7 +327,7 @@ int CanIOManager::send(const CanFrame& frame, uint64_t monotonic_tx_deadline, ui
return retval;
}
int CanIOManager::receive(CanRxFrame& frame, uint64_t monotonic_deadline)
int CanIOManager::receive(CanRxFrame& frame, MonotonicTime blocking_deadline)
{
const int num_ifaces = getNumIfaces();
@@ -344,9 +335,8 @@ int CanIOManager::receive(CanRxFrame& frame, uint64_t monotonic_deadline)
{
int write_mask = makePendingTxMask();
int read_mask = (1 << num_ifaces) - 1;
const uint64_t timeout = getTimeUntilMonotonicDeadline(monotonic_deadline);
{
const int select_res = driver_.select(write_mask, read_mask, timeout);
const int select_res = driver_.select(write_mask, read_mask, blocking_deadline);
if (select_res < 0)
return select_res;
}
@@ -369,7 +359,7 @@ int CanIOManager::receive(CanRxFrame& frame, uint64_t monotonic_deadline)
assert(0); // Nonexistent interface
continue;
}
const int res = iface->receive(frame, frame.ts_monotonic, frame.ts_utc);
const int res = iface->receive(frame, frame.ts_mono, frame.ts_utc);
if (res == 0)
{
assert(0); // select() reported that iface has pending RX frames, but receive() returned none
@@ -380,7 +370,8 @@ int CanIOManager::receive(CanRxFrame& frame, uint64_t monotonic_deadline)
}
}
if (timeout == 0) // Timeout checked in the last order - this way we can operate with expired deadline
// Timeout checked in the last order - this way we can operate with expired deadline:
if (sysclock_.getMonotonic() >= blocking_deadline)
break;
}
return 0;
+12 -12
View File
@@ -33,12 +33,12 @@ void Dispatcher::ListenerRegister::remove(TransferListenerBase* listener)
list_.remove(listener);
}
void Dispatcher::ListenerRegister::cleanup(uint64_t ts_monotonic)
void Dispatcher::ListenerRegister::cleanup(MonotonicTime ts)
{
TransferListenerBase* p = list_.get();
while (p)
{
p->cleanup(ts_monotonic);
p->cleanup(ts);
p = p->getNextListNode();
}
}
@@ -94,13 +94,13 @@ void Dispatcher::handleFrame(const CanRxFrame& can_frame)
}
}
int Dispatcher::spin(uint64_t monotonic_deadline)
int Dispatcher::spin(MonotonicTime deadline)
{
int num_frames_processed = 0;
do
{
CanRxFrame frame;
const int res = canio_.receive(frame, monotonic_deadline);
const int res = canio_.receive(frame, deadline);
if (res < 0)
return res;
if (res > 0)
@@ -109,12 +109,12 @@ int Dispatcher::spin(uint64_t monotonic_deadline)
handleFrame(frame);
}
}
while (sysclock_.getMonotonicMicroseconds() < monotonic_deadline);
while (sysclock_.getMonotonic() < deadline);
return num_frames_processed;
}
int Dispatcher::send(const Frame& frame, uint64_t monotonic_tx_deadline, uint64_t monotonic_blocking_deadline,
int Dispatcher::send(const Frame& frame, MonotonicTime tx_deadline, MonotonicTime blocking_deadline,
CanTxQueue::Qos qos)
{
if (frame.getSrcNodeID() != getSelfNodeID())
@@ -132,15 +132,15 @@ int Dispatcher::send(const Frame& frame, uint64_t monotonic_tx_deadline, uint64_
}
const int iface_mask = (1 << canio_.getNumIfaces()) - 1;
return canio_.send(can_frame, monotonic_tx_deadline, monotonic_blocking_deadline, iface_mask, qos);
return canio_.send(can_frame, tx_deadline, blocking_deadline, iface_mask, qos);
}
void Dispatcher::cleanup(uint64_t ts_monotonic)
void Dispatcher::cleanup(MonotonicTime ts)
{
outgoing_transfer_reg_.cleanup(ts_monotonic);
lmsg_.cleanup(ts_monotonic);
lsrv_req_.cleanup(ts_monotonic);
lsrv_resp_.cleanup(ts_monotonic);
outgoing_transfer_reg_.cleanup(ts);
lmsg_.cleanup(ts);
lsrv_req_.cleanup(ts);
lsrv_resp_.cleanup(ts);
}
bool Dispatcher::registerMessageListener(TransferListenerBase* listener)
+12 -1
View File
@@ -6,6 +6,7 @@
#include <cstdio>
#include <sstream>
#include <uavcan/internal/transport/transfer.hpp>
#include <uavcan/internal/transport/can_io.hpp>
namespace uavcan
{
@@ -225,10 +226,20 @@ std::string Frame::toString() const
/**
* RxFrame
*/
bool RxFrame::parse(const CanRxFrame& can_frame)
{
if (!Frame::parse(can_frame))
return false;
ts_mono_ = can_frame.ts_mono;
ts_utc_ = can_frame.ts_utc;
iface_index_ = can_frame.iface_index;
return true;
}
std::string RxFrame::toString() const
{
std::ostringstream os; // C++03 doesn't support long long, so we need ostream to print the timestamp
os << Frame::toString() << " ts_m=" << ts_monotonic_ << " ts_utc=" << ts_utc_ << " iface=" << int(iface_index_);
os << Frame::toString() << " ts_m=" << ts_mono_ << " ts_utc=" << ts_utc_ << " iface=" << int(iface_index_);
return os.str();
}
@@ -49,9 +49,9 @@ int SingleFrameIncomingTransfer::read(unsigned int offset, uint8_t* data, unsign
/*
* MultiFrameIncomingTransfer
*/
MultiFrameIncomingTransfer::MultiFrameIncomingTransfer(uint64_t ts_monotonic, uint64_t ts_utc,
MultiFrameIncomingTransfer::MultiFrameIncomingTransfer(MonotonicTime ts_mono, UtcTime ts_utc,
const RxFrame& last_frame, TransferBufferAccessor& tba)
: IncomingTransfer(ts_monotonic, ts_utc, last_frame.getTransferType(), last_frame.getTransferID(),
: IncomingTransfer(ts_mono, ts_utc, last_frame.getTransferType(), last_frame.getTransferID(),
last_frame.getSrcNodeID())
, buf_acc_(tba)
{
@@ -13,9 +13,9 @@
namespace uavcan
{
const uint32_t TransferReceiver::DefaultTransferInterval;
const uint32_t TransferReceiver::MinTransferInterval;
const uint32_t TransferReceiver::MaxTransferInterval;
const uint32_t TransferReceiver::DefaultTransferIntervalUSec;
const uint32_t TransferReceiver::MinTransferIntervalUSec;
const uint32_t TransferReceiver::MaxTransferIntervalUSec;
TransferReceiver::TidRelation TransferReceiver::getTidRelation(const RxFrame& frame) const
{
@@ -29,18 +29,17 @@ TransferReceiver::TidRelation TransferReceiver::getTidRelation(const RxFrame& fr
void TransferReceiver::updateTransferTimings()
{
assert(this_transfer_ts_monotonic_ > 0);
assert(!this_transfer_ts_.isZero());
const uint64_t prev_prev_ts = prev_transfer_ts_monotonic_;
prev_transfer_ts_monotonic_ = this_transfer_ts_monotonic_;
const MonotonicTime prev_prev_ts = prev_transfer_ts_;
prev_transfer_ts_ = this_transfer_ts_;
if ((prev_prev_ts != 0) &&
(prev_transfer_ts_monotonic_ != 0) &&
(prev_transfer_ts_monotonic_ >= prev_prev_ts))
if ((!prev_prev_ts.isZero()) && (!prev_transfer_ts_.isZero()) && (prev_transfer_ts_ >= prev_prev_ts))
{
uint64_t interval = prev_transfer_ts_monotonic_ - prev_prev_ts;
interval = std::max(std::min(interval, uint64_t(MaxTransferInterval)), uint64_t(MinTransferInterval));
transfer_interval_ = static_cast<uint32_t>((uint64_t(transfer_interval_) * 7 + interval) / 8);
uint64_t interval_usec = (prev_transfer_ts_ - prev_prev_ts).toUSec();
interval_usec = std::min(interval_usec, uint64_t(MaxTransferIntervalUSec));
interval_usec = std::max(interval_usec, uint64_t(MinTransferIntervalUSec));
transfer_interval_usec_ = static_cast<uint32_t>((uint64_t(transfer_interval_usec_) * 7 + interval_usec) / 8);
}
}
@@ -117,8 +116,8 @@ TransferReceiver::ResultCode TransferReceiver::receive(const RxFrame& frame, Tra
// Transfer timestamps are derived from the first frame
if (frame.isFirst())
{
this_transfer_ts_monotonic_ = frame.getMonotonicTimestamp();
first_frame_ts_utc_ = frame.getUtcTimestamp();
this_transfer_ts_ = frame.getMonotonicTimestamp();
first_frame_ts_ = frame.getUtcTimestamp();
}
if (frame.isFirst() && frame.isLast())
@@ -158,20 +157,19 @@ TransferReceiver::ResultCode TransferReceiver::receive(const RxFrame& frame, Tra
return ResultNotComplete;
}
bool TransferReceiver::isTimedOut(uint64_t ts_monotonic) const
bool TransferReceiver::isTimedOut(MonotonicTime current_ts) const
{
static const uint64_t INTERVAL_MULT = (1 << TransferID::BitLen) / 2 + 1;
const uint64_t ts = this_transfer_ts_monotonic_;
if (ts_monotonic <= ts)
if (current_ts <= this_transfer_ts_)
return false;
return (ts_monotonic - ts) > (uint64_t(transfer_interval_) * INTERVAL_MULT);
return (current_ts - this_transfer_ts_).toUSec() > (uint64_t(transfer_interval_usec_) * INTERVAL_MULT);
}
TransferReceiver::ResultCode TransferReceiver::addFrame(const RxFrame& frame, TransferBufferAccessor& tba)
{
if ((frame.getMonotonicTimestamp() == 0) ||
(frame.getMonotonicTimestamp() < prev_transfer_ts_monotonic_) ||
(frame.getMonotonicTimestamp() < this_transfer_ts_monotonic_))
if ((frame.getMonotonicTimestamp().isZero()) ||
(frame.getMonotonicTimestamp() < prev_transfer_ts_) ||
(frame.getMonotonicTimestamp() < this_transfer_ts_))
{
return ResultNotComplete;
}
@@ -182,7 +180,7 @@ TransferReceiver::ResultCode TransferReceiver::addFrame(const RxFrame& frame, Tr
const bool first_fame = frame.isFirst();
const TidRelation tid_rel = getTidRelation(frame);
const bool iface_timed_out =
(frame.getMonotonicTimestamp() - this_transfer_ts_monotonic_) > (uint64_t(transfer_interval_) * 2);
(frame.getMonotonicTimestamp() - this_transfer_ts_).toUSec() > (uint64_t(transfer_interval_usec_) * 2);
const bool need_restart = // FSM, the hard way
(not_initialized) ||
@@ -10,8 +10,8 @@
namespace uavcan
{
int TransferSender::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 TransferSender::send(const uint8_t* payload, int payload_len, MonotonicTime tx_deadline,
MonotonicTime blocking_deadline, TransferType transfer_type, NodeID dst_node_id,
TransferID tid)
{
Frame frame(data_type_.getID(), transfer_type, dispatcher_.getSelfNodeID(), dst_node_id, 0, tid);
@@ -27,7 +27,7 @@ int TransferSender::send(const uint8_t* payload, int payload_len, uint64_t monot
}
frame.makeLast();
assert(frame.isLast() && frame.isFirst());
return dispatcher_.send(frame, monotonic_tx_deadline, monotonic_blocking_deadline, qos_);
return dispatcher_.send(frame, tx_deadline, blocking_deadline, qos_);
}
else // Multi Frame Transfer
{
@@ -57,7 +57,7 @@ int TransferSender::send(const uint8_t* payload, int payload_len, uint64_t monot
while (true)
{
const int send_res = dispatcher_.send(frame, monotonic_tx_deadline, monotonic_blocking_deadline, qos_);
const int send_res = dispatcher_.send(frame, tx_deadline, blocking_deadline, qos_);
if (send_res < 0)
return send_res;
@@ -84,13 +84,13 @@ int TransferSender::send(const uint8_t* payload, int payload_len, uint64_t monot
return -1; // Return path analysis is apparently broken. There should be no warning, this 'return' is unreachable.
}
int TransferSender::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 TransferSender::send(const uint8_t* payload, int payload_len, MonotonicTime tx_deadline,
MonotonicTime blocking_deadline, TransferType transfer_type, NodeID dst_node_id)
{
const OutgoingTransferRegistryKey otr_key(data_type_.getID(), transfer_type, dst_node_id);
assert(monotonic_tx_deadline > 0);
const uint64_t otr_deadline = monotonic_tx_deadline + max_transfer_interval_;
assert(!tx_deadline.isZero());
const MonotonicTime otr_deadline = tx_deadline + max_transfer_interval_;
TransferID* const tid = dispatcher_.getOutgoingTransferRegistry().accessOrCreate(otr_key, otr_deadline);
if (tid == NULL)
@@ -103,7 +103,7 @@ int TransferSender::send(const uint8_t* payload, int payload_len, uint64_t monot
const TransferID this_tid = tid->get();
tid->increment();
return send(payload, payload_len, monotonic_tx_deadline, monotonic_blocking_deadline, transfer_type,
return send(payload, payload_len, tx_deadline, blocking_deadline, transfer_type,
dst_node_id, this_tid);
}
+31
View File
@@ -0,0 +1,31 @@
/*
* Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
*/
#include <uavcan/time.hpp>
#include <uavcan/Timestamp.hpp>
namespace uavcan
{
/*
* UtcTime
*/
UtcTime::UtcTime(const Timestamp& ts) // Implicit
{
operator=(ts);
}
UtcTime& UtcTime::operator=(const Timestamp& ts)
{
*this = fromUSec(ts.husec * Timestamp::USEC_PER_LSB);
return *this;
}
UtcTime::operator Timestamp() const
{
Timestamp ts;
ts.husec = toUSec() / Timestamp::USEC_PER_LSB;
return ts;
}
}
+24 -22
View File
@@ -8,37 +8,39 @@
namespace uavcan
{
const uint64_t Timer::InfinitePeriod;
void Timer::handleMonotonicDeadline(uint64_t monotonic_timestamp)
void Timer::handleDeadline(MonotonicTime current_timestamp)
{
assert(!isRunning());
if (period_ != InfinitePeriod)
startWithDeadline(getMonotonicDeadline() + period_);
const MonotonicTime scheduled_deadline = getDeadline();
if (period_ < MonotonicDuration::getInfinite())
startWithDeadline(scheduled_deadline + period_);
// Application can re-register the timer with different params, it's OK
handleTimerEvent(TimerEvent(this, getMonotonicDeadline(), monotonic_timestamp));
handleTimerEvent(TimerEvent(this, scheduled_deadline, current_timestamp));
}
void Timer::startOneShotWithDeadline(uint64_t monotonic_deadline_usec)
void Timer::startOneShotWithDeadline(MonotonicTime deadline)
{
period_ = InfinitePeriod;
MonotonicDeadlineHandler::startWithDeadline(monotonic_deadline_usec);
}
void Timer::startOneShotWithDelay(uint64_t delay_usec)
{
period_ = InfinitePeriod;
MonotonicDeadlineHandler::startWithDelay(delay_usec);
}
void Timer::startPeriodic(uint64_t period_usec)
{
assert(period_usec != InfinitePeriod);
stop();
period_ = period_usec;
MonotonicDeadlineHandler::startWithDelay(period_usec);
period_ = MonotonicDuration::getInfinite();
MonotonicDeadlineHandler::startWithDeadline(deadline);
}
void Timer::startOneShotWithDelay(MonotonicDuration delay)
{
stop();
period_ = MonotonicDuration::getInfinite();
MonotonicDeadlineHandler::startWithDelay(delay);
}
void Timer::startPeriodic(MonotonicDuration period)
{
assert(period < MonotonicDuration::getInfinite());
stop();
period_ = period;
MonotonicDeadlineHandler::startWithDelay(period);
}
}