Merge branch 'dsdl_review'

This commit is contained in:
Pavel Kirienko
2015-03-27 00:05:46 +03:00
96 changed files with 636 additions and 392 deletions
+8 -1
View File
@@ -123,7 +123,6 @@
#if UAVCAN_TOSTRING
# include <string>
# include <cstdio>
#endif
/**
@@ -135,6 +134,14 @@
# define UAVCAN_IMPLEMENT_PLACEMENT_NEW 0
#endif
/**
* Allows the user's application to provide custom implementation of uavcan::snprintf(),
* which is often useful on deeply embedded systems.
*/
#ifndef UAVCAN_USE_EXTERNAL_SNPRINTF
# define UAVCAN_USE_EXTERNAL_SNPRINTF 0
#endif
/**
* Run time checks.
* Resolves to the standard assert() by default.
+1 -1
View File
@@ -7,7 +7,7 @@
#include <cassert>
#include <cstring>
#include <uavcan/stdint.hpp>
#include <uavcan/std.hpp>
#include <uavcan/build_config.hpp>
#include <uavcan/transport/transfer.hpp>
+1 -1
View File
@@ -7,7 +7,7 @@
#define UAVCAN_DRIVER_CAN_HPP_INCLUDED
#include <cassert>
#include <uavcan/stdint.hpp>
#include <uavcan/std.hpp>
#include <uavcan/build_config.hpp>
#include <uavcan/driver/system_clock.hpp>
@@ -6,7 +6,7 @@
#ifndef UAVCAN_DRIVER_SYSTEM_CLOCK_HPP_INCLUDED
#define UAVCAN_DRIVER_SYSTEM_CLOCK_HPP_INCLUDED
#include <uavcan/stdint.hpp>
#include <uavcan/std.hpp>
#include <uavcan/build_config.hpp>
#include <uavcan/time.hpp>
+1 -2
View File
@@ -8,7 +8,7 @@
#include <cassert>
#include <cstdlib>
#include <cstring>
#include <uavcan/stdint.hpp>
#include <uavcan/std.hpp>
#include <uavcan/util/templates.hpp>
#include <uavcan/util/placement_new.hpp>
#include <uavcan/build_config.hpp>
@@ -157,7 +157,6 @@ bool PoolManager<MaxPools>::addPool(IPoolAllocator* pool)
}
}
// We need to keep the pools in order, so that smallest blocks go first
using namespace std; // for qsort()
qsort(pools_, MaxPools, sizeof(IPoolAllocator*), &PoolManager::qsortComparePoolAllocators);
return retval;
}
+1 -1
View File
@@ -6,7 +6,7 @@
#define UAVCAN_ERROR_HPP_INCLUDED
#include <uavcan/build_config.hpp>
#include <uavcan/stdint.hpp>
#include <uavcan/std.hpp>
namespace uavcan
{
@@ -6,7 +6,7 @@
#define UAVCAN_HELPERS_COMPONENT_STATUS_MANAGER_HPP_INCLUDED
#include <uavcan/build_config.hpp>
#include <uavcan/stdint.hpp>
#include <uavcan/std.hpp>
#include <uavcan/protocol/NodeStatus.hpp>
namespace uavcan
+35 -2
View File
@@ -15,6 +15,7 @@
#include <uavcan/build_config.hpp>
#include <uavcan/marshal/type_util.hpp>
#include <uavcan/marshal/integer_spec.hpp>
#include <uavcan/std.hpp>
#ifndef UAVCAN_CPP_VERSION
# error UAVCAN_CPP_VERSION
@@ -714,7 +715,8 @@ public:
StaticAssert<IsDynamic>::check();
StaticAssert<sizeof(A() >= A(0))>::check(); // This check allows to weed out most compound types
StaticAssert<sizeof(A) <= sizeof(long double)>::check(); // Another stupid check to catch non-primitive types
StaticAssert<(sizeof(A) <= sizeof(long double)) ||
(sizeof(A) <= sizeof(long long))>::check(); // Another stupid check to catch non-primitive types
if (!format)
{
@@ -728,7 +730,6 @@ public:
const SizeType max_size = SizeType(capacity() - size());
// We have one extra byte for the null terminator, hence +1
using namespace std; // For snprintf()
const int ret = snprintf(reinterpret_cast<char*>(ptr), SizeType(max_size + 1U), format, value);
for (int i = 0; i < min(ret, int(max_size)); i++)
@@ -742,6 +743,38 @@ public:
}
}
/**
* Converts the string to upper/lower case in place, assuming that encoding is ASCII.
* These methods can only be used with string-like arrays; otherwise compilation will fail.
*/
void convertToUpperCaseASCII()
{
StaticAssert<Base::IsStringLike>::check();
for (SizeType i = 0; i < size(); i++)
{
const int x = Base::at(i);
if ((x <= 'z') && (x >= 'a'))
{
Base::at(i) = static_cast<ValueType>(x + ('Z' - 'z'));
}
}
}
void convertToLowerCaseASCII()
{
StaticAssert<Base::IsStringLike>::check();
for (SizeType i = 0; i < size(); i++)
{
const int x = Base::at(i);
if ((x <= 'Z') && (x >= 'A'))
{
Base::at(i) = static_cast<ValueType>(x - ('Z' - 'z'));
}
}
}
/**
* Fills this array as a packed square matrix from a static array.
* Please refer to the specification to learn more about matrix packing.
@@ -6,7 +6,7 @@
#define UAVCAN_MARSHAL_BIT_STREAM_HPP_INCLUDED
#include <cassert>
#include <uavcan/stdint.hpp>
#include <uavcan/std.hpp>
#include <uavcan/util/templates.hpp>
#include <uavcan/transport/abstract_transfer_buffer.hpp>
#include <uavcan/build_config.hpp>
@@ -6,7 +6,7 @@
#define UAVCAN_MARSHAL_FLOAT_SPEC_HPP_INCLUDED
#include <cmath>
#include <uavcan/stdint.hpp>
#include <uavcan/std.hpp>
#include <uavcan/data_type.hpp>
#include <uavcan/util/templates.hpp>
#include <uavcan/build_config.hpp>
@@ -16,9 +16,7 @@
#ifndef UAVCAN_CPP_VERSION
# error UAVCAN_CPP_VERSION
#endif
#if UAVCAN_CPP_VERSION < UAVCAN_CPP11
# include <math.h> // Needed for isfinite()
#else
#if UAVCAN_CPP_VERSION >= UAVCAN_CPP11
# include <limits> // Assuming that in C++11 mode all standard headers are available
#endif
@@ -169,8 +167,7 @@ public:
private:
static inline void saturate(StorageType& value)
{
using namespace std;
if ((IsExactRepresentation == 0) && isfinite(value))
if ((IsExactRepresentation == 0) && isFinite(value))
{
if (value > max())
{
@@ -189,8 +186,7 @@ private:
static inline void truncate(StorageType& value)
{
using namespace std;
if ((IsExactRepresentation == 0) && isfinite(value))
if ((IsExactRepresentation == 0) && isFinite(value))
{
if (value > max())
{
@@ -5,7 +5,7 @@
#ifndef UAVCAN_MARSHAL_INTEGER_SPEC_HPP_INCLUDED
#define UAVCAN_MARSHAL_INTEGER_SPEC_HPP_INCLUDED
#include <uavcan/stdint.hpp>
#include <uavcan/std.hpp>
#include <uavcan/data_type.hpp>
#include <uavcan/util/templates.hpp>
#include <uavcan/marshal/scalar_codec.hpp>
@@ -6,7 +6,7 @@
#define UAVCAN_MARSHAL_SCALAR_CODEC_HPP_INCLUDED
#include <cassert>
#include <uavcan/stdint.hpp>
#include <uavcan/std.hpp>
#include <uavcan/build_config.hpp>
#include <uavcan/util/templates.hpp>
#include <uavcan/marshal/bit_stream.hpp>
@@ -7,7 +7,7 @@
#include <cassert>
#include <uavcan/error.hpp>
#include <uavcan/stdint.hpp>
#include <uavcan/std.hpp>
#include <uavcan/data_type.hpp>
#include <uavcan/util/bitset.hpp>
#include <uavcan/util/templates.hpp>
+8
View File
@@ -180,6 +180,14 @@ public:
(void)proto_nsp_.forcePublish();
}
/**
* Updates the vendor-specific status code.
*/
void setVendorSpecificStatusCode(NodeStatusProvider::VendorSpecificStatusCode code)
{
proto_nsp_.setVendorSpecificStatusCode(code);
}
/**
* Sets the node version information.
*/
+1 -1
View File
@@ -5,7 +5,7 @@
#ifndef UAVCAN_NODE_TIMER_HPP_INCLUDED
#define UAVCAN_NODE_TIMER_HPP_INCLUDED
#include <uavcan/stdint.hpp>
#include <uavcan/std.hpp>
#include <uavcan/error.hpp>
#include <uavcan/build_config.hpp>
#include <uavcan/util/linked_list.hpp>
@@ -46,7 +46,12 @@ private:
void (NodeStatusMonitor::*)(const ReceivedDataStructure<protocol::NodeStatus>&)>
NodeStatusCallback;
Subscriber<protocol::NodeStatus, NodeStatusCallback> sub_;
/*
* We'll be able to handle this many nodes in the network without any dynamic memory.
*/
enum { NumStaticReceivers = 64 };
Subscriber<protocol::NodeStatus, NodeStatusCallback, NumStaticReceivers, 0> sub_;
struct Entry
{
@@ -49,6 +49,9 @@ class UAVCAN_EXPORT NodeStatusProvider : private TimerBase
void handleGetNodeInfoRequest(const protocol::GetNodeInfo::Request&, protocol::GetNodeInfo::Response& rsp);
public:
typedef typename StorageType<typename protocol::NodeStatus::FieldTypes::vendor_specific_status_code>::Type
VendorSpecificStatusCode;
explicit NodeStatusProvider(INode& node)
: TimerBase(node)
, creation_timestamp_(node.getMonotonicTime())
@@ -78,8 +81,8 @@ public:
* Refer to the DSDL definition of uavcan.protocol.NodeStatus to see what is the default rate.
* Doesn't fail; if the value is outside of acceptable range, a closest valid value will be used instead.
*/
void setStatusPublishingPeriod(uavcan::MonotonicDuration period);
uavcan::MonotonicDuration getStatusPublishingPeriod() const;
void setStatusPublicationPeriod(uavcan::MonotonicDuration period);
uavcan::MonotonicDuration getStatusPublicationPeriod() const;
/**
* Local node status code control.
@@ -92,6 +95,15 @@ public:
void setStatusCritical() { setStatusCode(protocol::NodeStatus::STATUS_CRITICAL); }
void setStatusOffline() { setStatusCode(protocol::NodeStatus::STATUS_OFFLINE); }
/**
* Local node vendor-specific status code control.
*/
void setVendorSpecificStatusCode(VendorSpecificStatusCode code);
VendorSpecificStatusCode getVendorSpecificStatusCode() const
{
return node_info_.status.vendor_specific_status_code;
}
/**
* Local node name control.
* Can be set only once before the provider is started.
@@ -6,7 +6,7 @@
#define UAVCAN_PROTOCOL_PARAM_SERVER_HPP_INCLUDED
#include <uavcan/protocol/param/GetSet.hpp>
#include <uavcan/protocol/param/SaveErase.hpp>
#include <uavcan/protocol/param/ExecuteOpcode.hpp>
#include <uavcan/node/service_server.hpp>
#include <uavcan/util/method_binder.hpp>
@@ -19,33 +19,35 @@ namespace uavcan
class UAVCAN_EXPORT IParamManager
{
public:
typedef typename StorageType<typename protocol::param::GetSet::Response::FieldTypes::name>::Type ParamName;
typedef typename StorageType<typename protocol::param::GetSet::Request::FieldTypes::index>::Type ParamIndex;
typedef protocol::param::Value ParamValue;
typedef typename StorageType<typename protocol::param::GetSet::Response::FieldTypes::name>::Type Name;
typedef typename StorageType<typename protocol::param::GetSet::Request::FieldTypes::index>::Type Index;
typedef protocol::param::Value Value;
typedef protocol::param::NumericValue NumericValue;
virtual ~IParamManager() { }
/**
* Copy the parameter name to @ref out_name if it exists, otherwise do nothing.
*/
virtual void getParamNameByIndex(ParamIndex index, ParamName& out_name) const = 0;
virtual void getParamNameByIndex(Index index, Name& out_name) const = 0;
/**
* Assign by name if exists.
*/
virtual void assignParamValue(const ParamName& name, const ParamValue& value) = 0;
virtual void assignParamValue(const Name& name, const Value& value) = 0;
/**
* Read by name if exists, otherwise do nothing.
*/
virtual void readParamValue(const ParamName& name, ParamValue& out_value) const = 0;
virtual void readParamValue(const Name& name, Value& out_value) const = 0;
/**
* Read param's default/max/min if available.
* Note that min/max are only applicable to numeric params.
* Implementation is optional.
*/
virtual void readParamDefaultMaxMin(const ParamName& name, ParamValue& out_default,
ParamValue& out_max, ParamValue& out_min) const
virtual void readParamDefaultMaxMin(const Name& name, Value& out_default,
NumericValue& out_max, NumericValue& out_min) const
{
(void)name;
(void)out_default;
@@ -64,6 +66,22 @@ public:
* @return Negative if failed.
*/
virtual int eraseAllParams() = 0;
/**
* Convenience methods that can be used to check if a param value is empty.
*/
static bool isValueEmpty(const Value& val)
{
return val.value_bool.empty() &&
val.value_int.empty() &&
val.value_float.empty() &&
val.value_string.empty();
}
static bool isValueEmpty(const NumericValue& val)
{
return val.value_int.empty() &&
val.value_float.empty();
}
};
/**
@@ -75,19 +93,18 @@ class UAVCAN_EXPORT ParamServer
typedef MethodBinder<ParamServer*, void (ParamServer::*)(const protocol::param::GetSet::Request&,
protocol::param::GetSet::Response&)> GetSetCallback;
typedef MethodBinder<ParamServer*, void (ParamServer::*)(const protocol::param::SaveErase::Request&,
protocol::param::SaveErase::Response&)> SaveEraseCallback;
typedef MethodBinder<ParamServer*,
void (ParamServer::*)(const protocol::param::ExecuteOpcode::Request&,
protocol::param::ExecuteOpcode::Response&)> ExecuteOpcodeCallback;
ServiceServer<protocol::param::GetSet, GetSetCallback> get_set_srv_;
ServiceServer<protocol::param::SaveErase, SaveEraseCallback> save_erase_srv_;
ServiceServer<protocol::param::ExecuteOpcode, ExecuteOpcodeCallback> save_erase_srv_;
IParamManager* manager_;
static bool isValueNonEmpty(const protocol::param::Value& value);
void handleGetSet(const protocol::param::GetSet::Request& request, protocol::param::GetSet::Response& response);
void handleSaveErase(const protocol::param::SaveErase::Request& request,
protocol::param::SaveErase::Response& response);
void handleExecuteOpcode(const protocol::param::ExecuteOpcode::Request& request,
protocol::param::ExecuteOpcode::Response& response);
public:
explicit ParamServer(INode& node)
+85
View File
@@ -0,0 +1,85 @@
/*
* Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
*/
#ifndef UAVCAN_STD_HPP_INCLUDED
#define UAVCAN_STD_HPP_INCLUDED
#include <uavcan/build_config.hpp>
#include <cstdarg>
#if !defined(UAVCAN_CPP_VERSION) || !defined(UAVCAN_CPP11)
# error UAVCAN_CPP_VERSION
#endif
#if UAVCAN_CPP_VERSION >= UAVCAN_CPP11
# include <cstdint>
# include <cstdio>
namespace uavcan
{
typedef std::uint8_t uint8_t;
typedef std::uint16_t uint16_t;
typedef std::uint32_t uint32_t;
typedef std::uint64_t uint64_t;
typedef std::int8_t int8_t;
typedef std::int16_t int16_t;
typedef std::int32_t int32_t;
typedef std::int64_t int64_t;
}
#else
# include <stdint.h> // Standard integer types from C library
# include <stdio.h> // vsnprintf() from the C library
namespace uavcan
{
typedef ::uint8_t uint8_t;
typedef ::uint16_t uint16_t;
typedef ::uint32_t uint32_t;
typedef ::uint64_t uint64_t;
typedef ::int8_t int8_t;
typedef ::int16_t int16_t;
typedef ::int32_t int32_t;
typedef ::int64_t int64_t;
}
#endif
namespace uavcan
{
/**
* Wrapper over the standard snprintf(). This wrapper is needed because different standards and different
* implementations of C++ do not agree whether snprintf() should be defined in std:: or in ::. The solution
* is to use 'using namespace std' hack inside the wrapper, so the compiler will be able to pick whatever
* definition is available in the standard library. Alternatively, the user's application can provide a
* custom implementation of uavcan::snprintf().
*/
#if __GNUC__
__attribute__ ((format(printf, 3, 4)))
#endif
extern int snprintf(char* out, std::size_t maxlen, const char* format, ...);
#if !UAVCAN_USE_EXTERNAL_SNPRINTF
inline int snprintf(char* out, std::size_t maxlen, const char* format, ...)
{
using namespace std; // This way we can pull vsnprintf() either from std:: or from ::.
va_list args;
va_start(args, format);
const int return_value = vsnprintf(out, maxlen, format, args);
va_end(args);
return return_value;
}
#endif
}
#endif // UAVCAN_STD_HPP_INCLUDED
-57
View File
@@ -1,57 +0,0 @@
/*
* Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
*/
#ifndef UAVCAN_STDINT_HPP_INCLUDED
#define UAVCAN_STDINT_HPP_INCLUDED
#include <uavcan/build_config.hpp>
#if !defined(UAVCAN_CPP_VERSION) || !defined(UAVCAN_CPP11)
# error UAVCAN_CPP_VERSION
#endif
#if UAVCAN_CPP_VERSION >= UAVCAN_CPP11
# include <cstdint>
namespace uavcan
{
typedef std::uint8_t uint8_t;
typedef std::uint16_t uint16_t;
typedef std::uint32_t uint32_t;
typedef std::uint64_t uint64_t;
typedef std::int8_t int8_t;
typedef std::int16_t int16_t;
typedef std::int32_t int32_t;
typedef std::int64_t int64_t;
}
#else
/*
* C++03 doesn't define standard integer types, so we pull it from the C library as a workaround.
*/
# include <stdint.h>
namespace uavcan
{
typedef ::uint8_t uint8_t;
typedef ::uint16_t uint16_t;
typedef ::uint32_t uint32_t;
typedef ::uint64_t uint64_t;
typedef ::int8_t int8_t;
typedef ::int16_t int16_t;
typedef ::int32_t int32_t;
typedef ::int64_t int64_t;
}
#endif
#endif // UAVCAN_STDINT_HPP_INCLUDED
+1 -3
View File
@@ -6,7 +6,7 @@
#define UAVCAN_TIME_HPP_INCLUDED
#include <cstdio>
#include <uavcan/stdint.hpp>
#include <uavcan/std.hpp>
#include <uavcan/build_config.hpp>
#include <uavcan/util/templates.hpp>
#include <uavcan/Timestamp.hpp>
@@ -223,7 +223,6 @@ const unsigned TimeBase<T, D>::StringBufSize;
template <typename D>
void DurationBase<D>::toString(char buf[StringBufSize]) const
{
using namespace std; // For snprintf()
char* ptr = buf;
if (isNegative())
{
@@ -238,7 +237,6 @@ void DurationBase<D>::toString(char buf[StringBufSize]) const
template <typename T, typename D>
void TimeBase<T, D>::toString(char buf[StringBufSize]) const
{
using namespace std; // For snprintf()
(void)snprintf(buf, StringBufSize, "%llu.%06lu",
static_cast<unsigned long long>(toUSec() / 1000000UL),
static_cast<unsigned long>(toUSec() % 1000000UL));
@@ -6,7 +6,7 @@
#define UAVCAN_TRANSPORT_ABSTRACT_TRANSFER_BUFFER_HPP_INCLUDED
#include <uavcan/build_config.hpp>
#include <uavcan/stdint.hpp>
#include <uavcan/std.hpp>
namespace uavcan
{
@@ -8,7 +8,7 @@
#include <cassert>
#include <uavcan/error.hpp>
#include <uavcan/stdint.hpp>
#include <uavcan/std.hpp>
#include <uavcan/util/linked_list.hpp>
#include <uavcan/dynamic_memory.hpp>
#include <uavcan/build_config.hpp>
+1 -1
View File
@@ -6,7 +6,7 @@
#define UAVCAN_TRANSPORT_CRC_HPP_INCLUDED
#include <cassert>
#include <uavcan/stdint.hpp>
#include <uavcan/std.hpp>
#include <uavcan/build_config.hpp>
namespace uavcan
@@ -7,7 +7,7 @@
#include <cassert>
#include <uavcan/error.hpp>
#include <uavcan/stdint.hpp>
#include <uavcan/std.hpp>
#include <uavcan/build_config.hpp>
#include <uavcan/transport/perf_counter.hpp>
#include <uavcan/transport/transfer_listener.hpp>
@@ -6,7 +6,7 @@
#define UAVCAN_TRANSPORT_OUTGOING_TRANSFER_REGISTRY_HPP_INCLUDED
#include <cassert>
#include <uavcan/stdint.hpp>
#include <uavcan/std.hpp>
#include <uavcan/build_config.hpp>
#include <uavcan/util/map.hpp>
#include <uavcan/debug.hpp>
@@ -5,7 +5,7 @@
#ifndef UAVCAN_TRANSPORT_PERF_COUNTER_HPP_INCLUDED
#define UAVCAN_TRANSPORT_PERF_COUNTER_HPP_INCLUDED
#include <uavcan/stdint.hpp>
#include <uavcan/std.hpp>
#include <uavcan/build_config.hpp>
namespace uavcan
@@ -7,7 +7,7 @@
#include <cassert>
#include <uavcan/build_config.hpp>
#include <uavcan/stdint.hpp>
#include <uavcan/std.hpp>
namespace uavcan
{
@@ -5,7 +5,7 @@
#ifndef UAVCAN_TRANSPORT_TRANSFER_BUFFER_HPP_INCLUDED
#define UAVCAN_TRANSPORT_TRANSFER_BUFFER_HPP_INCLUDED
#include <uavcan/stdint.hpp>
#include <uavcan/std.hpp>
#include <uavcan/error.hpp>
#include <uavcan/transport/frame.hpp>
#include <uavcan/transport/abstract_transfer_buffer.hpp>
@@ -7,7 +7,7 @@
#include <cassert>
#include <uavcan/error.hpp>
#include <uavcan/stdint.hpp>
#include <uavcan/std.hpp>
#include <uavcan/transport/transfer_receiver.hpp>
#include <uavcan/transport/perf_counter.hpp>
#include <uavcan/util/linked_list.hpp>
@@ -470,6 +470,20 @@ inline bool isInfinity(T arg)
#endif
}
/**
* Replacement for std::isfinite().
* Note that direct float comparison (==, !=) is intentionally avoided.
*/
template <typename T>
inline bool isFinite(T arg)
{
#if UAVCAN_CPP_VERSION >= UAVCAN_CPP11
return std::isfinite(arg);
#else
return !isNaN(arg) && !isInfinity(arg);
#endif
}
/**
* Replacement for std::signbit().
* Note that direct float comparison (==, !=) is intentionally avoided.