First step in changing the CAN frame format - introduced various transfer lengths per transfer type

This commit is contained in:
Pavel Kirienko
2015-04-28 11:27:01 +03:00
parent 1b75c48783
commit c159f9f7df
7 changed files with 44 additions and 14 deletions
@@ -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
+1 -1
View File
@@ -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;
+10 -7
View File
@@ -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());
} }