diff --git a/libuavcan/include/uavcan/impl_constants.hpp b/libuavcan/include/uavcan/impl_constants.hpp index c429b1f6b1..923a23e572 100644 --- a/libuavcan/include/uavcan/impl_constants.hpp +++ b/libuavcan/include/uavcan/impl_constants.hpp @@ -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 diff --git a/libuavcan/include/uavcan/map.hpp b/libuavcan/include/uavcan/map.hpp index ba6b91e025..306e2cfd57 100644 --- a/libuavcan/include/uavcan/map.hpp +++ b/libuavcan/include/uavcan/map.hpp @@ -86,13 +86,16 @@ class UAVCAN_EXPORT MapBase : Noncopyable LinkedListRoot 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 typename MapBase::KVPair static_[NumStaticEntries]; public: + +#if !UAVCAN_TINY + + // This instantiation will not be valid in UAVCAN_TINY mode Map(IPoolAllocator& allocator) : MapBase(static_, NumStaticEntries, allocator) { } ~Map() { this->removeAll(); } + +#endif // !UAVCAN_TINY }; @@ -162,7 +179,11 @@ class UAVCAN_EXPORT Map : public MapBase { public: Map(IPoolAllocator& allocator) +#if UAVCAN_TINY + : MapBase(allocator) +#else : MapBase(NULL, 0, allocator) +#endif { } ~Map() { this->removeAll(); } @@ -176,6 +197,7 @@ public: template typename MapBase::KVPair* MapBase::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::KVPair* MapBase::find(const Key& key) return static_ + i; } } +#endif KVGroup* p = list_.get(); while (p) @@ -197,6 +220,8 @@ typename MapBase::KVPair* MapBase::find(const Key& key) return NULL; } +#if !UAVCAN_TINY + template void MapBase::optimizeStorage() { @@ -249,6 +274,8 @@ void MapBase::optimizeStorage() } } +#endif // !UAVCAN_TINY + template void MapBase::compact() { @@ -313,7 +340,9 @@ void MapBase::remove(const Key& key) if (kv) { *kv = KVPair(); +#if !UAVCAN_TINY optimizeStorage(); +#endif compact(); } } @@ -324,6 +353,7 @@ void MapBase::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::removeWhere(Predicate predicate) } } } +#endif KVGroup* p = list_.get(); while (p) @@ -356,7 +387,9 @@ void MapBase::removeWhere(Predicate predicate) if (num_removed > 0) { +#if !UAVCAN_TINY optimizeStorage(); +#endif compact(); } } @@ -365,6 +398,7 @@ template template const Key* MapBase::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::findFirstKey(Predicate predicate) const } } } +#endif KVGroup* p = list_.get(); while (p) @@ -411,6 +446,7 @@ template unsigned MapBase::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::getNumStaticPairs() const num++; } } +#endif return num; } diff --git a/libuavcan/include/uavcan/node/generic_subscriber.hpp b/libuavcan/include/uavcan/node/generic_subscriber.hpp index dcc7f10120..6e6c00a4ac 100644 --- a/libuavcan/include/uavcan/node/generic_subscriber.hpp +++ b/libuavcan/include/uavcan/node/generic_subscriber.hpp @@ -98,11 +98,16 @@ class UAVCAN_EXPORT TransferListenerInstantiationHelper enum { DataTypeMaxByteLen = BitLenToByteLen::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 Type; + typedef TransferListener Type; }; diff --git a/libuavcan/include/uavcan/node/node.hpp b/libuavcan/include/uavcan/node/node.hpp index d40c33eabe..97806663f5 100644 --- a/libuavcan/include/uavcan/node/node.hpp +++ b/libuavcan/include/uavcan/node/node.hpp @@ -30,8 +30,14 @@ namespace uavcan { template + unsigned OutgoingTransferMaxPayloadLen = MaxTransferPayloadLen +#endif + > class UAVCAN_EXPORT Node : public INode { enum diff --git a/libuavcan/include/uavcan/node/service_server.hpp b/libuavcan/include/uavcan/node/service_server.hpp index 22898b1b96..b7043e3a82 100644 --- a/libuavcan/include/uavcan/node/service_server.hpp +++ b/libuavcan/include/uavcan/node/service_server.hpp @@ -27,8 +27,14 @@ template &, 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&), #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::check(); // Static buffers in UAVCAN_TINY mode are not allowed +#endif StaticAssert<(MaxBufSize > 0)>::check(); } }; @@ -305,7 +308,7 @@ public: template class UAVCAN_EXPORT TransferBufferManager : public TransferBufferManagerImpl { - StaticTransferBufferManagerEntry* getStaticByIndex(uint16_t index) const + StaticTransferBufferManagerEntry* getStaticByIndex(uint16_t) const { return NULL; } diff --git a/libuavcan/include/uavcan/transport/transfer_listener.hpp b/libuavcan/include/uavcan/transport/transfer_listener.hpp index a3a885f1c9..38a45bcdcf 100644 --- a/libuavcan/include/uavcan/transport/transfer_listener.hpp +++ b/libuavcan/include/uavcan/transport/transfer_listener.hpp @@ -150,6 +150,10 @@ public: , bufmgr_(allocator) , receivers_(allocator) { +#if UAVCAN_TINY + StaticAssert::check(); + StaticAssert::check(); +#endif StaticAssert<(NumStaticReceivers >= NumStaticBufs)>::check(); // Otherwise it would be meaningless } @@ -164,7 +168,12 @@ public: * This class should be derived by callers. */ template -class UAVCAN_EXPORT ServiceResponseTransferListener : public TransferListener +class UAVCAN_EXPORT ServiceResponseTransferListener +#if UAVCAN_TINY + : public TransferListener +#else + : public TransferListener +#endif { public: struct ExpectedResponseParams diff --git a/libuavcan_drivers/lpc11c24/test_olimex_lpc_p11c24/src/main.cpp b/libuavcan_drivers/lpc11c24/test_olimex_lpc_p11c24/src/main.cpp index 7911fae11b..cbe8b020f6 100644 --- a/libuavcan_drivers/lpc11c24/test_olimex_lpc_p11c24/src/main.cpp +++ b/libuavcan_drivers/lpc11c24/test_olimex_lpc_p11c24/src/main.cpp @@ -10,7 +10,7 @@ namespace { -typedef uavcan::Node<2048> Node; +typedef uavcan::Node<3584> Node; Node& getNode() {