From 0309d13eae87b5d9c942c99e5da6a75fc158278b Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Tue, 1 Apr 2014 02:29:57 +0400 Subject: [PATCH] Linux SOcketCAN driver: strict ordering of received CAN frames; added debug header for tests --- .../linux/include/uavcan_linux/socketcan.hpp | 7 ++--- libuavcan_drivers/linux/test/debug.hpp | 14 ++++++++++ libuavcan_drivers/linux/test/test_socket.cpp | 28 ++++++++----------- 3 files changed, 27 insertions(+), 22 deletions(-) create mode 100644 libuavcan_drivers/linux/test/debug.hpp diff --git a/libuavcan_drivers/linux/include/uavcan_linux/socketcan.hpp b/libuavcan_drivers/linux/include/uavcan_linux/socketcan.hpp index ea1d52acd0..e99bb35e0f 100644 --- a/libuavcan_drivers/linux/include/uavcan_linux/socketcan.hpp +++ b/libuavcan_drivers/linux/include/uavcan_linux/socketcan.hpp @@ -113,8 +113,6 @@ class SocketCanIface : public uavcan::ICanIface RxItem() : flags(0) { } - - bool operator<(const RxItem& rhs) const { return frame.priorityLowerThan(rhs.frame); } }; const SystemClock clock_; @@ -126,7 +124,7 @@ class SocketCanIface : public uavcan::ICanIface std::map errors_; std::priority_queue tx_queue_; // TODO: Use pool allocator - std::priority_queue rx_queue_; // TODO: Use pool allocator + std::queue rx_queue_; // TODO: Use pool allocator std::unordered_multiset pending_loopback_ids_; // TODO: Use pool allocator void registerError(SocketCanError e) { errors_[e]++; } @@ -340,14 +338,13 @@ public: } } { - const RxItem& rx = rx_queue_.top(); + const RxItem& rx = rx_queue_.front(); out_frame = rx.frame; out_ts_monotonic = rx.ts_mono; out_ts_utc = rx.ts_utc; out_flags = rx.flags; } rx_queue_.pop(); - assert(rx_queue_.empty() ? true : !out_frame.priorityLowerThan(rx_queue_.top().frame)); // Order check return 1; } diff --git a/libuavcan_drivers/linux/test/debug.hpp b/libuavcan_drivers/linux/test/debug.hpp new file mode 100644 index 0000000000..77ee8bf4b9 --- /dev/null +++ b/libuavcan_drivers/linux/test/debug.hpp @@ -0,0 +1,14 @@ +/* + * Copyright (C) 2014 Pavel Kirienko + */ + +#pragma once + +#include + +#ifndef STRINGIZE +# define STRINGIZE2(x) #x +# define STRINGIZE(x) STRINGIZE2(x) +#endif +#define ENFORCE(x) if (!(x)) { throw std::runtime_error(__FILE__ ":" STRINGIZE(__LINE__) ": " #x); } + diff --git a/libuavcan_drivers/linux/test/test_socket.cpp b/libuavcan_drivers/linux/test/test_socket.cpp index aa7dc23f4c..c0af15b181 100644 --- a/libuavcan_drivers/linux/test/test_socket.cpp +++ b/libuavcan_drivers/linux/test/test_socket.cpp @@ -6,12 +6,7 @@ #include #include #include - -#ifndef STRINGIZE -# define STRINGIZE2(x) #x -# define STRINGIZE(x) STRINGIZE2(x) -#endif -#define ENFORCE(x) if (!(x)) { throw std::runtime_error(__FILE__ ":" STRINGIZE(__LINE__) ": " #x); } +#include "debug.hpp" static uavcan::CanFrame makeFrame(std::uint32_t id, const std::string& data) { @@ -56,7 +51,7 @@ static void testSocketRxTx(const std::string& iface_name) */ ENFORCE(1 == if2.send(makeFrame(321, "if2-1"), tsMonoOffsetMs(100), 0)); ENFORCE(1 == if2.send(makeFrame(654, "if2-2"), tsMonoOffsetMs(100), uavcan::CanIOFlagLoopback)); - ENFORCE(1 == if2.send(makeFrame(1, "discard"), tsMonoOffsetMs(0), uavcan::CanIOFlagLoopback)); // Will timeout + ENFORCE(1 == if2.send(makeFrame(1, "discard"), tsMonoOffsetMs(-1), uavcan::CanIOFlagLoopback)); // Will timeout if2.poll(true, true); if2.poll(true, true); ENFORCE(1 == if2.getErrorCount()); // One timed out @@ -80,16 +75,16 @@ static void testSocketRxTx(const std::string& iface_name) * Read first */ ENFORCE(1 == if1.receive(frame, ts_mono, ts_utc, flags)); - ENFORCE(frame == makeFrame(321, "if2-1")); - ENFORCE(flags == 0); - ENFORCE(!ts_mono.isZero()); - ENFORCE(!ts_utc.isZero()); + ENFORCE(frame == makeFrame(456, "if1-2")); + ENFORCE(flags == uavcan::CanIOFlagLoopback); ENFORCE((clock.getMonotonic() - ts_mono).getAbs().toMSec() < 10); ENFORCE((clock.getUtc() - ts_utc).getAbs().toMSec() < 10); ENFORCE(1 == if1.receive(frame, ts_mono, ts_utc, flags)); - ENFORCE(frame == makeFrame(456, "if1-2")); - ENFORCE(flags == uavcan::CanIOFlagLoopback); + ENFORCE(frame == makeFrame(321, "if2-1")); + ENFORCE(flags == 0); + ENFORCE(!ts_mono.isZero()); + ENFORCE(!ts_utc.isZero()); ENFORCE((clock.getMonotonic() - ts_mono).getAbs().toMSec() < 10); ENFORCE((clock.getUtc() - ts_utc).getAbs().toMSec() < 10); @@ -180,7 +175,6 @@ static void testSocketFilters(const std::string& iface_name) /* * Checking RX on 2 - * Notice how the frames were reordered according to CAN bus arbitration rules */ uavcan::CanFrame frame; uavcan::MonotonicTime ts_mono; @@ -188,8 +182,7 @@ static void testSocketFilters(const std::string& iface_name) uavcan::CanIOFlags flags = 0; ENFORCE(1 == if2.receive(frame, ts_mono, ts_utc, flags)); - ENFORCE(frame == makeFrame(0, "6")); - ENFORCE(flags == 0); + ENFORCE(frame == makeFrame(123, "1")); ENFORCE(1 == if2.receive(frame, ts_mono, ts_utc, flags)); ENFORCE(frame == makeFrame(123 | EFF, "2")); @@ -198,7 +191,8 @@ static void testSocketFilters(const std::string& iface_name) ENFORCE(frame == makeFrame(456789 | EFF, "5")); ENFORCE(1 == if2.receive(frame, ts_mono, ts_utc, flags)); - ENFORCE(frame == makeFrame(123, "1")); + ENFORCE(frame == makeFrame(0, "6")); + ENFORCE(flags == 0); ENFORCE(!if2.hasReadyRx()); }