mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-04-29 16:54:07 +08:00
INode class. Publisher, Subscriber, ServiceServer, ServiceClient now accept INode in constructor instead of the bunch of independent params. Self NodeID now being configured via setNodeID() method instead of constructor param
This commit is contained in:
parent
15cbf96378
commit
613efa49b9
46
libuavcan/include/uavcan/node/abstract_node.hpp
Normal file
46
libuavcan/include/uavcan/node/abstract_node.hpp
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <uavcan/node/scheduler.hpp>
|
||||
#include <uavcan/node/marshal_buffer.hpp>
|
||||
|
||||
namespace uavcan
|
||||
{
|
||||
|
||||
class INode
|
||||
{
|
||||
public:
|
||||
virtual ~INode() { }
|
||||
virtual IAllocator& getAllocator() = 0;
|
||||
virtual Scheduler& getScheduler() = 0;
|
||||
virtual const Scheduler& getScheduler() const = 0;
|
||||
virtual IMarshalBufferProvider& getMarshalBufferProvider() = 0;
|
||||
|
||||
Dispatcher& getDispatcher() { return getScheduler().getDispatcher(); }
|
||||
const Dispatcher& getDispatcher() const { return getScheduler().getDispatcher(); }
|
||||
|
||||
ISystemClock& getSystemClock() { return getScheduler().getSystemClock(); }
|
||||
MonotonicTime getMonotonicTime() const { return getScheduler().getMonotonicTime(); }
|
||||
UtcTime getUtcTime() const { return getScheduler().getUtcTime(); }
|
||||
|
||||
NodeID getNodeID() const { return getScheduler().getDispatcher().getNodeID(); }
|
||||
bool setNodeID(NodeID nid)
|
||||
{
|
||||
return getScheduler().getDispatcher().setNodeID(nid);
|
||||
}
|
||||
|
||||
int spin(MonotonicTime deadline)
|
||||
{
|
||||
return getScheduler().spin(deadline);
|
||||
}
|
||||
|
||||
int spin(MonotonicDuration duration)
|
||||
{
|
||||
return getScheduler().spin(getMonotonicTime() + duration);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@ -4,9 +4,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <uavcan/node/scheduler.hpp>
|
||||
#include <uavcan/node/abstract_node.hpp>
|
||||
#include <uavcan/data_type.hpp>
|
||||
#include <uavcan/node/marshal_buffer.hpp>
|
||||
#include <uavcan/node/global_data_type_registry.hpp>
|
||||
#include <uavcan/util/lazy_constructor.hpp>
|
||||
#include <uavcan/debug.hpp>
|
||||
@ -30,8 +29,7 @@ class GenericPublisher
|
||||
|
||||
const MonotonicDuration max_transfer_interval_; // TODO: memory usage can be reduced
|
||||
MonotonicDuration tx_timeout_;
|
||||
Scheduler& scheduler_;
|
||||
IMarshalBufferProvider& buffer_provider_;
|
||||
INode& node_;
|
||||
LazyConstructor<TransferSender> sender_;
|
||||
|
||||
bool checkInit()
|
||||
@ -50,15 +48,15 @@ class GenericPublisher
|
||||
return false;
|
||||
}
|
||||
sender_.template construct<Dispatcher&, const DataTypeDescriptor&, CanTxQueue::Qos, MonotonicDuration>
|
||||
(scheduler_.getDispatcher(), *descr, CanTxQueue::Qos(Qos), max_transfer_interval_);
|
||||
(node_.getDispatcher(), *descr, CanTxQueue::Qos(Qos), max_transfer_interval_);
|
||||
return true;
|
||||
}
|
||||
|
||||
MonotonicTime getTxDeadline() const { return scheduler_.getMonotonicTimestamp() + tx_timeout_; }
|
||||
MonotonicTime getTxDeadline() const { return node_.getMonotonicTime() + tx_timeout_; }
|
||||
|
||||
IMarshalBuffer* getBuffer()
|
||||
{
|
||||
return buffer_provider_.getBuffer(BitLenToByteLen<DataStruct::MaxBitLen>::Result);
|
||||
return node_.getMarshalBufferProvider().getBuffer(BitLenToByteLen<DataStruct::MaxBitLen>::Result);
|
||||
}
|
||||
|
||||
int genericPublish(const DataStruct& message, TransferType transfer_type, NodeID dst_node_id,
|
||||
@ -94,12 +92,11 @@ class GenericPublisher
|
||||
}
|
||||
|
||||
public:
|
||||
GenericPublisher(Scheduler& scheduler, IMarshalBufferProvider& buffer_provider, MonotonicDuration tx_timeout,
|
||||
GenericPublisher(INode& node, MonotonicDuration tx_timeout,
|
||||
MonotonicDuration max_transfer_interval = TransferSender::getDefaultMaxTransferInterval())
|
||||
: max_transfer_interval_(max_transfer_interval)
|
||||
, tx_timeout_(tx_timeout)
|
||||
, scheduler_(scheduler)
|
||||
, buffer_provider_(buffer_provider)
|
||||
, node_(node)
|
||||
{
|
||||
setTxTimeout(tx_timeout);
|
||||
#if UAVCAN_DEBUG
|
||||
@ -132,7 +129,7 @@ public:
|
||||
tx_timeout_ = tx_timeout;
|
||||
}
|
||||
|
||||
Scheduler& getScheduler() const { return scheduler_; }
|
||||
INode& getNode() const { return node_; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <uavcan/node/scheduler.hpp>
|
||||
#include <uavcan/node/abstract_node.hpp>
|
||||
#include <uavcan/data_type.hpp>
|
||||
#include <uavcan/node/global_data_type_registry.hpp>
|
||||
#include <uavcan/util/compile_time.hpp>
|
||||
@ -107,8 +107,7 @@ class GenericSubscriber : Noncopyable
|
||||
using ReceivedDataStructure<DataStruct>::setTransfer;
|
||||
};
|
||||
|
||||
Scheduler& scheduler_;
|
||||
IAllocator& allocator_;
|
||||
INode& node_;
|
||||
LazyConstructor<TransferForwarder> forwarder_;
|
||||
ReceivedDataStructureSpec message_;
|
||||
uint32_t failure_count_;
|
||||
@ -128,7 +127,8 @@ class GenericSubscriber : Noncopyable
|
||||
UAVCAN_TRACE("GenericSubscriber", "Type [%s] is not registered", DataSpec::getDataTypeFullName());
|
||||
return false;
|
||||
}
|
||||
forwarder_.template construct<SelfType&, const DataTypeDescriptor&, IAllocator&>(*this, *descr, allocator_);
|
||||
forwarder_.template construct<SelfType&, const DataTypeDescriptor&, IAllocator&>
|
||||
(*this, *descr, node_.getAllocator());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -170,7 +170,7 @@ class GenericSubscriber : Noncopyable
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!(scheduler_.getDispatcher().*registration_method)(forwarder_))
|
||||
if (!(node_.getDispatcher().*registration_method)(forwarder_))
|
||||
{
|
||||
UAVCAN_TRACE("GenericSubscriber", "Failed to register transfer listener [%s]",
|
||||
DataSpec::getDataTypeFullName());
|
||||
@ -180,9 +180,8 @@ class GenericSubscriber : Noncopyable
|
||||
}
|
||||
|
||||
protected:
|
||||
GenericSubscriber(Scheduler& scheduler, IAllocator& allocator)
|
||||
: scheduler_(scheduler)
|
||||
, allocator_(allocator)
|
||||
explicit GenericSubscriber(INode& node)
|
||||
: node_(node)
|
||||
, failure_count_(0)
|
||||
{ }
|
||||
|
||||
@ -209,9 +208,9 @@ protected:
|
||||
{
|
||||
if (forwarder_)
|
||||
{
|
||||
scheduler_.getDispatcher().unregisterMessageListener(forwarder_);
|
||||
scheduler_.getDispatcher().unregisterServiceRequestListener(forwarder_);
|
||||
scheduler_.getDispatcher().unregisterServiceResponseListener(forwarder_);
|
||||
node_.getDispatcher().unregisterMessageListener(forwarder_);
|
||||
node_.getDispatcher().unregisterServiceRequestListener(forwarder_);
|
||||
node_.getDispatcher().unregisterServiceResponseListener(forwarder_);
|
||||
}
|
||||
}
|
||||
|
||||
@ -222,7 +221,7 @@ protected:
|
||||
ReceivedDataStructure<DataStruct>& getReceivedStructStorage() { return message_; }
|
||||
|
||||
public:
|
||||
Scheduler& getScheduler() const { return scheduler_; }
|
||||
INode& getNode() const { return node_; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -17,10 +17,9 @@ class Publisher : protected GenericPublisher<DataType_, DataType_>
|
||||
public:
|
||||
typedef DataType_ DataType;
|
||||
|
||||
Publisher(Scheduler& scheduler, IMarshalBufferProvider& buffer_provider,
|
||||
MonotonicDuration tx_timeout = getDefaultTxTimeout(),
|
||||
MonotonicDuration max_transfer_interval = TransferSender::getDefaultMaxTransferInterval())
|
||||
: BaseType(scheduler, buffer_provider, tx_timeout, max_transfer_interval)
|
||||
explicit Publisher(INode& node, MonotonicDuration tx_timeout = getDefaultTxTimeout(),
|
||||
MonotonicDuration max_transfer_interval = TransferSender::getDefaultMaxTransferInterval())
|
||||
: BaseType(node, tx_timeout, max_transfer_interval)
|
||||
{
|
||||
#if UAVCAN_DEBUG
|
||||
assert(getTxTimeout() == tx_timeout); // Making sure default values are OK
|
||||
@ -49,7 +48,7 @@ public:
|
||||
using BaseType::getMaxTxTimeout;
|
||||
using BaseType::getTxTimeout;
|
||||
using BaseType::setTxTimeout;
|
||||
using BaseType::getScheduler;
|
||||
using BaseType::getNode;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -26,7 +26,7 @@ protected:
|
||||
virtual ~DeadlineHandler() { stop(); }
|
||||
|
||||
public:
|
||||
virtual void handleDeadline(MonotonicTime current_timestamp) = 0;
|
||||
virtual void handleDeadline(MonotonicTime current) = 0;
|
||||
|
||||
void startWithDeadline(MonotonicTime deadline);
|
||||
void startWithDelay(MonotonicDuration delay);
|
||||
@ -50,7 +50,7 @@ public:
|
||||
bool doesExist(const DeadlineHandler* mdh) const;
|
||||
unsigned int getNumHandlers() const { return handlers_.getLength(); }
|
||||
|
||||
MonotonicTime pollAndGetMonotonicTimestamp(ISystemClock& sysclock);
|
||||
MonotonicTime pollAndGetMonotonicTime(ISystemClock& sysclock);
|
||||
MonotonicTime getEarliestDeadline() const;
|
||||
};
|
||||
|
||||
@ -75,9 +75,8 @@ class Scheduler : Noncopyable
|
||||
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)
|
||||
Scheduler(ICanDriver& can_driver, IAllocator& allocator, ISystemClock& sysclock, IOutgoingTransferRegistry& otr)
|
||||
: dispatcher_(can_driver, allocator, sysclock, otr)
|
||||
, prev_cleanup_ts_(sysclock.getMonotonic())
|
||||
, deadline_resolution_(MonotonicDuration::fromMSec(DefaultDeadlineResolutionMs))
|
||||
, cleanup_period_(MonotonicDuration::fromMSec(DefaultCleanupPeriodMs))
|
||||
@ -86,11 +85,13 @@ public:
|
||||
int spin(MonotonicTime deadline);
|
||||
|
||||
DeadlineScheduler& getDeadlineScheduler() { return deadline_scheduler_; }
|
||||
Dispatcher& getDispatcher() { return dispatcher_; }
|
||||
|
||||
ISystemClock& getSystemClock() { return dispatcher_.getSystemClock(); }
|
||||
MonotonicTime getMonotonicTimestamp() const { return dispatcher_.getSystemClock().getMonotonic(); }
|
||||
UtcTime getUtcTimestamp() const { return dispatcher_.getSystemClock().getUtc(); }
|
||||
Dispatcher& getDispatcher() { return dispatcher_; }
|
||||
const Dispatcher& getDispatcher() const { return dispatcher_; }
|
||||
|
||||
ISystemClock& getSystemClock() { return dispatcher_.getSystemClock(); }
|
||||
MonotonicTime getMonotonicTime() const { return dispatcher_.getSystemClock().getMonotonic(); }
|
||||
UtcTime getUtcTime() const { return dispatcher_.getSystemClock().getUtc(); }
|
||||
|
||||
MonotonicDuration getDeadlineResolution() const { return deadline_resolution_; }
|
||||
void setDeadlineResolution(MonotonicDuration res)
|
||||
|
||||
@ -73,7 +73,6 @@ private:
|
||||
typedef GenericSubscriber<DataType, ResponseType, TransferListenerType> SubscriberType;
|
||||
|
||||
PublisherType publisher_;
|
||||
IAllocator& allocator_;
|
||||
Callback callback_;
|
||||
MonotonicDuration request_timeout_;
|
||||
bool pending_;
|
||||
@ -128,12 +127,10 @@ private:
|
||||
}
|
||||
|
||||
public:
|
||||
ServiceClient(Scheduler& scheduler, IAllocator& allocator, IMarshalBufferProvider& buffer_provider,
|
||||
const Callback& callback = Callback())
|
||||
: SubscriberType(scheduler, allocator)
|
||||
, DeadlineHandler(scheduler)
|
||||
, publisher_(scheduler, buffer_provider, getDefaultRequestTimeout())
|
||||
, allocator_(allocator)
|
||||
explicit ServiceClient(INode& node, const Callback& callback = Callback())
|
||||
: SubscriberType(node)
|
||||
, DeadlineHandler(node.getScheduler())
|
||||
, publisher_(node, getDefaultRequestTimeout())
|
||||
, callback_(callback)
|
||||
, request_timeout_(getDefaultRequestTimeout())
|
||||
, pending_(false)
|
||||
@ -177,8 +174,8 @@ public:
|
||||
*/
|
||||
const OutgoingTransferRegistryKey otr_key(descr->getID(), TransferTypeServiceRequest, server_node_id);
|
||||
const MonotonicTime otr_deadline =
|
||||
SubscriberType::getScheduler().getMonotonicTimestamp() + TransferSender::getDefaultMaxTransferInterval();
|
||||
TransferID* const otr_tid = SubscriberType::getScheduler().getDispatcher().getOutgoingTransferRegistry()
|
||||
SubscriberType::getNode().getMonotonicTime() + TransferSender::getDefaultMaxTransferInterval();
|
||||
TransferID* const otr_tid = SubscriberType::getNode().getDispatcher().getOutgoingTransferRegistry()
|
||||
.accessOrCreate(otr_key, otr_deadline);
|
||||
if (!otr_tid)
|
||||
{
|
||||
|
||||
@ -57,9 +57,9 @@ private:
|
||||
}
|
||||
|
||||
public:
|
||||
ServiceServer(Scheduler& scheduler, IAllocator& allocator, IMarshalBufferProvider& buffer_provider)
|
||||
: SubscriberType(scheduler, allocator)
|
||||
, publisher_(scheduler, buffer_provider, getDefaultTxTimeout())
|
||||
explicit ServiceServer(INode& node)
|
||||
: SubscriberType(node)
|
||||
, publisher_(node, getDefaultTxTimeout())
|
||||
, callback_()
|
||||
, response_failure_count_(0)
|
||||
{
|
||||
|
||||
@ -36,8 +36,8 @@ class Subscriber : public GenericSubscriber<DataType_, DataType_,
|
||||
public:
|
||||
typedef DataType_ DataType;
|
||||
|
||||
Subscriber(Scheduler& scheduler, IAllocator& allocator)
|
||||
: BaseType(scheduler, allocator)
|
||||
explicit Subscriber(INode& node)
|
||||
: BaseType(node)
|
||||
, callback_()
|
||||
{
|
||||
StaticAssert<DataTypeKind(DataType::DataTypeKind) == DataTypeKindMessage>::check();
|
||||
|
||||
@ -31,7 +31,7 @@ class Timer : private DeadlineHandler
|
||||
{
|
||||
MonotonicDuration period_;
|
||||
|
||||
void handleDeadline(MonotonicTime current_timestamp);
|
||||
void handleDeadline(MonotonicTime current);
|
||||
|
||||
public:
|
||||
using DeadlineHandler::stop;
|
||||
|
||||
@ -51,17 +51,15 @@ class Dispatcher : Noncopyable
|
||||
ListenerRegister lsrv_req_;
|
||||
ListenerRegister lsrv_resp_;
|
||||
|
||||
const NodeID self_node_id_;
|
||||
NodeID self_node_id_;
|
||||
|
||||
void handleFrame(const CanRxFrame& can_frame);
|
||||
|
||||
public:
|
||||
Dispatcher(ICanDriver& driver, IAllocator& allocator, ISystemClock& sysclock, IOutgoingTransferRegistry& otr,
|
||||
NodeID self_node_id)
|
||||
Dispatcher(ICanDriver& driver, IAllocator& allocator, ISystemClock& sysclock, IOutgoingTransferRegistry& otr)
|
||||
: canio_(driver, allocator, sysclock)
|
||||
, sysclock_(sysclock)
|
||||
, outgoing_transfer_reg_(otr)
|
||||
, self_node_id_(self_node_id)
|
||||
{ }
|
||||
|
||||
int spin(MonotonicTime deadline);
|
||||
@ -87,7 +85,8 @@ public:
|
||||
|
||||
IOutgoingTransferRegistry& getOutgoingTransferRegistry() { return outgoing_transfer_reg_; }
|
||||
|
||||
NodeID getSelfNodeID() const { return self_node_id_; }
|
||||
NodeID getNodeID() const { return self_node_id_; }
|
||||
bool setNodeID(NodeID nid);
|
||||
|
||||
const ISystemClock& getSystemClock() const { return sysclock_; }
|
||||
ISystemClock& getSystemClock() { return sysclock_; }
|
||||
|
||||
@ -21,7 +21,7 @@ void DeadlineHandler::startWithDeadline(MonotonicTime deadline)
|
||||
|
||||
void DeadlineHandler::startWithDelay(MonotonicDuration delay)
|
||||
{
|
||||
startWithDeadline(scheduler_.getMonotonicTimestamp() + delay);
|
||||
startWithDeadline(scheduler_.getMonotonicTime() + delay);
|
||||
}
|
||||
|
||||
void DeadlineHandler::stop()
|
||||
@ -80,7 +80,7 @@ bool DeadlineScheduler::doesExist(const DeadlineHandler* mdh) const
|
||||
return false;
|
||||
}
|
||||
|
||||
MonotonicTime DeadlineScheduler::pollAndGetMonotonicTimestamp(ISystemClock& sysclock)
|
||||
MonotonicTime DeadlineScheduler::pollAndGetMonotonicTime(ISystemClock& sysclock)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
@ -117,7 +117,7 @@ MonotonicTime DeadlineScheduler::getEarliestDeadline() const
|
||||
MonotonicTime Scheduler::computeDispatcherSpinDeadline(MonotonicTime spin_deadline) const
|
||||
{
|
||||
const MonotonicTime earliest = std::min(deadline_scheduler_.getEarliestDeadline(), spin_deadline);
|
||||
const MonotonicTime ts = getMonotonicTimestamp();
|
||||
const MonotonicTime ts = getMonotonicTime();
|
||||
if (earliest > ts)
|
||||
{
|
||||
if (ts - earliest > deadline_resolution_)
|
||||
@ -148,7 +148,7 @@ int Scheduler::spin(MonotonicTime deadline)
|
||||
if (retval < 0)
|
||||
break;
|
||||
|
||||
const MonotonicTime ts = deadline_scheduler_.pollAndGetMonotonicTimestamp(getSystemClock());
|
||||
const MonotonicTime ts = deadline_scheduler_.pollAndGetMonotonicTime(getSystemClock());
|
||||
pollCleanup(ts, retval);
|
||||
if (ts >= deadline)
|
||||
break;
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
namespace uavcan
|
||||
{
|
||||
|
||||
void Timer::handleDeadline(MonotonicTime current_timestamp)
|
||||
void Timer::handleDeadline(MonotonicTime current)
|
||||
{
|
||||
assert(!isRunning());
|
||||
|
||||
@ -18,7 +18,7 @@ void Timer::handleDeadline(MonotonicTime current_timestamp)
|
||||
startWithDeadline(scheduled_time + period_);
|
||||
|
||||
// Application can re-register the timer with different params, it's OK
|
||||
handleTimerEvent(TimerEvent(scheduled_time, current_timestamp));
|
||||
handleTimerEvent(TimerEvent(scheduled_time, current));
|
||||
}
|
||||
|
||||
void Timer::startOneShotWithDeadline(MonotonicTime deadline)
|
||||
|
||||
@ -69,7 +69,7 @@ void Dispatcher::handleFrame(const CanRxFrame& can_frame)
|
||||
}
|
||||
|
||||
if ((frame.getDstNodeID() != NodeID::Broadcast) &&
|
||||
(frame.getDstNodeID() != getSelfNodeID()))
|
||||
(frame.getDstNodeID() != getNodeID()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -117,7 +117,7 @@ int Dispatcher::spin(MonotonicTime deadline)
|
||||
int Dispatcher::send(const Frame& frame, MonotonicTime tx_deadline, MonotonicTime blocking_deadline,
|
||||
CanTxQueue::Qos qos)
|
||||
{
|
||||
if (frame.getSrcNodeID() != getSelfNodeID())
|
||||
if (frame.getSrcNodeID() != getNodeID())
|
||||
{
|
||||
assert(0);
|
||||
return -1;
|
||||
@ -188,4 +188,14 @@ void Dispatcher::unregisterServiceResponseListener(TransferListenerBase* listene
|
||||
lsrv_resp_.remove(listener);
|
||||
}
|
||||
|
||||
bool Dispatcher::setNodeID(NodeID nid)
|
||||
{
|
||||
if (nid.isUnicast() && !self_node_id_.isValid())
|
||||
{
|
||||
self_node_id_ = nid;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -14,7 +14,7 @@ int TransferSender::send(const uint8_t* payload, int payload_len, MonotonicTime
|
||||
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);
|
||||
Frame frame(data_type_.getID(), transfer_type, dispatcher_.getNodeID(), dst_node_id, 0, tid);
|
||||
|
||||
if (frame.getMaxPayloadLen() >= payload_len) // Single Frame Transfer
|
||||
{
|
||||
|
||||
@ -7,24 +7,16 @@
|
||||
#include <uavcan/mavlink/Message.hpp>
|
||||
#include "../clock.hpp"
|
||||
#include "../transport/can/can.hpp"
|
||||
#include "test_node.hpp"
|
||||
|
||||
|
||||
TEST(Publisher, Basic)
|
||||
{
|
||||
uavcan::PoolAllocator<uavcan::MemPoolBlockSize * 8, uavcan::MemPoolBlockSize> pool;
|
||||
uavcan::PoolManager<1> poolmgr;
|
||||
poolmgr.addPool(&pool);
|
||||
|
||||
SystemClockMock clock_mock(100);
|
||||
CanDriverMock can_driver(2, clock_mock);
|
||||
TestNode node(can_driver, clock_mock, 1);
|
||||
|
||||
uavcan::OutgoingTransferRegistry<8> out_trans_reg(poolmgr);
|
||||
|
||||
uavcan::Scheduler sch(can_driver, poolmgr, clock_mock, out_trans_reg, uavcan::NodeID(1));
|
||||
|
||||
uavcan::MarshalBufferProvider<> buffer_provider;
|
||||
|
||||
uavcan::Publisher<uavcan::mavlink::Message> publisher(sch, buffer_provider);
|
||||
uavcan::Publisher<uavcan::mavlink::Message> publisher(node);
|
||||
|
||||
std::cout <<
|
||||
"sizeof(uavcan::Publisher<uavcan::mavlink::Message>): " <<
|
||||
@ -61,7 +53,7 @@ TEST(Publisher, Basic)
|
||||
// uint_fast16_t data_type_id, TransferType transfer_type, NodeID src_node_id, NodeID dst_node_id,
|
||||
// uint_fast8_t frame_index, TransferID transfer_id, bool last_frame = false
|
||||
uavcan::Frame expected_frame(uavcan::mavlink::Message::DefaultDataTypeID, uavcan::TransferTypeMessageBroadcast,
|
||||
sch.getDispatcher().getSelfNodeID(), uavcan::NodeID::Broadcast, 0, 0, true);
|
||||
node.getNodeID(), uavcan::NodeID::Broadcast, 0, 0, true);
|
||||
expected_frame.setPayload(expected_transfer_payload, 7);
|
||||
|
||||
uavcan::CanFrame expected_can_frame;
|
||||
@ -76,7 +68,7 @@ TEST(Publisher, Basic)
|
||||
ASSERT_LT(0, publisher.broadcast(msg));
|
||||
|
||||
expected_frame = uavcan::Frame(uavcan::mavlink::Message::DefaultDataTypeID, uavcan::TransferTypeMessageBroadcast,
|
||||
sch.getDispatcher().getSelfNodeID(), uavcan::NodeID::Broadcast, 0, 1, true);
|
||||
node.getNodeID(), uavcan::NodeID::Broadcast, 0, 1, true);
|
||||
expected_frame.setPayload(expected_transfer_payload, 7);
|
||||
ASSERT_TRUE(expected_frame.compile(expected_can_frame));
|
||||
|
||||
@ -97,7 +89,7 @@ TEST(Publisher, Basic)
|
||||
// uint_fast16_t data_type_id, TransferType transfer_type, NodeID src_node_id, NodeID dst_node_id,
|
||||
// uint_fast8_t frame_index, TransferID transfer_id, bool last_frame = false
|
||||
uavcan::Frame expected_frame(uavcan::mavlink::Message::DefaultDataTypeID, uavcan::TransferTypeMessageUnicast,
|
||||
sch.getDispatcher().getSelfNodeID(), uavcan::NodeID(0x44), 0, 0, true);
|
||||
node.getNodeID(), uavcan::NodeID(0x44), 0, 0, true);
|
||||
expected_frame.setPayload(expected_transfer_payload, 7);
|
||||
|
||||
uavcan::CanFrame expected_can_frame;
|
||||
|
||||
@ -33,7 +33,8 @@ TEST(Scheduler, Timers)
|
||||
|
||||
uavcan::OutgoingTransferRegistry<8> out_trans_reg(poolmgr);
|
||||
|
||||
uavcan::Scheduler sch(can_driver, poolmgr, clock_driver, out_trans_reg, uavcan::NodeID(1));
|
||||
uavcan::Scheduler sch(can_driver, poolmgr, clock_driver, out_trans_reg);
|
||||
sch.getDispatcher().setNodeID(1);
|
||||
|
||||
/*
|
||||
* Registration
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
#include <queue>
|
||||
#include "../clock.hpp"
|
||||
#include "../transport/can/can.hpp"
|
||||
#include "test_node.hpp"
|
||||
|
||||
|
||||
template <typename DataType>
|
||||
@ -53,29 +54,6 @@ static void stringServiceServerCallback(const uavcan::ReceivedDataStructure<root
|
||||
}
|
||||
|
||||
|
||||
struct MakeshiftNode : uavcan::Noncopyable
|
||||
{
|
||||
uavcan::PoolAllocator<uavcan::MemPoolBlockSize * 8, uavcan::MemPoolBlockSize> pool;
|
||||
uavcan::PoolManager<1> poolmgr;
|
||||
SystemClockDriver clock_driver;
|
||||
uavcan::MarshalBufferProvider<> buffer_provider;
|
||||
uavcan::OutgoingTransferRegistry<8> otr;
|
||||
uavcan::Scheduler scheduler;
|
||||
|
||||
MakeshiftNode(uavcan::ICanDriver& can_driver, uavcan::NodeID self_node_id)
|
||||
: otr(poolmgr)
|
||||
, scheduler(can_driver, poolmgr, clock_driver, otr, self_node_id)
|
||||
{
|
||||
poolmgr.addPool(&pool);
|
||||
}
|
||||
|
||||
void spin(uavcan::MonotonicDuration duration)
|
||||
{
|
||||
scheduler.spin(clock_driver.getMonotonic() + duration);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct PairableCanDriver : public uavcan::ICanDriver, public uavcan::ICanIface
|
||||
{
|
||||
uavcan::ISystemClock& clock;
|
||||
@ -144,18 +122,16 @@ struct PairableCanDriver : public uavcan::ICanDriver, public uavcan::ICanIface
|
||||
TEST(ServiceClient, Basic)
|
||||
{
|
||||
SystemClockDriver clock;
|
||||
|
||||
PairableCanDriver can_a(clock), can_b(clock);
|
||||
can_a.linkTogether(&can_b);
|
||||
|
||||
MakeshiftNode node_a(can_a, 1), node_b(can_b, 2);
|
||||
TestNode node_a(can_a, clock, 1), node_b(can_b, clock, 2);
|
||||
|
||||
// Type registration
|
||||
uavcan::GlobalDataTypeRegistry::instance().reset();
|
||||
uavcan::DefaultDataTypeRegistrator<root_ns_a::StringService> _registrator;
|
||||
|
||||
// Server
|
||||
uavcan::ServiceServer<root_ns_a::StringService> server(node_a.scheduler, node_a.poolmgr, node_a.buffer_provider);
|
||||
uavcan::ServiceServer<root_ns_a::StringService> server(node_a);
|
||||
ASSERT_EQ(1, server.start(stringServiceServerCallback));
|
||||
|
||||
{
|
||||
@ -165,17 +141,17 @@ TEST(ServiceClient, Basic)
|
||||
typename ServiceCallResultHandler<root_ns_a::StringService>::Binder > ClientType;
|
||||
ServiceCallResultHandler<root_ns_a::StringService> handler;
|
||||
|
||||
ClientType client1(node_b.scheduler, node_b.poolmgr, node_b.buffer_provider);
|
||||
ClientType client2(node_b.scheduler, node_b.poolmgr, node_b.buffer_provider);
|
||||
ClientType client3(node_b.scheduler, node_b.poolmgr, node_b.buffer_provider);
|
||||
ClientType client1(node_b);
|
||||
ClientType client2(node_b);
|
||||
ClientType client3(node_b);
|
||||
|
||||
client1.setCallback(handler.bind());
|
||||
client2.setCallback(client1.getCallback());
|
||||
client3.setCallback(client1.getCallback());
|
||||
client3.setRequestTimeout(uavcan::MonotonicDuration::fromMSec(100));
|
||||
|
||||
ASSERT_EQ(1, node_a.scheduler.getDispatcher().getNumServiceRequestListeners());
|
||||
ASSERT_EQ(0, node_b.scheduler.getDispatcher().getNumServiceResponseListeners()); // NOT listening!
|
||||
ASSERT_EQ(1, node_a.getDispatcher().getNumServiceRequestListeners());
|
||||
ASSERT_EQ(0, node_b.getDispatcher().getNumServiceResponseListeners()); // NOT listening!
|
||||
|
||||
root_ns_a::StringService::Request request;
|
||||
request.string_request = "Hello world";
|
||||
@ -184,7 +160,7 @@ TEST(ServiceClient, Basic)
|
||||
ASSERT_LT(0, client2.call(1, request)); // OK
|
||||
ASSERT_LT(0, client3.call(99, request)); // Will timeout!
|
||||
|
||||
ASSERT_EQ(3, node_b.scheduler.getDispatcher().getNumServiceResponseListeners()); // Listening now!
|
||||
ASSERT_EQ(3, node_b.getDispatcher().getNumServiceResponseListeners()); // Listening now!
|
||||
|
||||
ASSERT_TRUE(client1.isPending());
|
||||
ASSERT_TRUE(client2.isPending());
|
||||
@ -193,7 +169,7 @@ TEST(ServiceClient, Basic)
|
||||
node_a.spin(uavcan::MonotonicDuration::fromMSec(10));
|
||||
node_b.spin(uavcan::MonotonicDuration::fromMSec(10));
|
||||
|
||||
ASSERT_EQ(1, node_b.scheduler.getDispatcher().getNumServiceResponseListeners()); // Third is still listening!
|
||||
ASSERT_EQ(1, node_b.getDispatcher().getNumServiceResponseListeners()); // Third is still listening!
|
||||
|
||||
ASSERT_FALSE(client1.isPending());
|
||||
ASSERT_FALSE(client2.isPending());
|
||||
@ -211,7 +187,7 @@ TEST(ServiceClient, Basic)
|
||||
ASSERT_FALSE(client2.isPending());
|
||||
ASSERT_FALSE(client3.isPending());
|
||||
|
||||
ASSERT_EQ(0, node_b.scheduler.getDispatcher().getNumServiceResponseListeners()); // Third has timed out :(
|
||||
ASSERT_EQ(0, node_b.getDispatcher().getNumServiceResponseListeners()); // Third has timed out :(
|
||||
|
||||
// Validating
|
||||
ASSERT_TRUE(handler.match(ResultType::ErrorTimeout, 99, root_ns_a::StringService::Response()));
|
||||
@ -219,11 +195,11 @@ TEST(ServiceClient, Basic)
|
||||
// Stray request
|
||||
ASSERT_LT(0, client3.call(99, request)); // Will timeout!
|
||||
ASSERT_TRUE(client3.isPending());
|
||||
ASSERT_EQ(1, node_b.scheduler.getDispatcher().getNumServiceResponseListeners());
|
||||
ASSERT_EQ(1, node_b.getDispatcher().getNumServiceResponseListeners());
|
||||
}
|
||||
|
||||
// All destroyed - nobody listening
|
||||
ASSERT_EQ(0, node_b.scheduler.getDispatcher().getNumServiceResponseListeners());
|
||||
ASSERT_EQ(0, node_b.getDispatcher().getNumServiceResponseListeners());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
#include <root_ns_a/StringService.hpp>
|
||||
#include "../clock.hpp"
|
||||
#include "../transport/can/can.hpp"
|
||||
#include "test_node.hpp"
|
||||
|
||||
|
||||
struct ServerImpl
|
||||
@ -36,30 +37,22 @@ struct ServerImpl
|
||||
|
||||
TEST(ServiceServer, Basic)
|
||||
{
|
||||
uavcan::PoolAllocator<uavcan::MemPoolBlockSize * 8, uavcan::MemPoolBlockSize> pool;
|
||||
uavcan::PoolManager<1> poolmgr;
|
||||
poolmgr.addPool(&pool);
|
||||
|
||||
// Manual type registration - we can't rely on the GDTR state
|
||||
uavcan::GlobalDataTypeRegistry::instance().reset();
|
||||
uavcan::DefaultDataTypeRegistrator<root_ns_a::StringService> _registrator;
|
||||
|
||||
SystemClockDriver clock_driver;
|
||||
CanDriverMock can_driver(1, clock_driver);
|
||||
|
||||
uavcan::MarshalBufferProvider<> buffer_provider;
|
||||
uavcan::OutgoingTransferRegistry<8> out_trans_reg(poolmgr);
|
||||
|
||||
uavcan::Scheduler sch(can_driver, poolmgr, clock_driver, out_trans_reg, uavcan::NodeID(1));
|
||||
TestNode node(can_driver, clock_driver, 1);
|
||||
|
||||
ServerImpl impl("456");
|
||||
|
||||
{
|
||||
uavcan::ServiceServer<root_ns_a::StringService, ServerImpl::Binder> server(sch, poolmgr, buffer_provider);
|
||||
uavcan::ServiceServer<root_ns_a::StringService, ServerImpl::Binder> server(node);
|
||||
|
||||
ASSERT_EQ(0, sch.getDispatcher().getNumServiceRequestListeners());
|
||||
ASSERT_EQ(0, node.getDispatcher().getNumServiceRequestListeners());
|
||||
server.start(impl.bind());
|
||||
ASSERT_EQ(1, sch.getDispatcher().getNumServiceRequestListeners());
|
||||
ASSERT_EQ(1, node.getDispatcher().getNumServiceRequestListeners());
|
||||
|
||||
/*
|
||||
* Request frames
|
||||
@ -78,7 +71,7 @@ TEST(ServiceServer, Basic)
|
||||
can_driver.ifaces[0].pushRx(rx_frame);
|
||||
}
|
||||
|
||||
sch.spin(clock_driver.getMonotonic() + uavcan::MonotonicDuration::fromUSec(10000));
|
||||
node.spin(clock_driver.getMonotonic() + uavcan::MonotonicDuration::fromUSec(10000));
|
||||
|
||||
/*
|
||||
* Responses (MFT)
|
||||
@ -113,7 +106,7 @@ TEST(ServiceServer, Basic)
|
||||
ASSERT_EQ(0, server.getRequestFailureCount());
|
||||
ASSERT_EQ(0, server.getResponseFailureCount());
|
||||
|
||||
ASSERT_EQ(1, sch.getDispatcher().getNumServiceRequestListeners());
|
||||
ASSERT_EQ(1, node.getDispatcher().getNumServiceRequestListeners());
|
||||
}
|
||||
ASSERT_EQ(0, sch.getDispatcher().getNumServiceRequestListeners());
|
||||
ASSERT_EQ(0, node.getDispatcher().getNumServiceRequestListeners());
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
#include <root_ns_a/EmptyMessage.hpp>
|
||||
#include "../clock.hpp"
|
||||
#include "../transport/can/can.hpp"
|
||||
#include "test_node.hpp"
|
||||
|
||||
|
||||
template <typename DataType>
|
||||
@ -59,27 +60,20 @@ struct SubscriptionListener
|
||||
|
||||
TEST(Subscriber, Basic)
|
||||
{
|
||||
uavcan::PoolAllocator<uavcan::MemPoolBlockSize * 8, uavcan::MemPoolBlockSize> pool;
|
||||
uavcan::PoolManager<1> poolmgr;
|
||||
poolmgr.addPool(&pool);
|
||||
|
||||
// Manual type registration - we can't rely on the GDTR state
|
||||
uavcan::GlobalDataTypeRegistry::instance().reset();
|
||||
uavcan::DefaultDataTypeRegistrator<uavcan::mavlink::Message> _registrator;
|
||||
|
||||
SystemClockDriver clock_driver;
|
||||
CanDriverMock can_driver(2, clock_driver);
|
||||
|
||||
uavcan::OutgoingTransferRegistry<8> out_trans_reg(poolmgr);
|
||||
|
||||
uavcan::Scheduler sch(can_driver, poolmgr, clock_driver, out_trans_reg, uavcan::NodeID(1));
|
||||
TestNode node(can_driver, clock_driver, 1);
|
||||
|
||||
typedef SubscriptionListener<uavcan::mavlink::Message> Listener;
|
||||
|
||||
uavcan::Subscriber<uavcan::mavlink::Message, Listener::ExtendedBinder> sub_extended(sch, poolmgr);
|
||||
uavcan::Subscriber<uavcan::mavlink::Message, Listener::ExtendedBinder> sub_extended2(sch, poolmgr); // Not used
|
||||
uavcan::Subscriber<uavcan::mavlink::Message, Listener::SimpleBinder> sub_simple(sch, poolmgr);
|
||||
uavcan::Subscriber<uavcan::mavlink::Message, Listener::SimpleBinder> sub_simple2(sch, poolmgr); // Not used
|
||||
uavcan::Subscriber<uavcan::mavlink::Message, Listener::ExtendedBinder> sub_extended(node);
|
||||
uavcan::Subscriber<uavcan::mavlink::Message, Listener::ExtendedBinder> sub_extended2(node); // Not used
|
||||
uavcan::Subscriber<uavcan::mavlink::Message, Listener::SimpleBinder> sub_simple(node);
|
||||
uavcan::Subscriber<uavcan::mavlink::Message, Listener::SimpleBinder> sub_simple2(node); // Not used
|
||||
|
||||
std::cout <<
|
||||
"sizeof(uavcan::Subscriber<uavcan::mavlink::Message, Listener::ExtendedBinder>): " <<
|
||||
@ -115,7 +109,7 @@ TEST(Subscriber, Basic)
|
||||
{
|
||||
uavcan::TransferType tt = (i & 1) ? uavcan::TransferTypeMessageUnicast : uavcan::TransferTypeMessageBroadcast;
|
||||
uavcan::NodeID dni = (tt == uavcan::TransferTypeMessageBroadcast) ?
|
||||
uavcan::NodeID::Broadcast : sch.getDispatcher().getSelfNodeID();
|
||||
uavcan::NodeID::Broadcast : node.getDispatcher().getNodeID();
|
||||
// uint_fast16_t data_type_id, TransferType transfer_type, NodeID src_node_id, NodeID dst_node_id,
|
||||
// uint_fast8_t frame_index, TransferID transfer_id, bool last_frame
|
||||
uavcan::Frame frame(uavcan::mavlink::Message::DefaultDataTypeID, tt, uavcan::NodeID(i + 100), dni, 0, i, true);
|
||||
@ -127,19 +121,19 @@ TEST(Subscriber, Basic)
|
||||
/*
|
||||
* Reception
|
||||
*/
|
||||
ASSERT_EQ(0, sch.getDispatcher().getNumMessageListeners());
|
||||
ASSERT_EQ(0, node.getDispatcher().getNumMessageListeners());
|
||||
|
||||
ASSERT_EQ(1, sub_extended.start(listener.bindExtended()));
|
||||
ASSERT_EQ(1, sub_extended2.start(listener.bindExtended()));
|
||||
ASSERT_EQ(1, sub_simple.start(listener.bindSimple()));
|
||||
ASSERT_EQ(1, sub_simple2.start(listener.bindSimple()));
|
||||
|
||||
ASSERT_EQ(4, sch.getDispatcher().getNumMessageListeners());
|
||||
ASSERT_EQ(4, node.getDispatcher().getNumMessageListeners());
|
||||
|
||||
sub_extended2.stop(); // These are not used - making sure they aren't receiving anything
|
||||
sub_simple2.stop();
|
||||
|
||||
ASSERT_EQ(2, sch.getDispatcher().getNumMessageListeners());
|
||||
ASSERT_EQ(2, node.getDispatcher().getNumMessageListeners());
|
||||
|
||||
for (unsigned int i = 0; i < rx_frames.size(); i++)
|
||||
{
|
||||
@ -147,7 +141,7 @@ TEST(Subscriber, Basic)
|
||||
can_driver.ifaces[1].pushRx(rx_frames[i]);
|
||||
}
|
||||
|
||||
ASSERT_LE(0, sch.spin(clock_driver.getMonotonic() + durMono(10000)));
|
||||
ASSERT_LE(0, node.spin(clock_driver.getMonotonic() + durMono(10000)));
|
||||
|
||||
/*
|
||||
* Validation
|
||||
@ -175,14 +169,14 @@ TEST(Subscriber, Basic)
|
||||
/*
|
||||
* Unregistration
|
||||
*/
|
||||
ASSERT_EQ(2, sch.getDispatcher().getNumMessageListeners());
|
||||
ASSERT_EQ(2, node.getDispatcher().getNumMessageListeners());
|
||||
|
||||
sub_extended.stop();
|
||||
sub_extended2.stop();
|
||||
sub_simple.stop();
|
||||
sub_simple2.stop();
|
||||
|
||||
ASSERT_EQ(0, sch.getDispatcher().getNumMessageListeners());
|
||||
ASSERT_EQ(0, node.getDispatcher().getNumMessageListeners());
|
||||
}
|
||||
|
||||
|
||||
@ -194,26 +188,19 @@ static void panickingSink(const uavcan::ReceivedDataStructure<uavcan::mavlink::M
|
||||
|
||||
TEST(Subscriber, FailureCount)
|
||||
{
|
||||
uavcan::PoolAllocator<uavcan::MemPoolBlockSize * 8, uavcan::MemPoolBlockSize> pool;
|
||||
uavcan::PoolManager<1> poolmgr;
|
||||
poolmgr.addPool(&pool);
|
||||
|
||||
// Manual type registration - we can't rely on the GDTR state
|
||||
uavcan::GlobalDataTypeRegistry::instance().reset();
|
||||
uavcan::DefaultDataTypeRegistrator<uavcan::mavlink::Message> _registrator;
|
||||
|
||||
SystemClockDriver clock_driver;
|
||||
CanDriverMock can_driver(2, clock_driver);
|
||||
|
||||
uavcan::OutgoingTransferRegistry<8> out_trans_reg(poolmgr);
|
||||
|
||||
uavcan::Scheduler sch(can_driver, poolmgr, clock_driver, out_trans_reg, uavcan::NodeID(1));
|
||||
TestNode node(can_driver, clock_driver, 1);
|
||||
|
||||
{
|
||||
uavcan::Subscriber<uavcan::mavlink::Message> sub(sch, poolmgr);
|
||||
ASSERT_EQ(0, sch.getDispatcher().getNumMessageListeners());
|
||||
uavcan::Subscriber<uavcan::mavlink::Message> sub(node);
|
||||
ASSERT_EQ(0, node.getDispatcher().getNumMessageListeners());
|
||||
sub.start(panickingSink);
|
||||
ASSERT_EQ(1, sch.getDispatcher().getNumMessageListeners());
|
||||
ASSERT_EQ(1, node.getDispatcher().getNumMessageListeners());
|
||||
|
||||
ASSERT_EQ(0, sub.getFailureCount());
|
||||
|
||||
@ -229,36 +216,29 @@ TEST(Subscriber, FailureCount)
|
||||
can_driver.ifaces[1].pushRx(rx_frame);
|
||||
}
|
||||
|
||||
ASSERT_LE(0, sch.spin(clock_driver.getMonotonic() + durMono(10000)));
|
||||
ASSERT_LE(0, node.spin(clock_driver.getMonotonic() + durMono(10000)));
|
||||
|
||||
ASSERT_EQ(4, sub.getFailureCount());
|
||||
|
||||
ASSERT_EQ(1, sch.getDispatcher().getNumMessageListeners()); // Still there
|
||||
ASSERT_EQ(1, node.getDispatcher().getNumMessageListeners()); // Still there
|
||||
}
|
||||
ASSERT_EQ(0, sch.getDispatcher().getNumMessageListeners()); // Removed
|
||||
ASSERT_EQ(0, node.getDispatcher().getNumMessageListeners()); // Removed
|
||||
}
|
||||
|
||||
|
||||
TEST(Subscriber, SingleFrameTransfer)
|
||||
{
|
||||
uavcan::PoolAllocator<uavcan::MemPoolBlockSize * 8, uavcan::MemPoolBlockSize> pool;
|
||||
uavcan::PoolManager<1> poolmgr;
|
||||
poolmgr.addPool(&pool);
|
||||
|
||||
// Manual type registration - we can't rely on the GDTR state
|
||||
uavcan::GlobalDataTypeRegistry::instance().reset();
|
||||
uavcan::DefaultDataTypeRegistrator<root_ns_a::EmptyMessage> _registrator;
|
||||
|
||||
SystemClockDriver clock_driver;
|
||||
CanDriverMock can_driver(2, clock_driver);
|
||||
|
||||
uavcan::OutgoingTransferRegistry<8> out_trans_reg(poolmgr);
|
||||
|
||||
uavcan::Scheduler sch(can_driver, poolmgr, clock_driver, out_trans_reg, uavcan::NodeID(1));
|
||||
TestNode node(can_driver, clock_driver, 1);
|
||||
|
||||
typedef SubscriptionListener<root_ns_a::EmptyMessage> Listener;
|
||||
|
||||
uavcan::Subscriber<root_ns_a::EmptyMessage, Listener::SimpleBinder> sub(sch, poolmgr);
|
||||
uavcan::Subscriber<root_ns_a::EmptyMessage, Listener::SimpleBinder> sub(node);
|
||||
|
||||
std::cout <<
|
||||
"sizeof(uavcan::Subscriber<root_ns_a::EmptyMessage, Listener::SimpleBinder>): " <<
|
||||
@ -280,7 +260,7 @@ TEST(Subscriber, SingleFrameTransfer)
|
||||
can_driver.ifaces[1].pushRx(rx_frame);
|
||||
}
|
||||
|
||||
ASSERT_LE(0, sch.spin(clock_driver.getMonotonic() + durMono(10000)));
|
||||
ASSERT_LE(0, node.spin(clock_driver.getMonotonic() + durMono(10000)));
|
||||
|
||||
ASSERT_EQ(0, sub.getFailureCount());
|
||||
|
||||
|
||||
31
libuavcan/test/node/test_node.hpp
Normal file
31
libuavcan/test/node/test_node.hpp
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <uavcan/node/abstract_node.hpp>
|
||||
#include <uavcan/util/lazy_constructor.hpp>
|
||||
|
||||
struct TestNode : public uavcan::INode
|
||||
{
|
||||
uavcan::PoolAllocator<uavcan::MemPoolBlockSize * 8, uavcan::MemPoolBlockSize> pool;
|
||||
uavcan::PoolManager<1> poolmgr;
|
||||
uavcan::MarshalBufferProvider<> buffer_provider;
|
||||
uavcan::OutgoingTransferRegistry<8> otr;
|
||||
uavcan::Scheduler scheduler;
|
||||
|
||||
TestNode(uavcan::ICanDriver& can_driver, uavcan::ISystemClock& clock_driver, uavcan::NodeID self_node_id)
|
||||
: otr(poolmgr)
|
||||
, scheduler(can_driver, poolmgr, clock_driver, otr)
|
||||
{
|
||||
poolmgr.addPool(&pool);
|
||||
setNodeID(self_node_id);
|
||||
}
|
||||
|
||||
uavcan::PoolManager<1>& getAllocator() { return poolmgr; }
|
||||
uavcan::Scheduler& getScheduler() { return scheduler; }
|
||||
const uavcan::Scheduler& getScheduler() const { return scheduler; }
|
||||
uavcan::IMarshalBufferProvider& getMarshalBufferProvider() { return buffer_provider; }
|
||||
};
|
||||
|
||||
@ -43,7 +43,10 @@ TEST(Dispatcher, Reception)
|
||||
|
||||
uavcan::OutgoingTransferRegistry<8> out_trans_reg(poolmgr);
|
||||
|
||||
uavcan::Dispatcher dispatcher(driver, poolmgr, clockmock, out_trans_reg, SELF_NODE_ID);
|
||||
uavcan::Dispatcher dispatcher(driver, poolmgr, clockmock, out_trans_reg);
|
||||
ASSERT_TRUE(dispatcher.setNodeID(SELF_NODE_ID)); // Can be set only once
|
||||
ASSERT_FALSE(dispatcher.setNodeID(SELF_NODE_ID));
|
||||
ASSERT_EQ(SELF_NODE_ID, dispatcher.getNodeID());
|
||||
|
||||
DispatcherTransferEmulator emulator(driver, SELF_NODE_ID);
|
||||
|
||||
@ -192,7 +195,9 @@ TEST(Dispatcher, Transmission)
|
||||
|
||||
uavcan::OutgoingTransferRegistry<8> out_trans_reg(poolmgr);
|
||||
|
||||
uavcan::Dispatcher dispatcher(driver, poolmgr, clockmock, out_trans_reg, SELF_NODE_ID);
|
||||
uavcan::Dispatcher dispatcher(driver, poolmgr, clockmock, out_trans_reg);
|
||||
ASSERT_TRUE(dispatcher.setNodeID(SELF_NODE_ID)); // Can be set only once
|
||||
ASSERT_FALSE(dispatcher.setNodeID(SELF_NODE_ID));
|
||||
|
||||
/*
|
||||
* Transmission
|
||||
@ -229,7 +234,9 @@ TEST(Dispatcher, Spin)
|
||||
|
||||
uavcan::OutgoingTransferRegistry<8> out_trans_reg(poolmgr);
|
||||
|
||||
uavcan::Dispatcher dispatcher(driver, poolmgr, clockmock, out_trans_reg, SELF_NODE_ID);
|
||||
uavcan::Dispatcher dispatcher(driver, poolmgr, clockmock, out_trans_reg);
|
||||
ASSERT_TRUE(dispatcher.setNodeID(SELF_NODE_ID)); // Can be set only once
|
||||
ASSERT_FALSE(dispatcher.setNodeID(SELF_NODE_ID));
|
||||
|
||||
clockmock.monotonic_auto_advance = 100;
|
||||
|
||||
|
||||
@ -39,8 +39,10 @@ TEST(TransferSender, Basic)
|
||||
|
||||
static const uavcan::NodeID TX_NODE_ID(64);
|
||||
static const uavcan::NodeID RX_NODE_ID(65);
|
||||
uavcan::Dispatcher dispatcher_tx(driver, poolmgr, clockmock, out_trans_reg, TX_NODE_ID);
|
||||
uavcan::Dispatcher dispatcher_rx(driver, poolmgr, clockmock, out_trans_reg, RX_NODE_ID);
|
||||
uavcan::Dispatcher dispatcher_tx(driver, poolmgr, clockmock, out_trans_reg);
|
||||
uavcan::Dispatcher dispatcher_rx(driver, poolmgr, clockmock, out_trans_reg);
|
||||
ASSERT_TRUE(dispatcher_tx.setNodeID(TX_NODE_ID));
|
||||
ASSERT_TRUE(dispatcher_rx.setNodeID(RX_NODE_ID));
|
||||
|
||||
/*
|
||||
* Test environment
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user