mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-04-28 16:44:06 +08:00
TransferID class
This commit is contained in:
parent
5252972d3e
commit
4bf2b2e81a
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014 <pavel.kirienko@gmail.com>
|
||||
* Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@ -19,21 +19,60 @@ enum TransferType
|
||||
MESSAGE_UNICAST = 3
|
||||
};
|
||||
|
||||
|
||||
class TransferID
|
||||
{
|
||||
uint_fast8_t value_;
|
||||
|
||||
public:
|
||||
enum { BITLEN = 4 };
|
||||
enum { MAX = (1 << BITLEN) - 1 };
|
||||
|
||||
TransferID()
|
||||
: value_(0)
|
||||
{ }
|
||||
|
||||
TransferID(uint_fast8_t value) // implicit
|
||||
: value_(value)
|
||||
{
|
||||
value_ &= MAX;
|
||||
assert(value == value_);
|
||||
}
|
||||
|
||||
bool operator!=(TransferID rhs) const { return !operator==(rhs); }
|
||||
bool operator==(TransferID rhs) const { return get() == rhs.get(); }
|
||||
|
||||
void increment()
|
||||
{
|
||||
value_ = (value_ + 1) & MAX;
|
||||
}
|
||||
|
||||
uint_fast8_t get() const
|
||||
{
|
||||
assert(value_ <= MAX);
|
||||
return value_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Amount of increment() calls to reach rhs value.
|
||||
*/
|
||||
int forwardDistance(TransferID rhs) const;
|
||||
};
|
||||
|
||||
|
||||
struct Frame
|
||||
{
|
||||
enum { MAX_TRANSFER_ID = 15 };
|
||||
|
||||
uint8_t payload[8];
|
||||
TransferType transfer_type;
|
||||
uint_fast16_t data_type_id;
|
||||
uint_fast8_t payload_len;
|
||||
uint_fast8_t source_node_id;
|
||||
uint_fast8_t frame_index;
|
||||
uint_fast8_t transfer_id;
|
||||
TransferID transfer_id;
|
||||
bool last_frame;
|
||||
|
||||
Frame(const uint8_t* payload, uint_fast8_t payload_len, uint_fast16_t data_type_id, TransferType transfer_type,
|
||||
uint_fast8_t source_node_id, uint_fast8_t frame_index, uint_fast8_t transfer_id, bool last_frame)
|
||||
uint_fast8_t source_node_id, uint_fast8_t frame_index, TransferID transfer_id, bool last_frame)
|
||||
: transfer_type(transfer_type)
|
||||
, data_type_id(data_type_id)
|
||||
, payload_len(payload_len)
|
||||
@ -48,11 +87,7 @@ struct Frame
|
||||
|
||||
static Frame parse(const CanFrame& can_frame);
|
||||
|
||||
/**
|
||||
* Difference computed from (this.transfer_id - rhs.transfer_id) with proper overflow handling.
|
||||
*/
|
||||
int subtractTransferID(const Frame& rhs) const { return subtractTransferID(rhs.transfer_id); }
|
||||
int subtractTransferID(int rhs) const;
|
||||
CanFrame compile() const;
|
||||
|
||||
bool operator!=(const Frame& rhs) const { return !operator==(rhs); }
|
||||
bool operator==(const Frame& rhs) const
|
||||
@ -69,6 +104,7 @@ struct Frame
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct RxFrame
|
||||
{
|
||||
uint_fast64_t timestamp;
|
||||
|
||||
@ -1,27 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2014 <pavel.kirienko@gmail.com>
|
||||
* Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
|
||||
*/
|
||||
|
||||
#include <cassert>
|
||||
#include <uavcan/internal/transport/transfer.hpp>
|
||||
|
||||
namespace uavcan
|
||||
{
|
||||
|
||||
//static Frame Frame::parse(const CanFrame& can_frame)
|
||||
//{
|
||||
//}
|
||||
|
||||
int Frame::subtractTransferID(int rhs) const
|
||||
int TransferID::forwardDistance(TransferID rhs) const
|
||||
{
|
||||
static const int RANGE = MAX_TRANSFER_ID + 1; // 16 256
|
||||
static const int NEGATIVE = -RANGE / 2; // -8 -128 (two's complement)
|
||||
static const int POSITIVE = (-NEGATIVE) - 1; // 7 127
|
||||
int d = int(rhs.get()) - int(get());
|
||||
if (d < 0)
|
||||
d += 1 << BITLEN;
|
||||
|
||||
const int d = int(this->transfer_id) - rhs;
|
||||
if (d <= NEGATIVE)
|
||||
return RANGE + d;
|
||||
else if (d >= POSITIVE)
|
||||
return d - RANGE;
|
||||
assert(((get() + d) & MAX) == rhs.get());
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
60
libuavcan/test/transport/transfer.cpp
Normal file
60
libuavcan/test/transport/transfer.cpp
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <gtest/gtest.h>
|
||||
#include <uavcan/internal/transport/transfer.hpp>
|
||||
|
||||
|
||||
TEST(Transfer, TransferID)
|
||||
{
|
||||
using uavcan::TransferID;
|
||||
|
||||
// Tests below are based on this assumption
|
||||
ASSERT_EQ(16, 1 << TransferID::BITLEN);
|
||||
|
||||
/*
|
||||
* forwardDistance()
|
||||
*/
|
||||
EXPECT_EQ(0, TransferID(0).forwardDistance(0));
|
||||
EXPECT_EQ(1, TransferID(0).forwardDistance(1));
|
||||
EXPECT_EQ(15, TransferID(0).forwardDistance(15));
|
||||
|
||||
EXPECT_EQ(0, TransferID(7).forwardDistance(7));
|
||||
EXPECT_EQ(15, TransferID(7).forwardDistance(6));
|
||||
EXPECT_EQ(1, TransferID(7).forwardDistance(8));
|
||||
|
||||
EXPECT_EQ(9, TransferID(10).forwardDistance(3));
|
||||
EXPECT_EQ(7, TransferID(3).forwardDistance(10));
|
||||
|
||||
EXPECT_EQ(8, TransferID(6).forwardDistance(14));
|
||||
EXPECT_EQ(8, TransferID(14).forwardDistance(6));
|
||||
|
||||
EXPECT_EQ(1, TransferID(14).forwardDistance(15));
|
||||
EXPECT_EQ(2, TransferID(14).forwardDistance(0));
|
||||
EXPECT_EQ(4, TransferID(14).forwardDistance(2));
|
||||
|
||||
EXPECT_EQ(15, TransferID(15).forwardDistance(14));
|
||||
EXPECT_EQ(14, TransferID(0).forwardDistance(14));
|
||||
EXPECT_EQ(12, TransferID(2).forwardDistance(14));
|
||||
|
||||
/*
|
||||
* Misc
|
||||
*/
|
||||
EXPECT_TRUE(TransferID(2) == TransferID(2));
|
||||
EXPECT_FALSE(TransferID(2) != TransferID(2));
|
||||
EXPECT_FALSE(TransferID(2) == TransferID(8));
|
||||
EXPECT_TRUE(TransferID(2) != TransferID(8));
|
||||
|
||||
TransferID tid;
|
||||
for (int i = 0; i < 999; i++)
|
||||
{
|
||||
ASSERT_EQ(i & ((1 << TransferID::BITLEN) - 1), tid.get());
|
||||
const TransferID copy = tid;
|
||||
tid.increment();
|
||||
ASSERT_EQ(1, copy.forwardDistance(tid));
|
||||
ASSERT_EQ(15, tid.forwardDistance(copy));
|
||||
ASSERT_EQ(0, tid.forwardDistance(tid));
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user