mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-21 01:33:33 +08:00
TransferID class
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2014 <pavel.kirienko@gmail.com>
|
* Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
@@ -19,21 +19,60 @@ enum TransferType
|
|||||||
MESSAGE_UNICAST = 3
|
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
|
struct Frame
|
||||||
{
|
{
|
||||||
enum { MAX_TRANSFER_ID = 15 };
|
|
||||||
|
|
||||||
uint8_t payload[8];
|
uint8_t payload[8];
|
||||||
TransferType transfer_type;
|
TransferType transfer_type;
|
||||||
uint_fast16_t data_type_id;
|
uint_fast16_t data_type_id;
|
||||||
uint_fast8_t payload_len;
|
uint_fast8_t payload_len;
|
||||||
uint_fast8_t source_node_id;
|
uint_fast8_t source_node_id;
|
||||||
uint_fast8_t frame_index;
|
uint_fast8_t frame_index;
|
||||||
uint_fast8_t transfer_id;
|
TransferID transfer_id;
|
||||||
bool last_frame;
|
bool last_frame;
|
||||||
|
|
||||||
Frame(const uint8_t* payload, uint_fast8_t payload_len, uint_fast16_t data_type_id, TransferType transfer_type,
|
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)
|
: transfer_type(transfer_type)
|
||||||
, data_type_id(data_type_id)
|
, data_type_id(data_type_id)
|
||||||
, payload_len(payload_len)
|
, payload_len(payload_len)
|
||||||
@@ -48,11 +87,7 @@ struct Frame
|
|||||||
|
|
||||||
static Frame parse(const CanFrame& can_frame);
|
static Frame parse(const CanFrame& can_frame);
|
||||||
|
|
||||||
/**
|
CanFrame compile() const;
|
||||||
* 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;
|
|
||||||
|
|
||||||
bool operator!=(const Frame& rhs) const { return !operator==(rhs); }
|
bool operator!=(const Frame& rhs) const { return !operator==(rhs); }
|
||||||
bool operator==(const Frame& rhs) const
|
bool operator==(const Frame& rhs) const
|
||||||
@@ -69,6 +104,7 @@ struct Frame
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct RxFrame
|
struct RxFrame
|
||||||
{
|
{
|
||||||
uint_fast64_t timestamp;
|
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>
|
#include <uavcan/internal/transport/transfer.hpp>
|
||||||
|
|
||||||
namespace uavcan
|
namespace uavcan
|
||||||
{
|
{
|
||||||
|
|
||||||
//static Frame Frame::parse(const CanFrame& can_frame)
|
int TransferID::forwardDistance(TransferID rhs) const
|
||||||
//{
|
|
||||||
//}
|
|
||||||
|
|
||||||
int Frame::subtractTransferID(int rhs) const
|
|
||||||
{
|
{
|
||||||
static const int RANGE = MAX_TRANSFER_ID + 1; // 16 256
|
int d = int(rhs.get()) - int(get());
|
||||||
static const int NEGATIVE = -RANGE / 2; // -8 -128 (two's complement)
|
if (d < 0)
|
||||||
static const int POSITIVE = (-NEGATIVE) - 1; // 7 127
|
d += 1 << BITLEN;
|
||||||
|
|
||||||
const int d = int(this->transfer_id) - rhs;
|
assert(((get() + d) & MAX) == rhs.get());
|
||||||
if (d <= NEGATIVE)
|
|
||||||
return RANGE + d;
|
|
||||||
else if (d >= POSITIVE)
|
|
||||||
return d - RANGE;
|
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user