mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-04-14 10:07:39 +08:00
Heavy optimizations for ROM/RAM usage in UAVCAN_TINY mode
This commit is contained in:
parent
4085613d00
commit
87e89fc042
@ -61,9 +61,10 @@
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Functionality / Code Size trade-off.
|
||||
* Trade-off between ROM/RAM usage and functionality/determinism.
|
||||
* Note that this feature is not well tested and should be avoided.
|
||||
* Use code search for UAVCAN_TINY to find what functionality will be disabled.
|
||||
* This is particularly useful for embedded systems with less than 64kB of ROM.
|
||||
* This is particularly useful for embedded systems with less than 40kB of ROM.
|
||||
*/
|
||||
#ifndef UAVCAN_TINY
|
||||
# define UAVCAN_TINY 0
|
||||
|
||||
@ -86,13 +86,16 @@ class UAVCAN_EXPORT MapBase : Noncopyable
|
||||
|
||||
LinkedListRoot<KVGroup> list_;
|
||||
IPoolAllocator& allocator_;
|
||||
#if !UAVCAN_TINY
|
||||
KVPair* const static_;
|
||||
const unsigned num_static_entries_;
|
||||
#endif
|
||||
|
||||
KVPair* find(const Key& key);
|
||||
|
||||
#if !UAVCAN_TINY
|
||||
void optimizeStorage();
|
||||
|
||||
#endif
|
||||
void compact();
|
||||
|
||||
struct YesPredicate
|
||||
@ -101,6 +104,13 @@ class UAVCAN_EXPORT MapBase : Noncopyable
|
||||
};
|
||||
|
||||
protected:
|
||||
#if UAVCAN_TINY
|
||||
MapBase(IPoolAllocator& allocator)
|
||||
: allocator_(allocator)
|
||||
{
|
||||
assert(Key() == Key());
|
||||
}
|
||||
#else
|
||||
MapBase(KVPair* static_buf, unsigned num_static_entries, IPoolAllocator& allocator)
|
||||
: allocator_(allocator)
|
||||
, static_(static_buf)
|
||||
@ -108,6 +118,7 @@ protected:
|
||||
{
|
||||
assert(Key() == Key());
|
||||
}
|
||||
#endif
|
||||
|
||||
/// Derived class destructor must call removeAll();
|
||||
~MapBase() { }
|
||||
@ -149,11 +160,17 @@ class UAVCAN_EXPORT Map : public MapBase<Key, Value>
|
||||
typename MapBase<Key, Value>::KVPair static_[NumStaticEntries];
|
||||
|
||||
public:
|
||||
|
||||
#if !UAVCAN_TINY
|
||||
|
||||
// This instantiation will not be valid in UAVCAN_TINY mode
|
||||
Map(IPoolAllocator& allocator)
|
||||
: MapBase<Key, Value>(static_, NumStaticEntries, allocator)
|
||||
{ }
|
||||
|
||||
~Map() { this->removeAll(); }
|
||||
|
||||
#endif // !UAVCAN_TINY
|
||||
};
|
||||
|
||||
|
||||
@ -162,7 +179,11 @@ class UAVCAN_EXPORT Map<Key, Value, 0> : public MapBase<Key, Value>
|
||||
{
|
||||
public:
|
||||
Map(IPoolAllocator& allocator)
|
||||
#if UAVCAN_TINY
|
||||
: MapBase<Key, Value>(allocator)
|
||||
#else
|
||||
: MapBase<Key, Value>(NULL, 0, allocator)
|
||||
#endif
|
||||
{ }
|
||||
|
||||
~Map() { this->removeAll(); }
|
||||
@ -176,6 +197,7 @@ public:
|
||||
template <typename Key, typename Value>
|
||||
typename MapBase<Key, Value>::KVPair* MapBase<Key, Value>::find(const Key& key)
|
||||
{
|
||||
#if !UAVCAN_TINY
|
||||
for (unsigned i = 0; i < num_static_entries_; i++)
|
||||
{
|
||||
if (static_[i].match(key))
|
||||
@ -183,6 +205,7 @@ typename MapBase<Key, Value>::KVPair* MapBase<Key, Value>::find(const Key& key)
|
||||
return static_ + i;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
KVGroup* p = list_.get();
|
||||
while (p)
|
||||
@ -197,6 +220,8 @@ typename MapBase<Key, Value>::KVPair* MapBase<Key, Value>::find(const Key& key)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if !UAVCAN_TINY
|
||||
|
||||
template <typename Key, typename Value>
|
||||
void MapBase<Key, Value>::optimizeStorage()
|
||||
{
|
||||
@ -249,6 +274,8 @@ void MapBase<Key, Value>::optimizeStorage()
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !UAVCAN_TINY
|
||||
|
||||
template <typename Key, typename Value>
|
||||
void MapBase<Key, Value>::compact()
|
||||
{
|
||||
@ -313,7 +340,9 @@ void MapBase<Key, Value>::remove(const Key& key)
|
||||
if (kv)
|
||||
{
|
||||
*kv = KVPair();
|
||||
#if !UAVCAN_TINY
|
||||
optimizeStorage();
|
||||
#endif
|
||||
compact();
|
||||
}
|
||||
}
|
||||
@ -324,6 +353,7 @@ void MapBase<Key, Value>::removeWhere(Predicate predicate)
|
||||
{
|
||||
unsigned num_removed = 0;
|
||||
|
||||
#if !UAVCAN_TINY
|
||||
for (unsigned i = 0; i < num_static_entries_; i++)
|
||||
{
|
||||
if (!static_[i].match(Key()))
|
||||
@ -335,6 +365,7 @@ void MapBase<Key, Value>::removeWhere(Predicate predicate)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
KVGroup* p = list_.get();
|
||||
while (p)
|
||||
@ -356,7 +387,9 @@ void MapBase<Key, Value>::removeWhere(Predicate predicate)
|
||||
|
||||
if (num_removed > 0)
|
||||
{
|
||||
#if !UAVCAN_TINY
|
||||
optimizeStorage();
|
||||
#endif
|
||||
compact();
|
||||
}
|
||||
}
|
||||
@ -365,6 +398,7 @@ template <typename Key, typename Value>
|
||||
template <typename Predicate>
|
||||
const Key* MapBase<Key, Value>::findFirstKey(Predicate predicate) const
|
||||
{
|
||||
#if !UAVCAN_TINY
|
||||
for (unsigned i = 0; i < num_static_entries_; i++)
|
||||
{
|
||||
if (!static_[i].match(Key()))
|
||||
@ -375,6 +409,7 @@ const Key* MapBase<Key, Value>::findFirstKey(Predicate predicate) const
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
KVGroup* p = list_.get();
|
||||
while (p)
|
||||
@ -411,6 +446,7 @@ template <typename Key, typename Value>
|
||||
unsigned MapBase<Key, Value>::getNumStaticPairs() const
|
||||
{
|
||||
unsigned num = 0;
|
||||
#if !UAVCAN_TINY
|
||||
for (unsigned i = 0; i < num_static_entries_; i++)
|
||||
{
|
||||
if (!static_[i].match(Key()))
|
||||
@ -418,6 +454,7 @@ unsigned MapBase<Key, Value>::getNumStaticPairs() const
|
||||
num++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return num;
|
||||
}
|
||||
|
||||
|
||||
@ -98,11 +98,16 @@ class UAVCAN_EXPORT TransferListenerInstantiationHelper
|
||||
enum { DataTypeMaxByteLen = BitLenToByteLen<DataStruct_::MaxBitLen>::Result };
|
||||
enum { NeedsBuffer = int(DataTypeMaxByteLen) > int(MaxSingleFrameTransferPayloadLen) };
|
||||
enum { BufferSize = NeedsBuffer ? DataTypeMaxByteLen : 0 };
|
||||
enum { NumStaticBufs = NeedsBuffer ? (NumStaticBufs_ ? NumStaticBufs_ : 1) : 0 };
|
||||
#if UAVCAN_TINY
|
||||
enum { NumStaticBufs = 0 };
|
||||
enum { NumStaticReceivers = 0 };
|
||||
#else
|
||||
enum { NumStaticBufs = NeedsBuffer ? NumStaticBufs_: 0 };
|
||||
enum { NumStaticReceivers = NumStaticReceivers_ };
|
||||
#endif
|
||||
|
||||
public:
|
||||
// TODO: support for zero static bufs
|
||||
typedef TransferListener<BufferSize, NumStaticBufs, NumStaticReceivers_ ? NumStaticReceivers_ : 1> Type;
|
||||
typedef TransferListener<BufferSize, NumStaticBufs, NumStaticReceivers> Type;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -30,8 +30,14 @@ namespace uavcan
|
||||
{
|
||||
|
||||
template <std::size_t MemPoolSize_,
|
||||
#if UAVCAN_TINY
|
||||
unsigned OutgoingTransferRegistryStaticEntries = 0,
|
||||
unsigned OutgoingTransferMaxPayloadLen = 264
|
||||
#else
|
||||
unsigned OutgoingTransferRegistryStaticEntries = 10,
|
||||
unsigned OutgoingTransferMaxPayloadLen = MaxTransferPayloadLen>
|
||||
unsigned OutgoingTransferMaxPayloadLen = MaxTransferPayloadLen
|
||||
#endif
|
||||
>
|
||||
class UAVCAN_EXPORT Node : public INode
|
||||
{
|
||||
enum
|
||||
|
||||
@ -27,8 +27,14 @@ template <typename DataType_,
|
||||
typename Callback_ = void (*)(const ReceivedDataStructure<typename DataType_::Request>&,
|
||||
typename DataType_::Response&),
|
||||
#endif
|
||||
#if UAVCAN_TINY
|
||||
unsigned NumStaticReceivers = 0,
|
||||
unsigned NumStaticBufs = 0
|
||||
#else
|
||||
unsigned NumStaticReceivers = 2,
|
||||
unsigned NumStaticBufs = 1>
|
||||
unsigned NumStaticBufs = 1
|
||||
#endif
|
||||
>
|
||||
class UAVCAN_EXPORT ServiceServer
|
||||
: public GenericSubscriber<DataType_, typename DataType_::Request,
|
||||
typename TransferListenerInstantiationHelper<typename DataType_::Request,
|
||||
|
||||
@ -25,8 +25,14 @@ template <typename DataType_,
|
||||
#else
|
||||
typename Callback_ = void (*)(const ReceivedDataStructure<DataType_>&),
|
||||
#endif
|
||||
#if UAVCAN_TINY
|
||||
unsigned NumStaticReceivers = 0,
|
||||
unsigned NumStaticBufs = 0
|
||||
#else
|
||||
unsigned NumStaticReceivers = 2,
|
||||
unsigned NumStaticBufs = 1>
|
||||
unsigned NumStaticBufs = 1
|
||||
#endif
|
||||
>
|
||||
class UAVCAN_EXPORT Subscriber
|
||||
: public GenericSubscriber<DataType_, DataType_,
|
||||
typename TransferListenerInstantiationHelper<DataType_, NumStaticReceivers,
|
||||
|
||||
@ -298,6 +298,9 @@ public:
|
||||
TransferBufferManager(IPoolAllocator& allocator)
|
||||
: TransferBufferManagerImpl(MaxBufSize, allocator)
|
||||
{
|
||||
#if UAVCAN_TINY
|
||||
StaticAssert<(NumStaticBufs == 0)>::check(); // Static buffers in UAVCAN_TINY mode are not allowed
|
||||
#endif
|
||||
StaticAssert<(MaxBufSize > 0)>::check();
|
||||
}
|
||||
};
|
||||
@ -305,7 +308,7 @@ public:
|
||||
template <uint16_t MaxBufSize>
|
||||
class UAVCAN_EXPORT TransferBufferManager<MaxBufSize, 0> : public TransferBufferManagerImpl
|
||||
{
|
||||
StaticTransferBufferManagerEntry<MaxBufSize>* getStaticByIndex(uint16_t index) const
|
||||
StaticTransferBufferManagerEntry<MaxBufSize>* getStaticByIndex(uint16_t) const
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -150,6 +150,10 @@ public:
|
||||
, bufmgr_(allocator)
|
||||
, receivers_(allocator)
|
||||
{
|
||||
#if UAVCAN_TINY
|
||||
StaticAssert<NumStaticBufs == 0>::check();
|
||||
StaticAssert<NumStaticReceivers == 0>::check();
|
||||
#endif
|
||||
StaticAssert<(NumStaticReceivers >= NumStaticBufs)>::check(); // Otherwise it would be meaningless
|
||||
}
|
||||
|
||||
@ -164,7 +168,12 @@ public:
|
||||
* This class should be derived by callers.
|
||||
*/
|
||||
template <unsigned MaxBufSize>
|
||||
class UAVCAN_EXPORT ServiceResponseTransferListener : public TransferListener<MaxBufSize, 1, 1>
|
||||
class UAVCAN_EXPORT ServiceResponseTransferListener
|
||||
#if UAVCAN_TINY
|
||||
: public TransferListener<MaxBufSize, 0, 0>
|
||||
#else
|
||||
: public TransferListener<MaxBufSize, 1, 1>
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
struct ExpectedResponseParams
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
namespace
|
||||
{
|
||||
|
||||
typedef uavcan::Node<2048> Node;
|
||||
typedef uavcan::Node<3584> Node;
|
||||
|
||||
Node& getNode()
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user