mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-28 05:13:33 +08:00
First step in changing the CAN frame format - introduced various transfer lengths per transfer type
This commit is contained in:
@@ -94,7 +94,7 @@ struct UAVCAN_EXPORT ${t.cpp_type_name}
|
|||||||
% endfor
|
% endfor
|
||||||
{
|
{
|
||||||
enum { MaxByteLen = ::uavcan::BitLenToByteLen<MaxBitLen>::Result };
|
enum { MaxByteLen = ::uavcan::BitLenToByteLen<MaxBitLen>::Result };
|
||||||
::uavcan::StaticAssert<int(MaxByteLen) <= int(::uavcan::MaxTransferPayloadLen)>::check();
|
::uavcan::StaticAssert<int(MaxByteLen) <= int(::uavcan::MaxPossibleTransferPayloadLen)>::check();
|
||||||
|
|
||||||
::uavcan::StaticAssert<_tmpl == 0>::check(); // Usage check
|
::uavcan::StaticAssert<_tmpl == 0>::check(); // Usage check
|
||||||
|
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ template <typename DataStruct_,
|
|||||||
class UAVCAN_EXPORT TransferListenerInstantiationHelper
|
class UAVCAN_EXPORT TransferListenerInstantiationHelper
|
||||||
{
|
{
|
||||||
enum { DataTypeMaxByteLen = BitLenToByteLen<DataStruct_::MaxBitLen>::Result };
|
enum { DataTypeMaxByteLen = BitLenToByteLen<DataStruct_::MaxBitLen>::Result };
|
||||||
enum { NeedsBuffer = int(DataTypeMaxByteLen) > int(MaxSingleFrameTransferPayloadLen) };
|
enum { NeedsBuffer = int(DataTypeMaxByteLen) > int(GuaranteedPayloadLenPerFrame) };
|
||||||
enum { BufferSize = NeedsBuffer ? DataTypeMaxByteLen : 0 };
|
enum { BufferSize = NeedsBuffer ? DataTypeMaxByteLen : 0 };
|
||||||
#if UAVCAN_TINY
|
#if UAVCAN_TINY
|
||||||
enum { NumStaticBufs = 0 };
|
enum { NumStaticBufs = 0 };
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ public:
|
|||||||
* This implementation provides the buffer large enough to
|
* This implementation provides the buffer large enough to
|
||||||
* serialize any UAVCAN data structure.
|
* serialize any UAVCAN data structure.
|
||||||
*/
|
*/
|
||||||
template <unsigned MaxSize_ = MaxTransferPayloadLen>
|
template <unsigned MaxSize_ = MaxPossibleTransferPayloadLen>
|
||||||
class UAVCAN_EXPORT MarshalBufferProvider : public IMarshalBufferProvider
|
class UAVCAN_EXPORT MarshalBufferProvider : public IMarshalBufferProvider
|
||||||
{
|
{
|
||||||
class Buffer : public IMarshalBuffer
|
class Buffer : public IMarshalBuffer
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ template <std::size_t MemPoolSize_,
|
|||||||
unsigned OutgoingTransferMaxPayloadLen = 264
|
unsigned OutgoingTransferMaxPayloadLen = 264
|
||||||
#else
|
#else
|
||||||
unsigned OutgoingTransferRegistryStaticEntries = 10,
|
unsigned OutgoingTransferRegistryStaticEntries = 10,
|
||||||
unsigned OutgoingTransferMaxPayloadLen = MaxTransferPayloadLen
|
unsigned OutgoingTransferMaxPayloadLen = MaxPossibleTransferPayloadLen
|
||||||
#endif
|
#endif
|
||||||
>
|
>
|
||||||
class UAVCAN_EXPORT Node : public INode
|
class UAVCAN_EXPORT Node : public INode
|
||||||
|
|||||||
@@ -11,10 +11,16 @@
|
|||||||
|
|
||||||
namespace uavcan
|
namespace uavcan
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Refer to the UAVCAN specification for more info about transfers.
|
||||||
|
*/
|
||||||
|
static const unsigned MaxMessageBroadcastTransferPayloadLen = 126; ///< 16 frames, 8 bytes per frame, 2 byte CRC
|
||||||
|
static const unsigned MaxMessageUnicastTransferPayloadLen = 110; ///< 16 frames, 7 bytes per frame, 2 byte CRC
|
||||||
|
static const unsigned MaxServiceTransferPayloadLen = 439; ///< 63 frames, 7 bytes per frame, 2 byte CRC
|
||||||
|
|
||||||
static const unsigned MaxTransferPayloadLen = 439; ///< According to the specification.
|
static const unsigned GuaranteedPayloadLenPerFrame = 7; ///< Guaranteed for all transfers, all CAN standards
|
||||||
|
|
||||||
static const unsigned MaxSingleFrameTransferPayloadLen = 7;
|
static const unsigned MaxPossibleTransferPayloadLen = MaxServiceTransferPayloadLen;
|
||||||
|
|
||||||
enum TransferType
|
enum TransferType
|
||||||
{
|
{
|
||||||
@@ -26,6 +32,27 @@ enum TransferType
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static inline unsigned getMaxPayloadLenForTransferType(const TransferType type)
|
||||||
|
{
|
||||||
|
static const unsigned lens[NumTransferTypes] =
|
||||||
|
{
|
||||||
|
MaxServiceTransferPayloadLen,
|
||||||
|
MaxServiceTransferPayloadLen,
|
||||||
|
MaxMessageBroadcastTransferPayloadLen,
|
||||||
|
MaxMessageUnicastTransferPayloadLen
|
||||||
|
};
|
||||||
|
if (static_cast<int>(type) < NumTransferTypes)
|
||||||
|
{
|
||||||
|
return lens[static_cast<int>(type)];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UAVCAN_ASSERT(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class UAVCAN_EXPORT TransferID
|
class UAVCAN_EXPORT TransferID
|
||||||
{
|
{
|
||||||
uint8_t value_;
|
uint8_t value_;
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ int TransferSender::send(const uint8_t* payload, unsigned payload_len, Monotonic
|
|||||||
MonotonicTime blocking_deadline, TransferType transfer_type, NodeID dst_node_id,
|
MonotonicTime blocking_deadline, TransferType transfer_type, NodeID dst_node_id,
|
||||||
TransferID tid)
|
TransferID tid)
|
||||||
{
|
{
|
||||||
if (payload_len > MaxTransferPayloadLen)
|
if (payload_len > getMaxPayloadLenForTransferType(transfer_type))
|
||||||
{
|
{
|
||||||
UAVCAN_ASSERT(0);
|
UAVCAN_ASSERT(0);
|
||||||
return -ErrInvalidParam;
|
return -ErrInvalidParam;
|
||||||
|
|||||||
@@ -225,21 +225,24 @@ TEST(TransferListener, MaximumTransferLength)
|
|||||||
|
|
||||||
uavcan::PoolManager<1> poolmgr;
|
uavcan::PoolManager<1> poolmgr;
|
||||||
uavcan::TransferPerfCounter perf;
|
uavcan::TransferPerfCounter perf;
|
||||||
TestListener<uavcan::MaxTransferPayloadLen * 2, 2, 2> subscriber(perf, type, poolmgr);
|
TestListener<uavcan::MaxPossibleTransferPayloadLen * 2, 3, 3> subscriber(perf, type, poolmgr);
|
||||||
|
|
||||||
static const std::string DATA_OK(uavcan::MaxTransferPayloadLen, 'z');
|
|
||||||
|
|
||||||
TransferListenerEmulator emulator(subscriber, type);
|
TransferListenerEmulator emulator(subscriber, type);
|
||||||
const Transfer transfers[] =
|
const Transfer transfers[] =
|
||||||
{
|
{
|
||||||
emulator.makeTransfer(uavcan::TransferTypeMessageUnicast, 1, DATA_OK),
|
emulator.makeTransfer(uavcan::TransferTypeServiceRequest, 1,
|
||||||
emulator.makeTransfer(uavcan::TransferTypeMessageBroadcast, 1, DATA_OK)
|
std::string(uavcan::MaxServiceTransferPayloadLen, 'z')), // Longer
|
||||||
|
emulator.makeTransfer(uavcan::TransferTypeMessageUnicast, 2,
|
||||||
|
std::string(uavcan::MaxMessageUnicastTransferPayloadLen, 'z')), // Shorter
|
||||||
|
emulator.makeTransfer(uavcan::TransferTypeMessageBroadcast, 3,
|
||||||
|
std::string(uavcan::MaxMessageBroadcastTransferPayloadLen, 'z')) // Same as above
|
||||||
};
|
};
|
||||||
|
|
||||||
emulator.send(transfers);
|
emulator.send(transfers);
|
||||||
|
|
||||||
ASSERT_TRUE(subscriber.matchAndPop(transfers[1])); // Broadcast is shorter, so will complete first
|
ASSERT_TRUE(subscriber.matchAndPop(transfers[1]));
|
||||||
ASSERT_TRUE(subscriber.matchAndPop(transfers[0]));
|
ASSERT_TRUE(subscriber.matchAndPop(transfers[2]));
|
||||||
|
ASSERT_TRUE(subscriber.matchAndPop(transfers[0])); // Service takes more frames
|
||||||
|
|
||||||
ASSERT_TRUE(subscriber.isEmpty());
|
ASSERT_TRUE(subscriber.isEmpty());
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user