io.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
3  * Copyright (C) 2019 Theodoros Ntakouris <zarkopafilis@gmail.com>
4  */
5 
6 #include <gtest/gtest.h>
7 #include "can.hpp"
8 
9 static bool rxFrameEquals(const uavcan::CanRxFrame& rxframe, const uavcan::CanFrame& frame,
10  uint64_t timestamp_usec, int iface_index)
11 {
12  if (static_cast<const uavcan::CanFrame&>(rxframe) != frame)
13  {
14  std::cout << "Frame mismatch:\n"
15  << " " << rxframe.toString(uavcan::CanFrame::StrAligned) << "\n"
16  << " " << frame.toString(uavcan::CanFrame::StrAligned) << std::endl;
17  }
18  return (static_cast<const uavcan::CanFrame&>(rxframe) == frame) &&
19  (rxframe.ts_mono == uavcan::MonotonicTime::fromUSec(timestamp_usec)) &&
20  (rxframe.iface_index == iface_index);
21 }
22 
23 TEST(CanIOManager, Reception)
24 {
25  // Memory
27 
28  // Platform interface
29  SystemClockMock clockmock;
30  CanDriverMock driver(2, clockmock);
31 
32  // IO Manager
33  uavcan::CanIOManager iomgr(driver, pool, clockmock);
34  ASSERT_EQ(2, iomgr.getNumIfaces());
35 
36  /*
37  * Empty, will time out
38  */
41  EXPECT_EQ(0, iomgr.receive(frame, tsMono(100), flags));
42  EXPECT_EQ(0, flags);
43  EXPECT_EQ(100, clockmock.monotonic);
44  EXPECT_EQ(100, clockmock.utc);
45 
46  /*
47  * Non empty from multiple ifaces
48  */
49  const uavcan::CanFrame frames[2][3] = {
50  { makeCanFrame(1, "a0", EXT), makeCanFrame(99, "a1", EXT), makeCanFrame(803, "a2", STD) },
51  { makeCanFrame(6341, "b0", EXT), makeCanFrame(196, "b1", STD), makeCanFrame(73, "b2", EXT) },
52  };
53 
54  clockmock.advance(10);
55  driver.ifaces.at(0).pushRx(frames[0][0]); // Timestamp 110
56  driver.ifaces.at(1).pushRx(frames[1][0]);
57  clockmock.advance(10);
58  driver.ifaces.at(0).pushRx(frames[0][1]); // Timestamp 120
59  driver.ifaces.at(1).pushRx(frames[1][1]);
60  clockmock.advance(10);
61  driver.ifaces.at(0).pushRx(frames[0][2]); // Timestamp 130
62  driver.ifaces.at(1).pushRx(frames[1][2]);
63  clockmock.advance(10);
64 
65  EXPECT_EQ(1, iomgr.receive(frame, uavcan::MonotonicTime(), flags));
66  EXPECT_TRUE(rxFrameEquals(frame, frames[0][0], 110, 0));
67  EXPECT_EQ(0, flags);
68 
69  EXPECT_EQ(1, iomgr.receive(frame, uavcan::MonotonicTime(), flags));
70  EXPECT_TRUE(rxFrameEquals(frame, frames[0][1], 120, 0));
71  EXPECT_EQ(0, flags);
72 
73  EXPECT_EQ(1, iomgr.receive(frame, uavcan::MonotonicTime(), flags));
74  EXPECT_TRUE(rxFrameEquals(frame, frames[0][2], 130, 0));
75  EXPECT_EQ(0, flags);
76 
77  EXPECT_EQ(1, iomgr.receive(frame, uavcan::MonotonicTime(), flags));
78  EXPECT_TRUE(rxFrameEquals(frame, frames[1][0], 110, 1));
79  EXPECT_EQ(0, flags);
80 
81  EXPECT_EQ(1, iomgr.receive(frame, uavcan::MonotonicTime(), flags));
82  EXPECT_TRUE(rxFrameEquals(frame, frames[1][1], 120, 1));
83  EXPECT_EQ(0, flags);
84 
85  EXPECT_EQ(1, iomgr.receive(frame, uavcan::MonotonicTime(), flags));
86  EXPECT_TRUE(rxFrameEquals(frame, frames[1][2], 130, 1));
87  EXPECT_EQ(0, flags);
88 
89  EXPECT_EQ(0, iomgr.receive(frame, uavcan::MonotonicTime(), flags)); // Will time out
90  EXPECT_EQ(0, flags);
91 
92  /*
93  * Perf counters
94  */
95  driver.select_failure = true;
96  EXPECT_EQ(-uavcan::ErrDriver, iomgr.receive(frame, uavcan::MonotonicTime(), flags));
97 
98  driver.select_failure = false;
99  driver.ifaces.at(1).pushRx(frames[0][0]);
100  driver.ifaces.at(1).rx_failure = true;
101  EXPECT_EQ(-uavcan::ErrDriver, iomgr.receive(frame, uavcan::MonotonicTime(), flags));
102 
103  driver.ifaces.at(0).num_errors = 9000;
104  driver.ifaces.at(1).num_errors = 100500;
105  EXPECT_EQ(9000, iomgr.getIfacePerfCounters(0).errors);
106  EXPECT_EQ(100500, iomgr.getIfacePerfCounters(1).errors);
107 
108  EXPECT_EQ(3, iomgr.getIfacePerfCounters(0).frames_rx);
109  EXPECT_EQ(3, iomgr.getIfacePerfCounters(1).frames_rx);
110 
111  EXPECT_EQ(0, iomgr.getIfacePerfCounters(0).frames_tx);
112  EXPECT_EQ(0, iomgr.getIfacePerfCounters(1).frames_tx);
113 }
114 
115 TEST(CanIOManager, Transmission)
116 {
117  using uavcan::CanIOManager;
118  using uavcan::CanTxQueue;
120 
121  // Memory
123 
124  // Platform interface
125  SystemClockMock clockmock;
126  CanDriverMock driver(2, clockmock);
127 
128  // IO Manager
129  CanIOManager iomgr(driver, pool, clockmock, 9999);
130  ASSERT_EQ(2, iomgr.getNumIfaces());
131 
132  const int ALL_IFACES_MASK = 3;
133 
134  const uavcan::CanFrame frames[] = {
135  makeCanFrame(1, "a0", EXT), makeCanFrame(99, "a1", EXT), makeCanFrame(803, "a2", STD)
136  };
137 
139 
140  /*
141  * Simple transmission
142  */
143  EXPECT_EQ(2, iomgr.send(frames[0], tsMono(100), tsMono(0), ALL_IFACES_MASK, flags));
144  EXPECT_TRUE(driver.ifaces.at(0).matchAndPopTx(frames[0], 100));
145  EXPECT_TRUE(driver.ifaces.at(1).matchAndPopTx(frames[0], 100));
146  EXPECT_TRUE(driver.ifaces.at(0).matchPendingTx(frames[0]));
147  EXPECT_TRUE(driver.ifaces.at(1).matchPendingTx(frames[0]));
148 
149  EXPECT_EQ(1, iomgr.send(frames[1], tsMono(200), tsMono(100), 2, flags)); // To #1 only
150  EXPECT_TRUE(driver.ifaces.at(1).matchAndPopTx(frames[1], 200));
151  EXPECT_TRUE(driver.ifaces.at(0).matchPendingTx(uavcan::CanFrame()));
152  EXPECT_TRUE(driver.ifaces.at(1).matchPendingTx(frames[1]));
153 
154  EXPECT_EQ(0, clockmock.monotonic);
155  EXPECT_EQ(0, clockmock.utc);
156  EXPECT_TRUE(driver.ifaces.at(0).tx.empty());
157  EXPECT_TRUE(driver.ifaces.at(1).tx.empty());
158  EXPECT_EQ(0, iomgr.getIfacePerfCounters(0).errors);
159  EXPECT_EQ(0, iomgr.getIfacePerfCounters(1).errors);
160 
161  /*
162  * TX Queue basics
163  */
164  EXPECT_EQ(0, pool.getNumUsedBlocks());
165 
166  // Sending to both, #0 blocked
167  driver.ifaces.at(0).writeable = false;
168  EXPECT_LT(0, iomgr.send(frames[0], tsMono(201), tsMono(200), ALL_IFACES_MASK, flags));
169  EXPECT_TRUE(driver.ifaces.at(1).matchAndPopTx(frames[0], 201));
170  EXPECT_EQ(200, clockmock.monotonic);
171  EXPECT_EQ(200, clockmock.utc);
172  EXPECT_TRUE(driver.ifaces.at(0).tx.empty());
173  EXPECT_TRUE(driver.ifaces.at(1).tx.empty());
174  EXPECT_EQ(2, pool.getNumUsedBlocks()); // One frame went into TX queue, and will expire soon
175  EXPECT_TRUE(driver.ifaces.at(0).matchPendingTx(frames[0])); // This one will persist
176  EXPECT_TRUE(driver.ifaces.at(1).matchPendingTx(uavcan::CanFrame())); // This will drop off on the second select()
177 
178  // Sending to both, both blocked
179  driver.ifaces.at(1).writeable = false;
180  EXPECT_EQ(0, iomgr.send(frames[1], tsMono(777), tsMono(300), ALL_IFACES_MASK, flags));
181  EXPECT_EQ(6, pool.getNumUsedBlocks()); // Total 3 frames in TX queue now
182  EXPECT_TRUE(driver.ifaces.at(0).matchPendingTx(frames[0])); // Still 0
183  EXPECT_TRUE(driver.ifaces.at(1).matchPendingTx(frames[1])); // 1!!
184 
185  // Sending to #0, both blocked
186  EXPECT_EQ(0, iomgr.send(frames[2], tsMono(888), tsMono(400), 1, flags));
187  EXPECT_EQ(400, clockmock.monotonic);
188  EXPECT_EQ(400, clockmock.utc);
189  EXPECT_TRUE(driver.ifaces.at(0).tx.empty());
190  EXPECT_TRUE(driver.ifaces.at(1).tx.empty());
191  EXPECT_EQ(6, pool.getNumUsedBlocks());
192  //EXPECT_TRUE(driver.ifaces.at(0).matchPendingTx(frames[0]));
193  EXPECT_TRUE(driver.ifaces.at(1).matchPendingTx(frames[1]));
194 
195  // At this time TX queues are containing the following data:
196  // iface 0: frames[0] (EXPIRED), frames[1], frames[2]
197  // iface 1: frames[1]
198 
199  // Sending to #1, both writeable
200  driver.ifaces.at(0).writeable = true;
201  driver.ifaces.at(1).writeable = true;
202  // One frame per each iface will be sent:
203  EXPECT_LT(0, iomgr.send(frames[0], tsMono(999), tsMono(500), 2, flags));
204  EXPECT_TRUE(driver.ifaces.at(0).matchAndPopTx(frames[1], 777)); // Note that frame[0] on iface #0 has expired
205  EXPECT_TRUE(driver.ifaces.at(1).matchAndPopTx(frames[0], 999)); // In different order due to prioritization
206  EXPECT_TRUE(driver.ifaces.at(0).tx.empty());
207  EXPECT_TRUE(driver.ifaces.at(1).tx.empty());
208  EXPECT_TRUE(driver.ifaces.at(0).matchPendingTx(frames[1])); // Overriden when pushed frames[1] (implicit peek under the hood)
209  EXPECT_TRUE(driver.ifaces.at(1).matchPendingTx(frames[0]));
210 
211  // Calling receive() to flush the rest two frames
212  uavcan::CanRxFrame dummy_rx_frame;
213  EXPECT_EQ(0, iomgr.receive(dummy_rx_frame, tsMono(0), flags));
214  EXPECT_TRUE(driver.ifaces.at(0).matchAndPopTx(frames[2], 888));
215  EXPECT_TRUE(driver.ifaces.at(1).matchAndPopTx(frames[1], 777));
216  ASSERT_EQ(0, flags);
217  EXPECT_TRUE(driver.ifaces.at(0).matchPendingTx(frames[2]));
218  EXPECT_TRUE(driver.ifaces.at(1).matchPendingTx(frames[1]));
219 
220  // Final checks
221  EXPECT_TRUE(driver.ifaces.at(0).tx.empty());
222  EXPECT_TRUE(driver.ifaces.at(1).tx.empty());
223  EXPECT_EQ(0, pool.getNumUsedBlocks()); // Make sure the memory was properly released
224  EXPECT_EQ(0, iomgr.getIfacePerfCounters(0).errors); // Expired frame[0] removed automagically on peek
225  EXPECT_EQ(0, iomgr.getIfacePerfCounters(1).errors);
226 
227  /*
228  * TX Queue updates from receive() call
229  */
230  driver.ifaces.at(0).writeable = false;
231  driver.ifaces.at(1).writeable = false;
232 
233  // Sending 5 frames, one will be rejected
234  EXPECT_EQ(0, iomgr.send(frames[2], tsMono(2222), tsMono(1000), ALL_IFACES_MASK, flags));
235  EXPECT_EQ(0, iomgr.send(frames[0], tsMono(3333), tsMono(1100), 2, flags));
236  // One frame kicked here:
237  EXPECT_EQ(0, iomgr.send(frames[1], tsMono(4444), tsMono(1200), ALL_IFACES_MASK, flags));
238 
239  EXPECT_TRUE(driver.ifaces.at(0).matchPendingTx(frames[1]));
240  EXPECT_TRUE(driver.ifaces.at(1).matchPendingTx(frames[0]));
241 
242  // State checks
243  EXPECT_EQ(10, pool.getNumUsedBlocks()); // TX queue is full
244  EXPECT_EQ(1200, clockmock.monotonic);
245  EXPECT_EQ(1200, clockmock.utc);
246  EXPECT_TRUE(driver.ifaces.at(0).tx.empty());
247  EXPECT_TRUE(driver.ifaces.at(1).tx.empty());
248 
249  // Preparing the driver mock for receive() call
250  driver.ifaces.at(0).writeable = true;
251  driver.ifaces.at(1).writeable = true;
252  const uavcan::CanFrame rx_frames[] = { makeCanFrame(123, "rx0", STD), makeCanFrame(321, "rx1", EXT) };
253  driver.ifaces.at(0).pushRx(rx_frames[0]);
254  driver.ifaces.at(1).pushRx(rx_frames[1]);
255 
256  // This shall transmit _some_ frames now, at least one per iface (exact number can be changed - it will be OK)
257  uavcan::CanRxFrame rx_frame;
258  EXPECT_EQ(1, iomgr.receive(rx_frame, tsMono(0), flags)); // Non-blocking
259  EXPECT_TRUE(rxFrameEquals(rx_frame, rx_frames[0], 1200, 0));
260  EXPECT_TRUE(driver.ifaces.at(0).matchAndPopTx(frames[1], 4444));
261  EXPECT_TRUE(driver.ifaces.at(1).matchAndPopTx(frames[0], 3333));
262  ASSERT_EQ(0, flags);
263  EXPECT_TRUE(driver.ifaces.at(0).matchPendingTx(frames[1]));
264  EXPECT_TRUE(driver.ifaces.at(1).matchPendingTx(frames[0]));
265 
266  EXPECT_EQ(1, iomgr.receive(rx_frame, tsMono(0), flags));
267  EXPECT_TRUE(rxFrameEquals(rx_frame, rx_frames[1], 1200, 1));
268  EXPECT_TRUE(driver.ifaces.at(0).matchAndPopTx(frames[2], 2222));
269  EXPECT_TRUE(driver.ifaces.at(1).matchAndPopTx(frames[1], 4444)); // Volatility on QoS no longer affects priority
270  ASSERT_EQ(0, flags);
271  EXPECT_TRUE(driver.ifaces.at(0).matchPendingTx(frames[2]));
272  EXPECT_TRUE(driver.ifaces.at(1).matchPendingTx(frames[1]));
273 
274  // State checks
275  EXPECT_EQ(2, pool.getNumUsedBlocks()); // TX queue is not empty now, contains the pending frames[2] because of QoS changes stated above
276  EXPECT_EQ(1200, clockmock.monotonic);
277  EXPECT_EQ(1200, clockmock.utc);
278  EXPECT_TRUE(driver.ifaces.at(0).tx.empty());
279  EXPECT_TRUE(driver.ifaces.at(1).tx.empty());
280  EXPECT_EQ(0, iomgr.getIfacePerfCounters(0).errors);
281  EXPECT_EQ(0, iomgr.getIfacePerfCounters(1).errors);
282 
283  /*
284  * Error handling
285  */
286  // Select failure
287  driver.select_failure = true;
288  EXPECT_EQ(-uavcan::ErrDriver, iomgr.receive(rx_frame, tsMono(2000), flags));
289  EXPECT_EQ(-uavcan::ErrDriver,
290  iomgr.send(frames[0], tsMono(2100), tsMono(2000), ALL_IFACES_MASK, flags));
291  EXPECT_EQ(1200, clockmock.monotonic);
292  EXPECT_EQ(1200, clockmock.utc);
293  ASSERT_EQ(0, flags);
294  EXPECT_TRUE(driver.ifaces.at(0).matchPendingTx(frames[0]));
295  EXPECT_TRUE(driver.ifaces.at(1).matchPendingTx(frames[0]));
296 
297  // Transmission failure
298  driver.select_failure = false;
299  driver.ifaces.at(0).writeable = true;
300  driver.ifaces.at(1).writeable = true;
301  driver.ifaces.at(0).tx_failure = true;
302  driver.ifaces.at(1).tx_failure = true;
303  // Non-blocking - return < 0
304  EXPECT_GE(0, iomgr.send(frames[0], tsMono(2200), tsMono(0), ALL_IFACES_MASK, flags));
305  EXPECT_TRUE(driver.ifaces.at(0).matchPendingTx(frames[0]));
306  EXPECT_TRUE(driver.ifaces.at(1).matchPendingTx(frames[0]));
307 
308  ASSERT_EQ(6, pool.getNumUsedBlocks()); // Untransmitted frames will be buffered
309 
310  // Failure removed - transmission shall proceed
311  driver.ifaces.at(0).tx_failure = false;
312  driver.ifaces.at(1).tx_failure = false;
313  EXPECT_EQ(0, iomgr.receive(rx_frame, tsMono(2500), flags));
314  EXPECT_TRUE(driver.ifaces.at(0).matchAndPopTx(frames[0], 2200));
315  EXPECT_TRUE(driver.ifaces.at(1).matchAndPopTx(frames[0], 2200));
316  EXPECT_EQ(0, pool.getNumUsedBlocks()); // All transmitted
317  ASSERT_EQ(0, flags);
318  EXPECT_TRUE(driver.ifaces.at(0).matchPendingTx(uavcan::CanFrame())); // Last call will be receive-only,
319  EXPECT_TRUE(driver.ifaces.at(1).matchPendingTx(uavcan::CanFrame())); // hence empty TX
320 
321  /*
322  * Perf counters
323  */
324  EXPECT_EQ(1, iomgr.getIfacePerfCounters(0).frames_rx);
325  EXPECT_EQ(1, iomgr.getIfacePerfCounters(1).frames_rx);
326 
327  EXPECT_EQ(6, iomgr.getIfacePerfCounters(0).frames_tx);
328  EXPECT_EQ(9, iomgr.getIfacePerfCounters(1).frames_tx);
329 }
330 
331 TEST(CanIOManager, Loopback)
332 {
333  using uavcan::CanIOManager;
334  using uavcan::CanTxQueue;
336  using uavcan::CanFrame;
337  using uavcan::CanRxFrame;
338 
339  // Memory
340  uavcan::PoolAllocator<sizeof(CanTxQueueEntry) * 4, sizeof(CanTxQueueEntry)> pool;
341 
342  // Platform interface
343  SystemClockMock clockmock;
344  CanDriverMock driver(2, clockmock);
345 
346  // IO Manager
347  CanIOManager iomgr(driver, pool, clockmock);
348  ASSERT_EQ(2, iomgr.getNumIfaces());
349 
350  CanFrame fr1;
351  fr1.id = 123 | CanFrame::FlagEFF;
352 
353  CanFrame fr2;
354  fr2.id = 456 | CanFrame::FlagEFF;
355 
356  CanRxFrame rfr1;
357  CanRxFrame rfr2;
358 
359  uavcan::CanIOFlags flags = 0;
360  ASSERT_EQ(1, iomgr.send(fr1, tsMono(1000), tsMono(0), 1, uavcan::CanIOFlagLoopback));
361  ASSERT_LE(0, iomgr.receive(rfr1, tsMono(100), flags));
362  ASSERT_EQ(uavcan::CanIOFlagLoopback, flags);
363  ASSERT_TRUE(rfr1 == fr1);
364 
365  flags = 0;
366  ASSERT_EQ(1, iomgr.send(fr1, tsMono(1000), tsMono(0), 1, uavcan::CanIOFlagLoopback));
367  ASSERT_EQ(1, iomgr.send(fr2, tsMono(1000), tsMono(0), 1, uavcan::CanIOFlagLoopback));
368  ASSERT_LE(0, iomgr.receive(rfr1, tsMono(100), flags));
369  ASSERT_EQ(uavcan::CanIOFlagLoopback, flags);
370  ASSERT_LE(0, iomgr.receive(rfr2, tsMono(100), flags));
371  ASSERT_EQ(uavcan::CanIOFlagLoopback, flags);
372  ASSERT_TRUE(rfr1 == fr1);
373  ASSERT_TRUE(rfr2 == fr2);
374 
375  /*
376  * Perf counters
377  * Loopback frames are not registered as RX
378  */
379  EXPECT_EQ(0, iomgr.getIfacePerfCounters(0).frames_rx);
380  EXPECT_EQ(0, iomgr.getIfacePerfCounters(1).frames_rx);
381 
382  EXPECT_EQ(3, iomgr.getIfacePerfCounters(0).frames_tx);
383  EXPECT_EQ(0, iomgr.getIfacePerfCounters(1).frames_tx);
384 }
385 
386 TEST(CanIOManager, Size)
387 {
388  std::cout << sizeof(uavcan::CanIOManager) << std::endl;
389 }
uavcan::CanIfacePerfCounters::frames_tx
uint64_t frames_tx
Definition: can_io.hpp:117
uavcan::uint64_t
std::uint64_t uint64_t
Definition: std.hpp:27
SystemClockMock::advance
void advance(uint64_t usec) const
Definition: libuavcan/libuavcan/test/clock.hpp:28
rxFrameEquals
static bool rxFrameEquals(const uavcan::CanRxFrame &rxframe, const uavcan::CanFrame &frame, uint64_t timestamp_usec, int iface_index)
Definition: io.cpp:9
makeCanFrame
uavcan::CanFrame makeCanFrame(uint32_t id, const std::string &str_data, FrameType type)
Definition: libuavcan/libuavcan/test/transport/can/can.hpp:278
uavcan::CanFrame
Definition: libuavcan/libuavcan/include/uavcan/driver/can.hpp:24
SystemClockMock::monotonic
uint64_t monotonic
Definition: libuavcan/libuavcan/test/clock.hpp:15
uavcan::CanIOFlagLoopback
static const CanIOFlags CanIOFlagLoopback
Definition: libuavcan/libuavcan/include/uavcan/driver/can.hpp:141
uavcan::CanRxFrame
Definition: can_io.hpp:25
uavcan::CanIOManager::getIfacePerfCounters
CanIfacePerfCounters getIfacePerfCounters(uint8_t iface_index) const
Definition: uc_can_io.cpp:282
uavcan::PoolAllocator
Definition: dynamic_memory.hpp:51
uavcan::TimeBase< MonotonicTime, MonotonicDuration >::fromUSec
static MonotonicTime fromUSec(uint64_t us)
Definition: time.hpp:112
CanDriverMock::ifaces
std::vector< CanIfaceMock > ifaces
Definition: libuavcan/libuavcan/test/transport/can/can.hpp:193
uavcan::CanIOManager::getNumIfaces
uint8_t getNumIfaces() const
Definition: can_io.hpp:158
uavcan::CanIOManager
Definition: can_io.hpp:128
CanDriverMock::select_failure
bool select_failure
Definition: libuavcan/libuavcan/test/transport/can/can.hpp:195
uavcan::CanIfacePerfCounters::frames_rx
uint64_t frames_rx
Definition: can_io.hpp:118
TEST
TEST(CanIOManager, Reception)
Definition: io.cpp:23
can.hpp
STD
@ STD
Definition: libuavcan/libuavcan/test/transport/can/can.hpp:277
uavcan::CanRxFrame::iface_index
uint8_t iface_index
Definition: can_io.hpp:29
uavcan::CanIOManager::receive
int receive(CanRxFrame &out_frame, MonotonicTime blocking_deadline, CanIOFlags &out_flags)
Definition: uc_can_io.cpp:412
frame
uavcan::CanFrame frame
Definition: can.cpp:78
uavcan::CanTxQueueEntry
Definition: can_io.hpp:40
CanDriverMock
Definition: libuavcan/libuavcan/test/transport/can/can.hpp:190
tsMono
uavcan::MonotonicTime tsMono(uint64_t usec)
Definition: libuavcan/libuavcan/test/clock.hpp:97
uavcan::PoolAllocator::getNumUsedBlocks
uint16_t getNumUsedBlocks() const
Definition: dynamic_memory.hpp:85
uavcan::CanIfacePerfCounters::errors
uint64_t errors
Definition: can_io.hpp:119
uavcan::CanIOFlags
uint16_t CanIOFlags
Definition: libuavcan/libuavcan/include/uavcan/driver/can.hpp:140
uavcan::CanTxQueue
Definition: can_io.hpp:78
SystemClockMock
Definition: libuavcan/libuavcan/test/clock.hpp:12
uavcan::MonotonicTime
Definition: time.hpp:184
SystemClockMock::utc
uint64_t utc
Definition: libuavcan/libuavcan/test/clock.hpp:16
EXT
@ EXT
Definition: libuavcan/libuavcan/test/transport/can/can.hpp:277
uavcan::CanRxFrame::ts_mono
MonotonicTime ts_mono
Definition: can_io.hpp:27


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