mirror of https://github.com/ARMmbed/mbed-os.git
This is the initial version of stats implementation in network layer.
SocketStats Class is added to collect and provide the statistics information. In this phase only socket information is collected and max sockets that can be recorded at any time are configurable through 'MBED_CONF_NSAPI_SOCKET_STATS_MAX_COUNT' Network statistics can be enabled through a macro MBED_NW_STATS_ENABLED More information on design is captured in #8743pull/8592/head
parent
d5da9eb636
commit
09b4bc07ce
|
@ -26,6 +26,7 @@
|
|||
#include "rtos/EventFlags.h"
|
||||
#include "Callback.h"
|
||||
#include "mbed_toolchain.h"
|
||||
#include "SocketStats.h"
|
||||
|
||||
/** Socket implementation that uses IP network stack.
|
||||
* Not to be directly used by applications. Cannot be directly instantiated.
|
||||
|
@ -176,6 +177,7 @@ protected:
|
|||
static const int FINISHED_FLAG = 0x3u;
|
||||
|
||||
friend class DTLSSocket; // Allow DTLSSocket::connect() to do name resolution on the _stack
|
||||
SocketStats _socket_stats;
|
||||
|
||||
#endif //!defined(DOXYGEN_ONLY)
|
||||
};
|
||||
|
|
|
@ -0,0 +1,163 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2018 ARM Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "SocketStats.h"
|
||||
#include "platform/mbed_error.h"
|
||||
#include "platform/mbed_assert.h"
|
||||
#ifdef MBED_CONF_RTOS_PRESENT
|
||||
#include "rtos/Kernel.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(MBED_NW_STATS_ENABLED)
|
||||
SingletonPtr<PlatformMutex> SocketStats::_mutex;
|
||||
mbed_stats_socket_t SocketStats::_stats[MBED_CONF_NSAPI_SOCKET_STATS_MAX_COUNT] = {0};
|
||||
uint32_t SocketStats::_size = 0;
|
||||
|
||||
int SocketStats::get_entry_position(const Socket *const reference_id)
|
||||
{
|
||||
_mutex->lock();
|
||||
for (uint32_t j = 0; j < _size; j++) {
|
||||
if (_stats[j].reference_id == reference_id) {
|
||||
return j;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
size_t SocketStats::mbed_stats_socket_get_each(mbed_stats_socket_t *stats, size_t count)
|
||||
{
|
||||
MBED_ASSERT(stats != NULL);
|
||||
size_t i = 0;
|
||||
#if defined(MBED_NW_STATS_ENABLED)
|
||||
memset(stats, 0, count * sizeof(mbed_stats_socket_t));
|
||||
_mutex->lock();
|
||||
for (uint32_t j = 0; j < count; j++) {
|
||||
if (_stats[j].reference_id) {
|
||||
memcpy(&stats[i], &_stats[j], sizeof(mbed_stats_socket_t));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
_mutex->unlock();
|
||||
#endif
|
||||
return i;
|
||||
}
|
||||
|
||||
SocketStats::SocketStats()
|
||||
{
|
||||
}
|
||||
|
||||
void SocketStats::stats_new_socket_entry(const Socket *const reference_id)
|
||||
{
|
||||
#if defined(MBED_NW_STATS_ENABLED)
|
||||
_mutex->lock();
|
||||
if (get_entry_position(reference_id) >= 0) {
|
||||
// Duplicate entry
|
||||
MBED_WARNING1(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STATS, MBED_ERROR_CODE_INVALID_INDEX), "Duplicate socket Reference ID ", reference_id);
|
||||
} else if (_size <= MBED_CONF_NSAPI_SOCKET_STATS_MAX_COUNT) {
|
||||
// Add new entry
|
||||
_stats[_size].reference_id = (Socket *)reference_id;
|
||||
_size++;
|
||||
} else {
|
||||
int position = -1;
|
||||
uint64_t oldest_time = 0;
|
||||
// Determine which entry in the list shall be over-written
|
||||
for (uint32_t j = 0; j < MBED_CONF_NSAPI_SOCKET_STATS_MAX_COUNT; j++) {
|
||||
if (SOCK_CLOSED == _stats[j].state) {
|
||||
if ((0 == oldest_time) || (oldest_time < _stats[j].last_change_tick)) {
|
||||
oldest_time = _stats[j].last_change_tick;
|
||||
position = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (-1 == position) {
|
||||
MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STATS, MBED_ERROR_CODE_OUT_OF_RESOURCES), "List full with all open sockets");
|
||||
}
|
||||
memset(&_stats[position], 0, sizeof(mbed_stats_socket_t));
|
||||
_stats[position].reference_id = (Socket *)reference_id;
|
||||
}
|
||||
_mutex->unlock();
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
void SocketStats::stats_update_socket_state(const Socket *const reference_id, socket_state state)
|
||||
{
|
||||
#if defined(MBED_NW_STATS_ENABLED)
|
||||
_mutex->lock();
|
||||
int position = get_entry_position(reference_id);
|
||||
if (position >= 0) {
|
||||
_stats[position].state = state;
|
||||
#ifdef MBED_CONF_RTOS_PRESENT
|
||||
_stats[position].last_change_tick = rtos::Kernel::get_ms_count();
|
||||
#endif
|
||||
}
|
||||
_mutex->unlock();
|
||||
#endif
|
||||
}
|
||||
|
||||
void SocketStats::stats_update_peer(const Socket *const reference_id, const SocketAddress &peer)
|
||||
{
|
||||
#if defined(MBED_NW_STATS_ENABLED)
|
||||
_mutex->lock();
|
||||
int position = get_entry_position(reference_id);
|
||||
if (position >= 0) {
|
||||
if (!_stats[position].peer) {
|
||||
_stats[position].peer = peer;
|
||||
}
|
||||
}
|
||||
_mutex->unlock();
|
||||
#endif
|
||||
}
|
||||
|
||||
void SocketStats::stats_update_proto(const Socket *const reference_id, nsapi_protocol_t proto)
|
||||
{
|
||||
#if defined(MBED_NW_STATS_ENABLED)
|
||||
_mutex->lock();
|
||||
int position = get_entry_position(reference_id);
|
||||
if (position >= 0) {
|
||||
_stats[position].proto = proto;
|
||||
}
|
||||
_mutex->unlock();
|
||||
#endif
|
||||
}
|
||||
|
||||
void SocketStats::stats_update_sent_bytes(const Socket *const reference_id, size_t sent_bytes)
|
||||
{
|
||||
#if defined(MBED_NW_STATS_ENABLED)
|
||||
_mutex->lock();
|
||||
int position = get_entry_position(reference_id);
|
||||
if (position >= 0) {
|
||||
_stats[position].sent_bytes += sent_bytes;
|
||||
}
|
||||
_mutex->unlock();
|
||||
#endif
|
||||
}
|
||||
|
||||
void SocketStats::stats_update_recv_bytes(const Socket *const reference_id, size_t recv_bytes)
|
||||
{
|
||||
#if defined(MBED_NW_STATS_ENABLED)
|
||||
_mutex->lock();
|
||||
int position = get_entry_position(reference_id);
|
||||
if (position >= 0) {
|
||||
_stats[position].recv_bytes += recv_bytes;
|
||||
}
|
||||
_mutex->unlock();
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2018 ARM Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SOCKET_STATS_H
|
||||
#define SOCKET_STATS_H
|
||||
|
||||
#include "platform/mbed_stats.h"
|
||||
#include "platform/SingletonPtr.h"
|
||||
#include "platform/PlatformMutex.h"
|
||||
#include "netsocket/Socket.h"
|
||||
#include "SocketAddress.h"
|
||||
#include "hal/ticker_api.h"
|
||||
|
||||
#ifndef MBED_CONF_NSAPI_SOCKET_STATS_MAX_COUNT
|
||||
#define MBED_CONF_NSAPI_SOCKET_STATS_MAX_COUNT 10
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
SOCK_CLOSED, /**< Socket is closed and does not exist anymore in the system */
|
||||
SOCK_OPEN, /**< Socket is open, but not associated to any peer address */
|
||||
SOCK_CONNECTED, /**< Socket is associated to peer address, either by connect() or sendto()/recvfrom() calls */
|
||||
SOCK_LISTEN, /**< Socket is listening for incoming connections */
|
||||
}socket_state;
|
||||
|
||||
typedef struct {
|
||||
Socket *reference_id; /**< Used for identifying socket */
|
||||
SocketAddress peer; /**< Last associated peername of this socket (Destination address) */
|
||||
socket_state state; /**< State of this socket */
|
||||
nsapi_protocol_t proto; /**< Specifies a protocol used with socket */
|
||||
size_t sent_bytes; /**< Data sent through this socket */
|
||||
size_t recv_bytes; /**< Data received through this socket */
|
||||
us_timestamp_t last_change_tick;/**< osKernelGetTick() when state last changed */
|
||||
} mbed_stats_socket_t;
|
||||
|
||||
/** SocketStats class
|
||||
*
|
||||
*
|
||||
*/
|
||||
class SocketStats
|
||||
{
|
||||
public:
|
||||
SocketStats();
|
||||
virtual ~SocketStats()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the passed array of structures with the socket statistics for each created socket.
|
||||
*
|
||||
* @param stats A pointer to an array of mbed_stats_socket_t structures to fill
|
||||
* @param count The number of mbed_stats_socket_t structures in the provided array
|
||||
* @return The number of mbed_stats_socket_t structures that have been filled.
|
||||
* If the number of sockets on the system is less than or equal to count,
|
||||
* it will equal the number of sockets created (active / closed).
|
||||
* If the number of sockets on the system is greater than count,
|
||||
* it will equal count.
|
||||
*/
|
||||
static size_t mbed_stats_socket_get_each(mbed_stats_socket_t *stats, size_t count);
|
||||
|
||||
/** Add entry of newly created socket in statistics array.
|
||||
@Note: Entry in the array will be maintained even after socket is closed.
|
||||
It will be over-written for closed sockets when socket entries in
|
||||
`MBED_CONF_NSAPI_SOCKET_STATS_MAX_COUNT` exceed.
|
||||
*/
|
||||
void stats_new_socket_entry(const Socket *const reference_id);
|
||||
|
||||
/** Updates the state of socket and along with that records tick_last_change */
|
||||
void stats_update_socket_state(const Socket *const reference_id, socket_state state);
|
||||
|
||||
/** Update the peer information of the socket */
|
||||
void stats_update_peer(const Socket *const reference_id, const SocketAddress &peer);
|
||||
|
||||
/** Update socket protocol */
|
||||
void stats_update_proto(const Socket *const reference_id, nsapi_protocol_t proto);
|
||||
|
||||
/** Update bytes sent on socket, which is cumulative count per socket */
|
||||
void stats_update_sent_bytes(const Socket *const reference_id, size_t sent_bytes);
|
||||
|
||||
/** Update bytes received on socket, which is cumulative count per socket */
|
||||
void stats_update_recv_bytes(const Socket *const reference_id, size_t recv_bytes);
|
||||
|
||||
#if defined(MBED_NW_STATS_ENABLED)
|
||||
private:
|
||||
static mbed_stats_socket_t _stats[MBED_CONF_NSAPI_SOCKET_STATS_MAX_COUNT];
|
||||
static SingletonPtr<PlatformMutex> _mutex;
|
||||
static uint32_t _size;
|
||||
|
||||
/** Internal function to scan the array and get position of element in the list.
|
||||
This API locks the mutex and next API updating the entry in array
|
||||
should release the lock */
|
||||
int get_entry_position(const Socket *const reference_id);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
|
@ -20,10 +20,12 @@ using mbed::Callback;
|
|||
|
||||
TCPServer::TCPServer()
|
||||
{
|
||||
_socket_stats.stats_new_socket_entry(this);
|
||||
}
|
||||
|
||||
TCPServer::~TCPServer()
|
||||
{
|
||||
_socket_stats.stats_update_socket_state(this, SOCK_CLOSED);
|
||||
}
|
||||
|
||||
nsapi_error_t TCPServer::accept(TCPSocket *connection, SocketAddress *address)
|
||||
|
@ -52,7 +54,8 @@ nsapi_error_t TCPServer::accept(TCPSocket *connection, SocketAddress *address)
|
|||
connection->_socket = socket;
|
||||
connection->_event = Callback<void()>(connection, &TCPSocket::event);
|
||||
_stack->socket_attach(socket, &Callback<void()>::thunk, &connection->_event);
|
||||
|
||||
_socket_stats.stats_update_peer(this, *address);
|
||||
_socket_stats.stats_update_socket_state(this, SOCK_OPEN);
|
||||
connection->_lock.unlock();
|
||||
break;
|
||||
} else if ((_timeout == 0) || (ret != NSAPI_ERROR_WOULD_BLOCK)) {
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
TCPSocket::TCPSocket()
|
||||
{
|
||||
_socket_stats.stats_new_socket_entry(this);
|
||||
}
|
||||
|
||||
TCPSocket::TCPSocket(TCPSocket *parent, nsapi_socket_t socket, SocketAddress address)
|
||||
|
@ -28,17 +29,26 @@ TCPSocket::TCPSocket(TCPSocket *parent, nsapi_socket_t socket, SocketAddress add
|
|||
_stack = parent->_stack;
|
||||
_factory_allocated = true;
|
||||
_remote_peer = address;
|
||||
|
||||
_socket_stats.stats_new_socket_entry(this);
|
||||
_event = mbed::Callback<void()>(this, &TCPSocket::event);
|
||||
_stack->socket_attach(socket, &mbed::Callback<void()>::thunk, &_event);
|
||||
}
|
||||
|
||||
TCPSocket::~TCPSocket()
|
||||
{
|
||||
_socket_stats.stats_update_socket_state(this, SOCK_CLOSED);
|
||||
}
|
||||
|
||||
nsapi_error_t TCPSocket::close()
|
||||
{
|
||||
_socket_stats.stats_update_socket_state(this, SOCK_CLOSED);
|
||||
return InternetSocket::close();
|
||||
}
|
||||
|
||||
nsapi_protocol_t TCPSocket::get_proto()
|
||||
{
|
||||
_socket_stats.stats_update_proto(this, NSAPI_TCP);
|
||||
_socket_stats.stats_update_socket_state(this, SOCK_OPEN);
|
||||
return NSAPI_TCP;
|
||||
}
|
||||
|
||||
|
@ -64,6 +74,7 @@ nsapi_error_t TCPSocket::connect(const SocketAddress &address)
|
|||
_pending = 0;
|
||||
ret = _stack->socket_connect(_socket, address);
|
||||
if ((_timeout == 0) || !(ret == NSAPI_ERROR_IN_PROGRESS || ret == NSAPI_ERROR_ALREADY)) {
|
||||
_socket_stats.stats_update_socket_state(this, SOCK_CONNECTED);
|
||||
break;
|
||||
} else {
|
||||
blocking_connect_in_progress = true;
|
||||
|
@ -89,11 +100,13 @@ nsapi_error_t TCPSocket::connect(const SocketAddress &address)
|
|||
|
||||
/* Non-blocking connect gives "EISCONN" once done - convert to OK for blocking mode if we became connected during this call */
|
||||
if (ret == NSAPI_ERROR_IS_CONNECTED && blocking_connect_in_progress) {
|
||||
_socket_stats.stats_update_socket_state(this, SOCK_CONNECTED);
|
||||
ret = NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
if (ret == NSAPI_ERROR_OK || ret == NSAPI_ERROR_IN_PROGRESS) {
|
||||
_remote_peer = address;
|
||||
_socket_stats.stats_update_peer(this, _remote_peer);
|
||||
}
|
||||
|
||||
_lock.unlock();
|
||||
|
@ -178,6 +191,7 @@ nsapi_size_or_error_t TCPSocket::send(const void *data, nsapi_size_t size)
|
|||
} else if (written == 0) {
|
||||
return NSAPI_ERROR_WOULD_BLOCK;
|
||||
} else {
|
||||
_socket_stats.stats_update_sent_bytes(this, written);
|
||||
return written;
|
||||
}
|
||||
}
|
||||
|
@ -208,6 +222,7 @@ nsapi_size_or_error_t TCPSocket::recv(void *data, nsapi_size_t size)
|
|||
_pending = 0;
|
||||
ret = _stack->socket_recv(_socket, data, size);
|
||||
if ((_timeout == 0) || (ret != NSAPI_ERROR_WOULD_BLOCK)) {
|
||||
_socket_stats.stats_update_recv_bytes(this, ret);
|
||||
break;
|
||||
} else {
|
||||
uint32_t flag;
|
||||
|
@ -252,6 +267,9 @@ nsapi_error_t TCPSocket::listen(int backlog)
|
|||
ret = NSAPI_ERROR_NO_SOCKET;
|
||||
} else {
|
||||
ret = _stack->socket_listen(_socket, backlog);
|
||||
if (NSAPI_ERROR_OK == ret) {
|
||||
_socket_stats.stats_update_socket_state(this, SOCK_LISTEN);
|
||||
}
|
||||
}
|
||||
|
||||
_lock.unlock();
|
||||
|
|
|
@ -61,6 +61,15 @@ public:
|
|||
*/
|
||||
virtual ~TCPSocket();
|
||||
|
||||
/** Close the socket.
|
||||
*
|
||||
* Closes any open connection and deallocates any memory associated
|
||||
* with the socket. Called from destructor if socket is not closed.
|
||||
*
|
||||
* @return NSAPI_ERROR_OK on success, negative error code on failure
|
||||
*/
|
||||
virtual nsapi_error_t close();
|
||||
|
||||
/** Override multicast functions to return error for TCP
|
||||
*
|
||||
*/
|
||||
|
|
|
@ -20,20 +20,32 @@
|
|||
|
||||
UDPSocket::UDPSocket()
|
||||
{
|
||||
_socket_stats.stats_new_socket_entry(this);
|
||||
}
|
||||
|
||||
UDPSocket::~UDPSocket()
|
||||
{
|
||||
_socket_stats.stats_update_socket_state(this, SOCK_CLOSED);
|
||||
}
|
||||
|
||||
nsapi_error_t UDPSocket::close()
|
||||
{
|
||||
_socket_stats.stats_update_socket_state(this, SOCK_CLOSED);
|
||||
return InternetSocket::close();
|
||||
}
|
||||
|
||||
nsapi_protocol_t UDPSocket::get_proto()
|
||||
{
|
||||
_socket_stats.stats_update_proto(this, NSAPI_UDP);
|
||||
_socket_stats.stats_update_socket_state(this, SOCK_OPEN);
|
||||
return NSAPI_UDP;
|
||||
}
|
||||
|
||||
nsapi_error_t UDPSocket::connect(const SocketAddress &address)
|
||||
{
|
||||
_remote_peer = address;
|
||||
_socket_stats.stats_update_peer(this, _remote_peer);
|
||||
_socket_stats.stats_update_socket_state(this, SOCK_CONNECTED);
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
|
@ -57,7 +69,10 @@ nsapi_size_or_error_t UDPSocket::sendto(const SocketAddress &address, const void
|
|||
nsapi_size_or_error_t ret;
|
||||
|
||||
_writers++;
|
||||
|
||||
if (_socket) {
|
||||
_socket_stats.stats_update_socket_state(this, SOCK_OPEN);
|
||||
_socket_stats.stats_update_peer(this, address);
|
||||
}
|
||||
while (true) {
|
||||
if (!_socket) {
|
||||
ret = NSAPI_ERROR_NO_SOCKET;
|
||||
|
@ -67,6 +82,7 @@ nsapi_size_or_error_t UDPSocket::sendto(const SocketAddress &address, const void
|
|||
_pending = 0;
|
||||
nsapi_size_or_error_t sent = _stack->socket_sendto(_socket, address, data, size);
|
||||
if ((0 == _timeout) || (NSAPI_ERROR_WOULD_BLOCK != sent)) {
|
||||
_socket_stats.stats_update_sent_bytes(this, sent);
|
||||
ret = sent;
|
||||
break;
|
||||
} else {
|
||||
|
@ -114,6 +130,9 @@ nsapi_size_or_error_t UDPSocket::recvfrom(SocketAddress *address, void *buffer,
|
|||
|
||||
_readers++;
|
||||
|
||||
if (_socket) {
|
||||
_socket_stats.stats_update_socket_state(this, SOCK_OPEN);
|
||||
}
|
||||
while (true) {
|
||||
if (!_socket) {
|
||||
ret = NSAPI_ERROR_NO_SOCKET;
|
||||
|
@ -122,12 +141,15 @@ nsapi_size_or_error_t UDPSocket::recvfrom(SocketAddress *address, void *buffer,
|
|||
|
||||
_pending = 0;
|
||||
nsapi_size_or_error_t recv = _stack->socket_recvfrom(_socket, address, buffer, size);
|
||||
|
||||
|
||||
// Filter incomming packets using connected peer address
|
||||
if (recv >= 0 && _remote_peer && _remote_peer != *address) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (recv > 0) {
|
||||
_socket_stats.stats_update_recv_bytes(this, recv);
|
||||
}
|
||||
_socket_stats.stats_update_peer(this, _remote_peer);
|
||||
// Non-blocking sockets always return. Blocking only returns when success or errors other than WOULD_BLOCK
|
||||
if ((0 == _timeout) || (NSAPI_ERROR_WOULD_BLOCK != recv)) {
|
||||
ret = recv;
|
||||
|
|
|
@ -59,6 +59,15 @@ public:
|
|||
*/
|
||||
virtual ~UDPSocket();
|
||||
|
||||
/** Close the socket.
|
||||
*
|
||||
* Closes any open connection and deallocates any memory associated
|
||||
* with the socket. Called from destructor if socket is not closed.
|
||||
*
|
||||
* @return NSAPI_ERROR_OK on success, negative error code on failure
|
||||
*/
|
||||
virtual nsapi_error_t close();
|
||||
|
||||
/** Send data to the specified host and port.
|
||||
*
|
||||
* By default, sendto blocks until data is sent. If socket is set to
|
||||
|
|
|
@ -254,6 +254,7 @@ typedef enum _mbed_error_type_t {
|
|||
MBED_MODULE_DRIVER_USB 21 USB Driver
|
||||
MBED_MODULE_TARGET_SDK 22 SDK
|
||||
MBED_MODULE_BLE 23 BLE
|
||||
MBED_MODULE_NETWORK_STATS 24 Network Statistics
|
||||
|
||||
MBED_MODULE_UNKNOWN 255 Unknown module
|
||||
\endverbatim
|
||||
|
@ -284,6 +285,7 @@ typedef enum _mbed_module_type {
|
|||
MBED_MODULE_DRIVER_USB,
|
||||
MBED_MODULE_TARGET_SDK,
|
||||
MBED_MODULE_BLE,
|
||||
MBED_MODULE_NETWORK_STATS,
|
||||
/* Add More entities here as required */
|
||||
|
||||
MBED_MODULE_UNKNOWN = 255,
|
||||
|
|
|
@ -36,6 +36,7 @@ extern "C" {
|
|||
#define MBED_CPU_STATS_ENABLED 1
|
||||
#define MBED_HEAP_STATS_ENABLED 1
|
||||
#define MBED_THREAD_STATS_ENABLED 1
|
||||
#define MBED_NW_STATS_ENABLED 1
|
||||
#endif
|
||||
|
||||
/** Maximum memory regions reported by mbed-os memory statistics */
|
||||
|
|
Loading…
Reference in New Issue