global_time_sync_master.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
3  */
4 
5 #ifndef UAVCAN_PROTOCOL_GLOBAL_TIME_SYNC_MASTER_HPP_INCLUDED
6 #define UAVCAN_PROTOCOL_GLOBAL_TIME_SYNC_MASTER_HPP_INCLUDED
7 
13 #include <uavcan/protocol/GlobalTimeSync.hpp>
14 #include <uavcan/debug.hpp>
15 #include <cstdlib>
16 #include <cassert>
17 
18 namespace uavcan
19 {
33 {
35  {
40 
41  public:
42  IfaceMaster(INode& node, uint8_t iface_index)
43  : pub_(node)
44  , iface_index_(iface_index)
45  {
46  UAVCAN_ASSERT(iface_index < MaxCanIfaces);
47  }
48 
49  int init(TransferPriority priority)
50  {
51  const int res = pub_.init(priority);
52  if (res >= 0)
53  {
54  pub_.getTransferSender().setIfaceMask(uint8_t(1 << iface_index_));
56  }
57  return res;
58  }
59 
61  {
62  if (ts.isZero())
63  {
64  UAVCAN_ASSERT(0);
65  pub_.getNode().registerInternalFailure("GlobalTimeSyncMaster zero TX ts");
66  return;
67  }
68  if (!prev_tx_utc_.isZero())
69  {
70  prev_tx_utc_ = UtcTime(); // Reset again, because there's something broken in the driver and we don't trust it
71  pub_.getNode().registerInternalFailure("GlobalTimeSyncMaster pub conflict");
72  return;
73  }
74  prev_tx_utc_ = ts;
75  }
76 
77  int publish(TransferID tid, MonotonicTime current_time)
78  {
80  UAVCAN_ASSERT(pub_.getTransferSender().getIfaceMask() == (1 << iface_index_));
81 
82  const MonotonicDuration since_prev_pub = current_time - iface_prev_pub_mono_;
83  iface_prev_pub_mono_ = current_time;
84  UAVCAN_ASSERT(since_prev_pub.isPositive());
85  const bool long_period = since_prev_pub.toMSec() >= protocol::GlobalTimeSync::MAX_BROADCASTING_PERIOD_MS;
86 
87  protocol::GlobalTimeSync msg;
88  msg.previous_transmission_timestamp_usec = long_period ? 0 : prev_tx_utc_.toUSec();
89  prev_tx_utc_ = UtcTime();
90 
91  UAVCAN_TRACE("GlobalTimeSyncMaster", "Publishing %llu iface=%i tid=%i",
92  static_cast<unsigned long long>(msg.previous_transmission_timestamp_usec),
93  int(iface_index_), int(tid.get()));
94  return pub_.broadcast(msg, tid);
95  }
96  };
97 
103 
104  virtual void handleLoopbackFrame(const RxFrame& frame)
105  {
106  const uint8_t iface = frame.getIfaceIndex();
107  if (initialized_ && iface < MaxCanIfaces)
108  {
109  if (frame.getDataTypeID() == dtid_ &&
110  frame.getTransferType() == TransferTypeMessageBroadcast &&
111  frame.isStartOfTransfer() && frame.isEndOfTransfer() &&
112  frame.getSrcNodeID() == node_.getNodeID())
113  {
114  iface_masters_[iface]->setTxTimestamp(frame.getUtcTimestamp());
115  }
116  }
117  else
118  {
119  UAVCAN_ASSERT(0);
120  }
121  }
122 
124  {
125  const MonotonicDuration max_transfer_interval =
126  MonotonicDuration::fromMSec(protocol::GlobalTimeSync::MAX_BROADCASTING_PERIOD_MS);
127 
129  const MonotonicTime otr_deadline = node_.getMonotonicTime() + max_transfer_interval;
130  TransferID* const tid_ptr =
131  node_.getDispatcher().getOutgoingTransferRegistry().accessOrCreate(otr_key, otr_deadline);
132  if (tid_ptr == UAVCAN_NULLPTR)
133  {
134  return -ErrMemory;
135  }
136 
137  tid = *tid_ptr;
138  tid_ptr->increment();
139  return 0;
140  }
141 
142 public:
144  : LoopbackFrameListenerBase(node.getDispatcher())
145  , node_(node)
146  , initialized_(false)
147  { }
148 
155  {
156  if (initialized_)
157  {
158  return 0;
159  }
160 
161  // Data type ID
162  const DataTypeDescriptor* const desc =
163  GlobalDataTypeRegistry::instance().find(DataTypeKindMessage, protocol::GlobalTimeSync::getDataTypeFullName());
164  if (desc == UAVCAN_NULLPTR)
165  {
166  return -ErrUnknownDataType;
167  }
168  dtid_ = desc->getID();
169 
170  // Iface master array
171  int res = -ErrLogic;
172  for (uint8_t i = 0; i < MaxCanIfaces; i++)
173  {
174  if (!iface_masters_[i].isConstructed())
175  {
176  iface_masters_[i].construct<INode&, uint8_t>(node_, i);
177  }
178  res = iface_masters_[i]->init(priority);
179  if (res < 0)
180  {
181  break;
182  }
183  }
184 
185  // Loopback listener
186  initialized_ = res >= 0;
187  if (initialized_)
188  {
190  }
191  return res;
192  }
193 
197  bool isInitialized() const { return initialized_; }
198 
210  int publish()
211  {
212  if (!initialized_)
213  {
214  const int res = init();
215  if (res < 0)
216  {
217  return res;
218  }
219  }
220 
221  /*
222  * Enforce max frequency
223  */
224  const MonotonicTime current_time = node_.getMonotonicTime();
225  {
226  const MonotonicDuration since_prev_pub = current_time - prev_pub_mono_;
227  UAVCAN_ASSERT(since_prev_pub.isPositive());
228  if (since_prev_pub.toMSec() < protocol::GlobalTimeSync::MIN_BROADCASTING_PERIOD_MS)
229  {
230  UAVCAN_TRACE("GlobalTimeSyncMaster", "Publication skipped");
231  return 0;
232  }
233  prev_pub_mono_ = current_time;
234  }
235 
236  /*
237  * Obtain common Transfer ID for all masters
238  */
239  TransferID tid;
240  {
241  const int tid_res = getNextTransferID(tid);
242  if (tid_res < 0)
243  {
244  return tid_res;
245  }
246  }
247 
248  for (uint8_t i = 0; i < node_.getDispatcher().getCanIOManager().getNumIfaces(); i++)
249  {
250  const int res = iface_masters_[i]->publish(tid, current_time);
251  if (res < 0)
252  {
253  return res;
254  }
255  }
256  return 0;
257  }
258 };
259 
260 }
261 
262 #endif // UAVCAN_PROTOCOL_GLOBAL_TIME_SYNC_MASTER_HPP_INCLUDED
uavcan::LoopbackFrameListenerBase::startListening
void startListening()
Definition: uc_dispatcher.cpp:15
subscriber.hpp
UAVCAN_NULLPTR
#define UAVCAN_NULLPTR
Definition: libuavcan/libuavcan/include/uavcan/build_config.hpp:51
uavcan::INode::getMonotonicTime
MonotonicTime getMonotonicTime() const
Definition: abstract_node.hpp:32
uavcan::TransferSender::setCanIOFlags
void setCanIOFlags(CanIOFlags flags)
Definition: transfer_sender.hpp:69
uavcan::GlobalTimeSyncMaster::getNextTransferID
int getNextTransferID(TransferID &tid)
Definition: global_time_sync_master.hpp:123
uavcan::DurationBase::toMSec
int64_t toMSec() const
Definition: time.hpp:44
uavcan::GlobalTimeSyncMaster::IfaceMaster::prev_tx_utc_
UtcTime prev_tx_utc_
Definition: global_time_sync_master.hpp:38
uavcan::GlobalTimeSyncMaster::IfaceMaster::pub_
Publisher< protocol::GlobalTimeSync > pub_
Definition: global_time_sync_master.hpp:36
debug.hpp
uavcan::UtcTime
Implicitly convertible to/from uavcan.Timestamp.
Definition: time.hpp:191
uavcan::Publisher< protocol::GlobalTimeSync >
uavcan::GenericPublisherBase::getNode
INode & getNode() const
Definition: generic_publisher.hpp:76
uavcan::GlobalTimeSyncMaster::IfaceMaster::init
int init(TransferPriority priority)
Definition: global_time_sync_master.hpp:49
uavcan::OutgoingTransferRegistryKey
Definition: outgoing_transfer_registry.hpp:19
uavcan::GlobalTimeSyncMaster::GlobalTimeSyncMaster
GlobalTimeSyncMaster(INode &node)
Definition: global_time_sync_master.hpp:143
uavcan::DurationBase< MonotonicDuration >::fromMSec
static MonotonicDuration fromMSec(int64_t ms)
Definition: time.hpp:41
uavcan::INode::getDispatcher
Dispatcher & getDispatcher()
Definition: abstract_node.hpp:28
uavcan::GlobalTimeSyncMaster::IfaceMaster::IfaceMaster
IfaceMaster(INode &node, uint8_t iface_index)
Definition: global_time_sync_master.hpp:42
uavcan::CanIOFlagLoopback
static const CanIOFlags CanIOFlagLoopback
Definition: libuavcan/libuavcan/include/uavcan/driver/can.hpp:141
uavcan::TransferSender::setIfaceMask
void setIfaceMask(uint8_t iface_mask)
Definition: transfer_sender.hpp:72
UAVCAN_TRACE
#define UAVCAN_TRACE(...)
Definition: libuavcan/libuavcan/include/uavcan/debug.hpp:31
uavcan::GlobalTimeSyncMaster::IfaceMaster::publish
int publish(TransferID tid, MonotonicTime current_time)
Definition: global_time_sync_master.hpp:77
uavcan::OutgoingTransferRegistry::accessOrCreate
TransferID * accessOrCreate(const OutgoingTransferRegistryKey &key, MonotonicTime new_deadline)
Definition: uc_outgoing_transfer_registry.cpp:27
uavcan::MonotonicDuration
Definition: time.hpp:182
uavcan::MaxCanIfaces
@ MaxCanIfaces
Definition: libuavcan/libuavcan/include/uavcan/driver/can.hpp:19
publisher.hpp
uavcan::TransferID::get
uint8_t get() const
Definition: transfer.hpp:99
uavcan::TransferSender::getCanIOFlags
CanIOFlags getCanIOFlags() const
Definition: transfer_sender.hpp:68
uavcan::GlobalDataTypeRegistry::find
const DataTypeDescriptor * find(const char *name) const
Definition: uc_global_data_type_registry.cpp:144
uavcan::TransferID
Definition: transfer.hpp:71
uavcan::LoopbackFrameListenerBase
Definition: dispatcher.hpp:27
uavcan::INode::registerInternalFailure
virtual void registerInternalFailure(const char *msg)=0
uavcan_kinetis::ErrLogic
static const uavcan::int16_t ErrLogic
Internal logic error.
Definition: platform_specific_components/kinetis/libuavcan/driver/include/uavcan_kinetis/can.hpp:22
uavcan::uint8_t
std::uint8_t uint8_t
Definition: std.hpp:24
uavcan::DataTypeID
Definition: data_type.hpp:47
uavcan::DataTypeDescriptor
Definition: data_type.hpp:130
uavcan::GlobalTimeSyncMaster::node_
INode & node_
Definition: global_time_sync_master.hpp:98
uavcan::TransferTypeMessageBroadcast
@ TransferTypeMessageBroadcast
Definition: transfer.hpp:22
uavcan::RxFrame
Definition: frame.hpp:104
lazy_constructor.hpp
uavcan::GlobalTimeSyncMaster::IfaceMaster::iface_index_
const uint8_t iface_index_
Definition: global_time_sync_master.hpp:39
uavcan::GlobalTimeSyncMaster::init
int init(const TransferPriority priority=TransferPriority::OneLowerThanHighest)
Definition: global_time_sync_master.hpp:154
uavcan::GenericPublisherBase::getTransferSender
TransferSender & getTransferSender()
Definition: generic_publisher.hpp:51
uavcan::DurationBase::isPositive
bool isPositive() const
Definition: time.hpp:48
UAVCAN_EXPORT
#define UAVCAN_EXPORT
Definition: libuavcan/libuavcan/include/uavcan/build_config.hpp:108
uavcan::TimeBase::isZero
bool isZero() const
Definition: time.hpp:123
uavcan::NodeID::Broadcast
static const NodeID Broadcast
Definition: transfer.hpp:122
method_binder.hpp
uavcan::INode
Definition: abstract_node.hpp:19
uavcan::LazyConstructor::construct
void construct()
Definition: lazy_constructor.hpp:110
uavcan::TransferPriority
Definition: transfer.hpp:28
uavcan::GlobalTimeSyncMaster
Definition: global_time_sync_master.hpp:32
build_config.hpp
uavcan::GlobalTimeSyncMaster::IfaceMaster::iface_prev_pub_mono_
MonotonicTime iface_prev_pub_mono_
Definition: global_time_sync_master.hpp:37
uavcan::TransferPriority::OneLowerThanHighest
static const TransferPriority OneLowerThanHighest
Definition: transfer.hpp:41
frame
uavcan::CanFrame frame
Definition: can.cpp:78
uavcan::INode::getNodeID
NodeID getNodeID() const
Definition: abstract_node.hpp:39
uavcan::GenericPublisher::init
int init()
Definition: generic_publisher.hpp:118
uavcan::TransferSender::getIfaceMask
uint8_t getIfaceMask() const
Definition: transfer_sender.hpp:71
uavcan::Dispatcher::getOutgoingTransferRegistry
OutgoingTransferRegistry & getOutgoingTransferRegistry()
Definition: dispatcher.hpp:204
uavcan::GlobalTimeSyncMaster::prev_pub_mono_
MonotonicTime prev_pub_mono_
Definition: global_time_sync_master.hpp:100
uavcan::GlobalTimeSyncMaster::dtid_
DataTypeID dtid_
Definition: global_time_sync_master.hpp:101
uavcan::DataTypeDescriptor::getID
DataTypeID getID() const
Definition: data_type.hpp:159
uavcan_kinetis::clock::init
void init()
Definition: clock.cpp:43
uavcan::Publisher::broadcast
int broadcast(const DataType &message)
Definition: publisher.hpp:52
uavcan::GlobalTimeSyncMaster::IfaceMaster
Definition: global_time_sync_master.hpp:34
uavcan::GlobalTimeSyncMaster::isInitialized
bool isInitialized() const
Definition: global_time_sync_master.hpp:197
pyuavcan_v0.introspect.node
node
Definition: introspect.py:398
uavcan::MonotonicTime
Definition: time.hpp:184
uavcan::GlobalDataTypeRegistry::instance
static GlobalDataTypeRegistry & instance()
Definition: uc_global_data_type_registry.cpp:128
uavcan::GlobalTimeSyncMaster::initialized_
bool initialized_
Definition: global_time_sync_master.hpp:102
uavcan
Definition: libuavcan/libuavcan/include/uavcan/build_config.hpp:204
uavcan::DataTypeKindMessage
@ DataTypeKindMessage
Definition: data_type.hpp:22
uavcan::GlobalTimeSyncMaster::handleLoopbackFrame
virtual void handleLoopbackFrame(const RxFrame &frame)
Definition: global_time_sync_master.hpp:104
uavcan::GlobalTimeSyncMaster::IfaceMaster::setTxTimestamp
void setTxTimestamp(UtcTime ts)
Definition: global_time_sync_master.hpp:60
uavcan::TransferID::increment
void increment()
Definition: transfer.hpp:94
uavcan::GlobalTimeSyncMaster::publish
int publish()
Definition: global_time_sync_master.hpp:210
uavcan::LazyConstructor
Definition: lazy_constructor.hpp:27
uavcan::TimeBase::toUSec
uint64_t toUSec() const
Definition: time.hpp:120
UAVCAN_ASSERT
#define UAVCAN_ASSERT(x)
Definition: libuavcan/libuavcan/include/uavcan/build_config.hpp:184


uavcan_communicator
Author(s):
autogenerated on Fri Dec 13 2024 03:10:02