[修改] 增加freeRTOS
1. 版本FreeRTOSv202212.01,命名为kernel;
This commit is contained in:
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V3.1.0
|
||||
* Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/*
|
||||
* dump_packets.c
|
||||
* Used in the PC/Win project to dump Ethernet packets, along with some description.
|
||||
*/
|
||||
|
||||
#ifndef DUMP_PACKETS_H
|
||||
|
||||
|
||||
#define DUMP_PACKETS_H
|
||||
|
||||
#ifndef dumpMAX_DUMP_ENTRIES
|
||||
#define dumpMAX_DUMP_ENTRIES 16
|
||||
#endif
|
||||
|
||||
#define flag_ICMP4 0x00000001UL
|
||||
#define flag_ICMP6 0x00000002UL
|
||||
#define flag_UDP 0x00000004UL
|
||||
#define flag_TCP 0x00000008UL
|
||||
#define flag_DNS 0x00000010UL
|
||||
#define flag_REPLY 0x00000020UL
|
||||
#define flag_REQUEST 0x00000040UL
|
||||
#define flag_SYN 0x00000080UL
|
||||
#define flag_FIN 0x00000100UL
|
||||
#define flag_RST 0x00000200UL
|
||||
#define flag_ACK 0x00000400UL
|
||||
#define flag_IN 0x00000800UL
|
||||
#define flag_OUT 0x00001000UL
|
||||
#define flag_FRAME_ARP 0x00002000UL
|
||||
#define flag_ARP 0x00004000UL
|
||||
#define flag_UNKNOWN 0x00008000UL
|
||||
#define flag_FRAME_4 0x00010000UL
|
||||
#define flag_FRAME_6 0x00020000UL
|
||||
#define flag_Unknown_FRAME 0x00040000UL
|
||||
|
||||
/**
|
||||
* Structure to hold information about one dump entry.
|
||||
*/
|
||||
typedef struct xDumpEntry
|
||||
{
|
||||
uint32_t ulMask; /**< The mask of the entry */
|
||||
size_t uxMax; /**< The max value of the entry */
|
||||
size_t uxCount; /**< The count of the entry */
|
||||
} DumpEntry_t;
|
||||
|
||||
/**
|
||||
* Structure to hold information of all the entries in this data dump.
|
||||
*/
|
||||
typedef struct xDumpEntries
|
||||
{
|
||||
size_t uxEntryCount; /**< The number of entries*/
|
||||
DumpEntry_t xEntries[ dumpMAX_DUMP_ENTRIES ]; /**< Array of struct for all the entries */
|
||||
} DumpEntries_t;
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
#if ( ipconfigUSE_DUMP_PACKETS != 0 )
|
||||
|
||||
extern void dump_packet_init( const char * pcFileName,
|
||||
DumpEntries_t * pxEntries );
|
||||
#define iptraceDUMP_INIT( pcFileName, pxEntries ) \
|
||||
dump_packet_init( pcFileName, pxEntries )
|
||||
|
||||
extern void dump_packet( const uint8_t * pucBuffer,
|
||||
size_t uxLength,
|
||||
BaseType_t xIncoming );
|
||||
#define iptraceDUMP_PACKET( pucBuffer, uxLength, xIncoming ) \
|
||||
dump_packet( pucBuffer, uxLength, xIncoming )
|
||||
|
||||
#endif /* if ( ipconfigUSE_DUMP_PACKETS != 0 ) */
|
||||
|
||||
#endif /* ifndef DUMP_PACKETS_H */
|
||||
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V3.1.0
|
||||
* Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/*
|
||||
* tcp_mem_stats.h
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TCP_MEM_STATS_H
|
||||
|
||||
#define TCP_MEM_STATS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum xTCP_MEMORY
|
||||
{
|
||||
tcpSOCKET_TCP,
|
||||
tcpSOCKET_UDP,
|
||||
tcpSOCKET_SET,
|
||||
tcpSEMAPHORE,
|
||||
tcpRX_STREAM_BUFFER,
|
||||
tcpTX_STREAM_BUFFER,
|
||||
tcpNETWORK_BUFFER,
|
||||
} TCP_MEMORY_t;
|
||||
|
||||
#if ( ipconfigUSE_TCP_MEM_STATS != 0 )
|
||||
|
||||
void vTCPMemStatCreate( TCP_MEMORY_t xMemType,
|
||||
void * pxObject,
|
||||
size_t uxSize );
|
||||
|
||||
void vTCPMemStatDelete( void * pxObject );
|
||||
|
||||
void vTCPMemStatClose( void );
|
||||
|
||||
#define iptraceMEM_STATS_CREATE( xMemType, pxObject, uxSize ) \
|
||||
vTCPMemStatCreate( xMemType, pxObject, uxSize )
|
||||
|
||||
#define iptraceMEM_STATS_DELETE( pxObject ) \
|
||||
vTCPMemStatDelete( pxObject )
|
||||
|
||||
#define iptraceMEM_STATS_CLOSE() \
|
||||
vTCPMemStatClose()
|
||||
#else /* if ( ipconfigUSE_TCP_MEM_STATS != 0 ) */
|
||||
|
||||
/* The header file 'IPTraceMacroDefaults.h' will define the default empty macro's. */
|
||||
|
||||
#endif /* ipconfigUSE_TCP_MEM_STATS != 0 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* TCP_MEM_STATS_H */
|
||||
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V3.1.0
|
||||
* Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/*
|
||||
* TCP_NETSTAT.c
|
||||
* Some function to get a list of sockets and active port numbers.
|
||||
*/
|
||||
#ifndef TCP_NETSTAT_H
|
||||
|
||||
#define TCP_NETSTAT_H
|
||||
|
||||
#ifndef nstatMAX_UDP_PORTS
|
||||
#define nstatMAX_UDP_PORTS 12U
|
||||
#endif
|
||||
|
||||
#ifndef nstatMAX_TCP_PORTS
|
||||
#define nstatMAX_TCP_PORTS 12U
|
||||
#endif
|
||||
|
||||
#ifndef nstatMAX_UDP_SOCKETS
|
||||
#define nstatMAX_UDP_SOCKETS 12U
|
||||
#endif
|
||||
|
||||
#ifndef nstatMAX_TCP_SOCKETS
|
||||
#define nstatMAX_TCP_SOCKETS 12U
|
||||
#endif
|
||||
|
||||
typedef struct xIOCounters
|
||||
{
|
||||
size_t uxByteCount;
|
||||
size_t uxPacketCount;
|
||||
} IOCounters_t;
|
||||
|
||||
extern IOCounters_t xInputCounters, xOutputCounters;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t usUDPPortList[ nstatMAX_UDP_PORTS ];
|
||||
size_t uxCount;
|
||||
} UDPPortList_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t usTCPPortList[ nstatMAX_TCP_PORTS ];
|
||||
size_t uxCount;
|
||||
} TCPPortList_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t usLocalPort;
|
||||
uint16_t usRemotePort;
|
||||
uint32_t ulRemoteIP;
|
||||
} TCPEntry_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
TCPEntry_t xTCPList[ nstatMAX_TCP_SOCKETS ];
|
||||
size_t uxCount;
|
||||
} TCPSocketList_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t usLocalPort;
|
||||
} UDPEntry_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UDPEntry_t xUDPList[ nstatMAX_UDP_SOCKETS ];
|
||||
size_t uxCount;
|
||||
} UDPSocketList_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UDPPortList_t xUDPPortList;
|
||||
TCPPortList_t xTCPPortList;
|
||||
TCPSocketList_t xTCPSocketList;
|
||||
UDPSocketList_t xUDPSocketList;
|
||||
IOCounters_t xInput;
|
||||
IOCounters_t xOutput;
|
||||
} MetricsType_t;
|
||||
|
||||
extern BaseType_t vGetMetrics( MetricsType_t * pxMetrics );
|
||||
extern void vShowMetrics( const MetricsType_t * pxMetrics );
|
||||
|
||||
|
||||
#define iptraceNETWORK_INTERFACE_INPUT( uxDataLength, pucEthernetBuffer ) \
|
||||
xInputCounters.uxByteCount += uxDataLength; \
|
||||
xInputCounters.uxPacketCount++;
|
||||
|
||||
#define iptraceNETWORK_INTERFACE_OUTPUT( uxDataLength, pucEthernetBuffer ) \
|
||||
xOutputCounters.uxByteCount += uxDataLength; \
|
||||
xOutputCounters.uxPacketCount++;
|
||||
|
||||
|
||||
#endif /* TCP_NETSTAT_H */
|
||||
@ -0,0 +1,706 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V3.1.0
|
||||
* Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/*
|
||||
* tcp_dump_packets.c
|
||||
* Used in the PC/Win project to dump Ethernet packets, along with some description.
|
||||
* See tools/tcp_dump_packets.md for further description.
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include <FreeRTOS.h>
|
||||
#include "task.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
#include "FreeRTOS_Stream_Buffer.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
|
||||
#if ( ipconfigUSE_DUMP_PACKETS != 0 )
|
||||
|
||||
#include "tcp_dump_packets.h"
|
||||
|
||||
/* The priority of the windows thread. */
|
||||
#define dumpPROCESS_THREAD_PRIORITY THREAD_PRIORITY_NORMAL
|
||||
|
||||
/* There is a stream buffer between the FreeRTOS tasks sending network packets,
|
||||
* and the Windows thread that writes these packets to disk. The macro 'dumpITEM_COUNT'
|
||||
* determines the number of full-size packets that can be stored in this stream buffer. */
|
||||
#ifndef dumpITEM_COUNT
|
||||
#define dumpITEM_COUNT 32
|
||||
#endif
|
||||
|
||||
/* Packets are written in hex notation, no more than 16 bytes on a row. */
|
||||
#ifndef dumpBYTES_PER_ROW
|
||||
#define dumpBYTES_PER_ROW 16
|
||||
#endif
|
||||
|
||||
/* The TCP port number reserved for a DNS server. */
|
||||
#define dnsDNS_PORT 0x0035u
|
||||
|
||||
/* Some const values describing the 'flags' in a TCP packet. */
|
||||
#define tcpTCP_FLAG_FIN 0x0001u /* No more data from sender */
|
||||
#define tcpTCP_FLAG_SYN 0x0002u /* Synchronize sequence numbers */
|
||||
#define tcpTCP_FLAG_RST 0x0004u /* Reset the connection */
|
||||
#define tcpTCP_FLAG_PSH 0x0008u /* Push function: please push buffered data to the recv application */
|
||||
#define tcpTCP_FLAG_ACK 0x0010u /* Acknowledgment field is significant */
|
||||
|
||||
/* A macro to add a type, both as a numeric value, as well as a string. */
|
||||
#define ADD_TYPE( FLAGS ) \
|
||||
vAddType( flag_ ## FLAGS, # FLAGS )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static char pcTypeString[ 255 ];
|
||||
static uint32_t ulTypeMask;
|
||||
|
||||
/* The name of the C source file to be written. */
|
||||
static char pcCodeFileName[ MAX_PATH ];
|
||||
|
||||
/* The name of the header file to be written. */
|
||||
static char pcHeaderFileName[ MAX_PATH ];
|
||||
|
||||
/* A stream buffer between the FreeRTOS tasks and the Windows thread. */
|
||||
static StreamBuffer_t * xPacketBuffer;
|
||||
|
||||
/* A process handle of the Windows thread. */
|
||||
static HANDLE pvProcessHandle;
|
||||
|
||||
static UBaseType_t uxNextPacketNumber;
|
||||
static BaseType_t xFirstPacket = 1;
|
||||
|
||||
/* Boolean 'xDumpingReady' becomes true once all desired packet have been collected.
|
||||
* Further packets will be dropped (ignored). */
|
||||
static volatile BaseType_t xDumpingReady = pdFALSE;
|
||||
|
||||
static DumpEntries_t * pxCurrentEntries;
|
||||
|
||||
static uint16_t usSourcePort;
|
||||
static uint16_t usDestinationPort;
|
||||
|
||||
typedef struct xBufferheader
|
||||
{
|
||||
size_t uxLength;
|
||||
UBaseType_t bIncoming : 1;
|
||||
} Bufferheader_t;
|
||||
|
||||
static DumpEntries_t xExampleEntries =
|
||||
{
|
||||
.uxEntryCount = 4, /* No more than 'dumpMAX_DUMP_ENTRIES' elements. */
|
||||
.xEntries =
|
||||
{
|
||||
{ .ulMask = flag_IN | flag_UDP, .uxMax = 2u },
|
||||
{ .ulMask = flag_IN | flag_ARP, .uxMax = 2u },
|
||||
{ .ulMask = flag_IN | flag_TCP, .uxMax = 5u },
|
||||
{ .ulMask = flag_IN | flag_SYN, .uxMax = 1u },
|
||||
}
|
||||
};
|
||||
|
||||
const char pcHeaderCode[] =
|
||||
"/*\n"
|
||||
" * This file was created automatically by 'dump_packets.c'\n"
|
||||
" */\n"
|
||||
"\n"
|
||||
"/* Standard includes. */\n"
|
||||
"#include <stdio.h>\n"
|
||||
"#include <stdint.h>\n"
|
||||
"#include <stdarg.h>\n"
|
||||
"#include <io.h>\n"
|
||||
"#include <ctype.h>\n"
|
||||
"\n"
|
||||
"/* FreeRTOS includes. */\n"
|
||||
"#include <FreeRTOS.h>\n"
|
||||
"#include <task.h>\n\n"
|
||||
"#include \"%s\"\n\n";
|
||||
|
||||
const char pcHeaderHeader[] =
|
||||
"/*\n"
|
||||
" * This file was created automatically by 'dump_packets.c'\n"
|
||||
" */\n"
|
||||
"\n"
|
||||
"#ifndef PACKET_LIST_H\n\n"
|
||||
"#define PACKET_LIST_H\n\n"
|
||||
"typedef struct xDumpPacket\n"
|
||||
"{\n"
|
||||
" const uint8_t *pucData;\n"
|
||||
" size_t uxLength;\n"
|
||||
" uint32_t ulType;\n"
|
||||
" uint16_t usSource;\n"
|
||||
" uint16_t usDestination;\n"
|
||||
"} DumpPacket_t;\n\n";
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* The Windows thread that actually writes the network packets to a C source and header file. */
|
||||
static DWORD WINAPI prvWritePackets( LPVOID lpParameter );
|
||||
|
||||
static void vAddProtocolTags( uint8_t * pucEthernetBuffer,
|
||||
BaseType_t xIPType );
|
||||
static void vDetermineMessageType( uint8_t * pucBuffer,
|
||||
BaseType_t xIncoming );
|
||||
static void vActualDump( uint8_t * pucBuffer,
|
||||
size_t uxLength,
|
||||
BaseType_t xIncoming );
|
||||
static void vAddType( uint32_t ulFlags,
|
||||
const char * pcFlagName );
|
||||
static void vWriteHeaderFile( void );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void dump_packet_init( const char * pcFileName,
|
||||
DumpEntries_t * pxEntries )
|
||||
{
|
||||
size_t uxIndex;
|
||||
|
||||
snprintf( pcCodeFileName, sizeof pcCodeFileName, "%s.c", pcFileName );
|
||||
snprintf( pcHeaderFileName, sizeof pcHeaderFileName, "%s.h", pcFileName );
|
||||
|
||||
if( pxEntries == NULL )
|
||||
{
|
||||
pxEntries = &( xExampleEntries );
|
||||
}
|
||||
|
||||
configASSERT( pxEntries->uxEntryCount > 0 );
|
||||
configASSERT( pxEntries->uxEntryCount <= dumpMAX_DUMP_ENTRIES );
|
||||
|
||||
for( uxIndex = 0; uxIndex < pxEntries->uxEntryCount; uxIndex++ )
|
||||
{
|
||||
pxEntries->xEntries[ uxIndex ].uxCount = 0;
|
||||
}
|
||||
|
||||
pxCurrentEntries = pxEntries;
|
||||
|
||||
if( xPacketBuffer == NULL )
|
||||
{
|
||||
size_t uxLength, uxSize;
|
||||
|
||||
/* Enough space for e.g. 32 buffers and length words. */
|
||||
uxLength = dumpITEM_COUNT * ( sizeof( void * ) + ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER );
|
||||
uxSize = ( sizeof( *xPacketBuffer ) + uxLength ) - sizeof( xPacketBuffer->ucArray );
|
||||
xPacketBuffer = ( StreamBuffer_t * ) pvPortMalloc( uxSize );
|
||||
configASSERT( xPacketBuffer != NULL );
|
||||
vStreamBufferClear( xPacketBuffer );
|
||||
xPacketBuffer->LENGTH = uxLength;
|
||||
}
|
||||
|
||||
if( pvProcessHandle == NULL )
|
||||
{
|
||||
pvProcessHandle = CreateThread( NULL, 0, prvWritePackets, NULL, CREATE_SUSPENDED, NULL );
|
||||
|
||||
if( pvProcessHandle != NULL )
|
||||
{
|
||||
SetThreadPriority( pvProcessHandle, dumpPROCESS_THREAD_PRIORITY );
|
||||
SetThreadPriorityBoost( pvProcessHandle, TRUE );
|
||||
SetThreadAffinityMask( pvProcessHandle, 0x0E );
|
||||
ResumeThread( pvProcessHandle );
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void dump_packet( const uint8_t * pucBuffer,
|
||||
size_t uxLength,
|
||||
BaseType_t xIncoming )
|
||||
{
|
||||
/* This function shall be called from a normal FreeRTOS task only. */
|
||||
if( xPacketBuffer != NULL )
|
||||
{
|
||||
if( xDumpingReady == pdFALSE )
|
||||
{
|
||||
size_t uxSpace = uxStreamBufferGetSpace( xPacketBuffer );
|
||||
size_t uxNeeded = uxLength + sizeof( size_t );
|
||||
|
||||
if( uxNeeded < uxSpace )
|
||||
{
|
||||
Bufferheader_t xheader;
|
||||
|
||||
xheader.uxLength = uxLength;
|
||||
xheader.bIncoming = xIncoming;
|
||||
uxStreamBufferAdd( xPacketBuffer, 0u, ( const uint8_t * ) &( xheader ), sizeof( xheader ) );
|
||||
uxStreamBufferAdd( xPacketBuffer, 0u, pucBuffer, uxLength );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Drop this packet. */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The Windows thread 'prvWritePackets()' had received enough packets.
|
||||
* The packet buffer may be freed. */
|
||||
vPortFree( xPacketBuffer );
|
||||
xPacketBuffer = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static DWORD WINAPI prvWritePackets( LPVOID lpParameter )
|
||||
{
|
||||
/* This is a Windows thread, not a FreeRTOS task. FreeRTOS API's may not be called. */
|
||||
for( ; ; )
|
||||
{
|
||||
Sleep( 100 );
|
||||
|
||||
while( ( xPacketBuffer != NULL ) && ( xDumpingReady == pdFALSE ) )
|
||||
{
|
||||
Bufferheader_t xHeader;
|
||||
size_t uxBytes = uxStreamBufferGetSize( xPacketBuffer );
|
||||
|
||||
if( uxBytes <= sizeof( xHeader ) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
/* Peek the number of bytes available. */
|
||||
uxStreamBufferGet( xPacketBuffer, 0u, ( uint8_t * ) &( xHeader ), sizeof( xHeader ), pdTRUE );
|
||||
|
||||
if( uxBytes >= sizeof( xHeader ) + xHeader.uxLength )
|
||||
{
|
||||
}
|
||||
|
||||
{
|
||||
size_t xBytesRead;
|
||||
uint8_t pcBuffer[ ipconfigNETWORK_MTU ];
|
||||
size_t xActualCount;
|
||||
|
||||
uxStreamBufferGet( xPacketBuffer, 0u, NULL, sizeof( xHeader ), pdFALSE );
|
||||
xActualCount = uxStreamBufferGet( xPacketBuffer, 0u, pcBuffer, xHeader.uxLength, pdFALSE );
|
||||
vActualDump( pcBuffer, xActualCount, xHeader.bIncoming );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static int _fprintf( FILE * pxHandle,
|
||||
const char * pcFormat,
|
||||
... )
|
||||
{
|
||||
char pcString[ 255 ];
|
||||
BaseType_t iCount;
|
||||
|
||||
va_list args;
|
||||
|
||||
va_start( args, pcFormat );
|
||||
iCount = vsnprintf( pcString, sizeof pcString, pcFormat, args );
|
||||
va_end( args );
|
||||
fwrite( pcString, 1u, iCount, pxHandle );
|
||||
|
||||
return iCount;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void vWriteHeaderFile( void )
|
||||
{
|
||||
FILE * outfile;
|
||||
|
||||
outfile = fopen( pcHeaderFileName, "w" );
|
||||
|
||||
if( outfile != NULL )
|
||||
{
|
||||
fwrite( pcHeaderHeader, 1u, sizeof( pcHeaderHeader ) - 1u, outfile );
|
||||
_fprintf( outfile, "#define dumpPACKET_COUNT %lu\n\n",
|
||||
( uxNextPacketNumber < 1u ) ? 1u : uxNextPacketNumber );
|
||||
_fprintf( outfile, "extern DumpPacket_t *xPacketList[ dumpPACKET_COUNT ];\n\n" );
|
||||
_fprintf( outfile, "#endif PACKET_LIST_H\n" );
|
||||
|
||||
fclose( outfile );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void vAddType( uint32_t ulFlags,
|
||||
const char * pcFlagName )
|
||||
{
|
||||
size_t uxLength = strlen( pcTypeString );
|
||||
char pcString[ 64 ];
|
||||
BaseType_t iCount;
|
||||
|
||||
ulTypeMask |= ulFlags;
|
||||
|
||||
if( uxLength == 0 )
|
||||
{
|
||||
snprintf( pcTypeString, sizeof pcTypeString, "%s", pcFlagName );
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf( pcTypeString + uxLength, sizeof pcTypeString - 1, " | %s", pcFlagName );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void vAddProtocolTags( uint8_t * pucEthernetBuffer,
|
||||
BaseType_t xIPType )
|
||||
{
|
||||
ProtocolHeaders_t * pxProtocolHeaders;
|
||||
|
||||
#if ( ipconfigUSE_IPv6 != 0 )
|
||||
const IPHeader_IPv6_t * pxIPHeader_IPv6;
|
||||
#endif
|
||||
UBaseType_t uxHeaderLength;
|
||||
uint8_t ucProtocol;
|
||||
IPPacket_t * pxIPPacket;
|
||||
IPHeader_t * pxIPHeader;
|
||||
|
||||
pxIPPacket = ( IPPacket_t * ) pucEthernetBuffer;
|
||||
pxIPHeader = &( pxIPPacket->xIPHeader );
|
||||
#if ( ipconfigUSE_IPv6 != 0 )
|
||||
pxIPHeader_IPv6 = ( const IPHeader_IPv6_t * ) &( pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER ] );
|
||||
|
||||
if( pxIPPacket->xEthernetHeader.usFrameType == ipIPv6_FRAME_TYPE )
|
||||
{
|
||||
uxHeaderLength = ipSIZE_OF_IPv6_HEADER;
|
||||
ucProtocol = pxIPHeader_IPv6->ucNextHeader;
|
||||
pxProtocolHeaders = ( ProtocolHeaders_t * ) &( pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv6_HEADER ] );
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
size_t uxLength = ( size_t ) pxIPHeader->ucVersionHeaderLength;
|
||||
|
||||
/* Check if the IP headers are acceptable and if it has our destination.
|
||||
* The lowest four bits of 'ucVersionHeaderLength' indicate the IP-header
|
||||
* length in multiples of 4. */
|
||||
uxHeaderLength = ( size_t ) ( ( uxLength & 0x0Fu ) << 2 );
|
||||
ucProtocol = pxIPPacket->xIPHeader.ucProtocol;
|
||||
pxProtocolHeaders = ( ProtocolHeaders_t * ) &( pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + uxHeaderLength ] );
|
||||
}
|
||||
|
||||
switch( ucProtocol )
|
||||
{
|
||||
case ipPROTOCOL_ICMP:
|
||||
ADD_TYPE( ICMP4 );
|
||||
break;
|
||||
|
||||
#if ( ipconfigUSE_IPv6 != 0 )
|
||||
case ipPROTOCOL_ICMP_IPv6:
|
||||
ADD_TYPE( ICMP6 );
|
||||
break;
|
||||
#endif
|
||||
|
||||
case ipPROTOCOL_UDP:
|
||||
ADD_TYPE( UDP );
|
||||
usSourcePort = pxProtocolHeaders->xUDPHeader.usSourcePort;
|
||||
usDestinationPort = pxProtocolHeaders->xUDPHeader.usDestinationPort;
|
||||
|
||||
if( usSourcePort == FreeRTOS_htons( dnsDNS_PORT ) )
|
||||
{
|
||||
ADD_TYPE( DNS );
|
||||
ADD_TYPE( REPLY );
|
||||
}
|
||||
else if( usDestinationPort == FreeRTOS_htons( dnsDNS_PORT ) )
|
||||
{
|
||||
ADD_TYPE( DNS );
|
||||
ADD_TYPE( REQUEST );
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
#if ipconfigUSE_TCP == 1
|
||||
case ipPROTOCOL_TCP:
|
||||
ADD_TYPE( TCP );
|
||||
usSourcePort = pxProtocolHeaders->xTCPHeader.usSourcePort;
|
||||
usDestinationPort = pxProtocolHeaders->xTCPHeader.usDestinationPort;
|
||||
|
||||
if( ( pxProtocolHeaders->xTCPHeader.ucTCPFlags & tcpTCP_FLAG_SYN ) != 0u )
|
||||
{
|
||||
ADD_TYPE( SYN );
|
||||
}
|
||||
|
||||
if( ( pxProtocolHeaders->xTCPHeader.ucTCPFlags & tcpTCP_FLAG_FIN ) != 0u )
|
||||
{
|
||||
ADD_TYPE( FIN );
|
||||
}
|
||||
|
||||
if( ( pxProtocolHeaders->xTCPHeader.ucTCPFlags & tcpTCP_FLAG_RST ) != 0u )
|
||||
{
|
||||
ADD_TYPE( RST );
|
||||
}
|
||||
|
||||
if( ( pxProtocolHeaders->xTCPHeader.ucTCPFlags & tcpTCP_FLAG_ACK ) != 0u )
|
||||
{
|
||||
ADD_TYPE( ACK );
|
||||
}
|
||||
break;
|
||||
#endif /* if ipconfigUSE_TCP == 1 */
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void vDetermineMessageType( uint8_t * pucBuffer,
|
||||
BaseType_t xIncoming )
|
||||
{
|
||||
EthernetHeader_t * pxEthernetHeader;
|
||||
|
||||
if( xIncoming != 0 )
|
||||
{
|
||||
ADD_TYPE( IN );
|
||||
}
|
||||
else
|
||||
{
|
||||
ADD_TYPE( OUT );
|
||||
}
|
||||
|
||||
pxEthernetHeader = ( EthernetHeader_t * ) pucBuffer;
|
||||
|
||||
/* Interpret the received Ethernet packet. */
|
||||
switch( pxEthernetHeader->usFrameType )
|
||||
{
|
||||
case ipARP_FRAME_TYPE:
|
||||
{
|
||||
ARPPacket_t * pxARPFrame;
|
||||
ARPHeader_t * pxARPHeader;
|
||||
|
||||
/* The Ethernet frame contains an ARP packet. */
|
||||
ADD_TYPE( FRAME_ARP );
|
||||
pxARPFrame = ( ARPPacket_t * ) pucBuffer;
|
||||
pxARPHeader = &( pxARPFrame->xARPHeader );
|
||||
ADD_TYPE( ARP );
|
||||
|
||||
switch( pxARPHeader->usOperation )
|
||||
{
|
||||
case ipARP_REQUEST:
|
||||
ADD_TYPE( REQUEST );
|
||||
break;
|
||||
|
||||
case ipARP_REPLY:
|
||||
ADD_TYPE( REPLY );
|
||||
break;
|
||||
|
||||
default:
|
||||
ADD_TYPE( UNKNOWN );
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ipIPv4_FRAME_TYPE:
|
||||
ADD_TYPE( FRAME_4 );
|
||||
vAddProtocolTags( pucBuffer, 4 );
|
||||
break;
|
||||
|
||||
#if ( ipconfigUSE_IPv6 != 0 )
|
||||
case ipIPv6_FRAME_TYPE:
|
||||
ADD_TYPE( FRAME_6 );
|
||||
vAddProtocolTags( pucBuffer, 6 );
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
/* No other packet types are handled. Nothing to do. */
|
||||
ADD_TYPE( Unknown_FRAME );
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void vActualDump( uint8_t * pucBuffer,
|
||||
size_t uxLength,
|
||||
BaseType_t xIncoming )
|
||||
{
|
||||
char pcString[ 513 ];
|
||||
size_t uxOffset;
|
||||
size_t uxIndex;
|
||||
size_t uxCompleteCount = 0;
|
||||
BaseType_t xUseIt = pdFALSE;
|
||||
|
||||
usSourcePort = 0u;
|
||||
usDestinationPort = 0u;
|
||||
pcTypeString[ 0 ] = 0;
|
||||
ulTypeMask = 0uL;
|
||||
|
||||
if( pxCurrentEntries == NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
vDetermineMessageType( pucBuffer, xIncoming );
|
||||
|
||||
for( uxIndex = 0; uxIndex < pxCurrentEntries->uxEntryCount; uxIndex++ )
|
||||
{
|
||||
if( pxCurrentEntries->xEntries[ uxIndex ].uxCount < pxCurrentEntries->xEntries[ uxIndex ].uxMax )
|
||||
{
|
||||
uint32_t ulMask = pxCurrentEntries->xEntries[ uxIndex ].ulMask;
|
||||
|
||||
if( ( ulMask & ulTypeMask ) == ulMask )
|
||||
{
|
||||
pxCurrentEntries->xEntries[ uxIndex ].uxCount++;
|
||||
xUseIt = pdTRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uxCompleteCount++;
|
||||
}
|
||||
}
|
||||
|
||||
FreeRTOS_printf( ( "prvWritePackets: done %d/%d : (%d,%d) (%d,%d) (%d,%d) (%d,%d)\n",
|
||||
uxCompleteCount,
|
||||
pxCurrentEntries->uxEntryCount,
|
||||
pxCurrentEntries->xEntries[ 0 ].uxCount, pxCurrentEntries->xEntries[ 0 ].uxMax,
|
||||
pxCurrentEntries->xEntries[ 1 ].uxCount, pxCurrentEntries->xEntries[ 1 ].uxMax,
|
||||
pxCurrentEntries->xEntries[ 2 ].uxCount, pxCurrentEntries->xEntries[ 2 ].uxMax,
|
||||
pxCurrentEntries->xEntries[ 3 ].uxCount, pxCurrentEntries->xEntries[ 3 ].uxMax ) );
|
||||
|
||||
if( uxCompleteCount >= pxCurrentEntries->uxEntryCount )
|
||||
{
|
||||
FreeRTOS_printf( ( "prvWritePackets: all %lu packets have been collected\n", pxCurrentEntries->uxEntryCount ) );
|
||||
|
||||
if( pxCurrentEntries != NULL )
|
||||
{
|
||||
FILE * outfile = fopen( pcCodeFileName, ( xFirstPacket != 0 ) ? "w" : "a+" );
|
||||
|
||||
if( outfile == NULL )
|
||||
{
|
||||
FreeRTOS_printf( ( "Can not create '%s'\n", pcCodeFileName ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Create a list with pointers to each network packet.
|
||||
* DumpPacket_t *xPacketList[ dumpPACKET_COUNT ] =
|
||||
* {
|
||||
* &xPacket_0000,
|
||||
* &xPacket_0001,
|
||||
* &xPacket_0002,
|
||||
* &xPacket_0003,
|
||||
* }
|
||||
*/
|
||||
_fprintf( outfile, "\nDumpPacket_t *xPacketList[ dumpPACKET_COUNT ] =\n{\n" );
|
||||
|
||||
for( uxIndex = 0; uxIndex < uxNextPacketNumber; uxIndex++ )
|
||||
{
|
||||
_fprintf( outfile, "\t&xPacket_%04lu,\n", uxIndex );
|
||||
}
|
||||
|
||||
_fprintf( outfile, "};\n" );
|
||||
fclose( outfile );
|
||||
vWriteHeaderFile();
|
||||
}
|
||||
|
||||
pxCurrentEntries = NULL;
|
||||
|
||||
/* Tell the thread and the function dump_packet() that packet
|
||||
* dumping is ready. */
|
||||
xDumpingReady = pdTRUE;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if( xUseIt == pdFALSE )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
printf( "prvWritePackets: Read %lu bytes, type %s\n", uxLength, pcTypeString );
|
||||
|
||||
FILE * outfile = fopen( pcCodeFileName, ( xFirstPacket != 0 ) ? "w" : "a+" );
|
||||
|
||||
if( outfile == NULL )
|
||||
{
|
||||
FreeRTOS_printf( ( "Can not create '%s'\n", pcCodeFileName ) );
|
||||
return;
|
||||
}
|
||||
|
||||
if( xFirstPacket != 0 )
|
||||
{
|
||||
char * pcPtr;
|
||||
size_t xLength;
|
||||
|
||||
vWriteHeaderFile( pcHeaderFileName );
|
||||
xLength = snprintf( pcString, sizeof pcString, pcHeaderCode, pcHeaderFileName );
|
||||
fwrite( pcString, 1u, xLength, outfile );
|
||||
xFirstPacket = pdFALSE;
|
||||
}
|
||||
|
||||
_fprintf( outfile, "\n/* Packet_%04d */\n", uxNextPacketNumber );
|
||||
_fprintf( outfile, "uint8_t ucPacket_%04lx[ %lu ] =\n{\n", uxNextPacketNumber, uxLength );
|
||||
|
||||
for( uxOffset = 0u; uxOffset < uxLength; )
|
||||
{
|
||||
size_t uxCurLength = 0u;
|
||||
size_t uxLast = uxOffset + dumpBYTES_PER_ROW;
|
||||
BaseType_t xFirst = pdTRUE;
|
||||
|
||||
if( uxLast > uxLength )
|
||||
{
|
||||
uxLast = uxLength;
|
||||
}
|
||||
|
||||
while( uxOffset < uxLast )
|
||||
{
|
||||
uxCurLength += snprintf( pcString + uxCurLength, sizeof pcString - uxCurLength, "%s0x%02x",
|
||||
( uxCurLength == 0 ) ? "\t" : ", ", pucBuffer[ uxOffset ] );
|
||||
uxOffset++;
|
||||
}
|
||||
|
||||
if( uxCurLength != 0u )
|
||||
{
|
||||
uxCurLength += snprintf( pcString + uxCurLength, sizeof pcString - uxCurLength, "%s\n",
|
||||
( uxOffset == uxLength ) ? "\n};" : "," );
|
||||
fwrite( pcString, 1u, uxCurLength, outfile );
|
||||
}
|
||||
}
|
||||
|
||||
_fprintf( outfile, "\n" );
|
||||
|
||||
_fprintf( outfile,
|
||||
"DumpPacket_t xPacket_%04lx =\n{\n"
|
||||
"\t.pucData = ucPacket_%04lx,\n"
|
||||
"\t.uxLength = %lu,\n"
|
||||
"\t.ulType = 0x%lX, /* %s */\n",
|
||||
uxNextPacketNumber, uxNextPacketNumber, uxLength, ulTypeMask, pcTypeString );
|
||||
|
||||
if( usSourcePort != 0u )
|
||||
{
|
||||
_fprintf( outfile,
|
||||
"\t.usSource = %u,\n", FreeRTOS_ntohs( usSourcePort ) );
|
||||
}
|
||||
|
||||
if( usSourcePort != 0u )
|
||||
{
|
||||
_fprintf( outfile,
|
||||
"\t.usDestination = %u,\n", FreeRTOS_ntohs( usDestinationPort ) );
|
||||
}
|
||||
|
||||
_fprintf( outfile,
|
||||
"};\n"
|
||||
"/*-----------------------------------------------------------*/\n\n" );
|
||||
fclose( outfile );
|
||||
uxNextPacketNumber++;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#endif /* ( ipconfigUSE_DUMP_PACKETS != 0 ) */
|
||||
@ -0,0 +1,72 @@
|
||||
tcp_dump_packets.c dumps network packets in a C source file.
|
||||
|
||||
It is written to be added to the "pc" project ( Windows simulator ). It uses the file system to write 2 C source files:
|
||||
|
||||
PacketList.c
|
||||
PacketList.h
|
||||
|
||||
How to include 'tcp_dump_packets' into a project:
|
||||
|
||||
● Make sure that tools/tcp_dump_packets.c is added to the source files
|
||||
● See if Network Interface has been adapted to call:
|
||||
`iptraceDUMP_PACKET( ucBuffer, xLength, pdTRUE ); /* Incoming packet. */`
|
||||
`iptraceDUMP_PACKET( ucBuffer, xLength, pdFALSE ); /* Outgoing packet. */`
|
||||
● Once the network is up, call `dump_packet_init()` with a file name and a pointer to
|
||||
`DumpEntries_t`, which contains the requirements. For instance like this:
|
||||
static DumpEntries_t xExampleEntries = {
|
||||
.uxEntryCount = 4, /* No more than 'dumpMAX_DUMP_ENTRIES' elements. */
|
||||
.xEntries = {
|
||||
{ .ulMask = flag_IN | flag_UDP, .uxMax = 2u },
|
||||
{ .ulMask = flag_IN | flag_ARP, .uxMax = 2u },
|
||||
{ .ulMask = flag_IN | flag_TCP, .uxMax = 5u },
|
||||
{ .ulMask = flag_IN | flag_SYN, .uxMax = 1u },
|
||||
}
|
||||
};
|
||||
● Add the following lines to FreeRTOSIPConfig.h :
|
||||
#define ipconfigUSE_DUMP_PACKETS ( 1 )
|
||||
#include "../tools/tcp_dump_packets.h"
|
||||
|
||||
Later on, the module can disabled by simply setting `ipconfigUSE_DUMP_PACKETS` to `0`.
|
||||
|
||||
Here is some contents of the output file:
|
||||
|
||||
/* Packet_0001 */
|
||||
uint8_t ucPacket_0001[ 60 ] =
|
||||
{
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x74, 0xb5, 0x7e, 0xf0, 0x47, 0xee, 0x08, 0x06, 0x00, 0x01,
|
||||
0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0x74, 0xb5, 0x7e, 0xf0, 0x47, 0xee, 0xc0, 0xa8, 0x02, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x02, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
DumpPacket_t xPacket_0001 =
|
||||
{
|
||||
.pucData = ucPacket_0001,
|
||||
.uxLength = 60,
|
||||
.ulType = 0x6840, /* IN | FRAME_ARP | ARP | REQUEST */
|
||||
};
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
tcp_dump_packets has an enum of all possible properties of network packets:
|
||||
ICMP4, ICMP6, UDP, TCP, DNS, REPLY, REQUEST, SYN,
|
||||
FIN, RST, ACK, IN, OUT, ARP, FRAME_ARP, FRAME_4, and FRAME_6
|
||||
|
||||
Each property is defined as a bit so they can be combined as in:
|
||||
.ulType = 0x6840, /* IN | FRAME_ARP | ARP | REQUEST */
|
||||
|
||||
Finishing: when there are enough packets of all required types, an array is added to the C-source output:
|
||||
|
||||
DumpPacket_t *xPacketList[ dumpPACKET_COUNT ] =
|
||||
{
|
||||
&xPacket_0000,
|
||||
&xPacket_0001,
|
||||
&xPacket_0002,
|
||||
&xPacket_0003,
|
||||
&xPacket_0004,
|
||||
&xPacket_0005,
|
||||
&xPacket_0006,
|
||||
&xPacket_0007,
|
||||
&xPacket_0008,
|
||||
};
|
||||
|
||||
The new source file PacketList.{c, h} can be used in testing software as sample packets.
|
||||
@ -0,0 +1,465 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V3.1.0
|
||||
* Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/*
|
||||
* tcp_mem_stats.c
|
||||
* Used to create a CSV file with detailed information about the memory usage of FreeRTOS+TCP.
|
||||
* See tools/tcp_mem_stats.md for further description.
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include <FreeRTOS.h>
|
||||
#include "task.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
#include "FreeRTOS_Stream_Buffer.h"
|
||||
#include "FreeRTOS_ARP.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
|
||||
#include "tcp_mem_stats.h"
|
||||
|
||||
#if ( ipconfigUSE_TCP_MEM_STATS != 0 )
|
||||
|
||||
#ifndef ipconfigTCP_MEM_STATS_MAX_ALLOCATION
|
||||
|
||||
/* Define the maximum number of objects ( memory allocations by
|
||||
* the IP-stack ) that will be recorded. */
|
||||
#define ipconfigTCP_MEM_STATS_MAX_ALLOCATION 128u
|
||||
|
||||
/* If you don't want to see this pragma message, you can either
|
||||
* remove it or define 'ipconfigTCP_MEM_STATS_MAX_ALLOCATION' in
|
||||
* your freeRTOSIPConfig.h. */
|
||||
#pragma message ("ipconfigTCP_MEM_STATS_MAX_ALLOCATION undefined?")
|
||||
#endif
|
||||
|
||||
/* When a streambuffer is allocated, 4 extra bytes will be reserved. */
|
||||
|
||||
#define STREAM_BUFFER_ROUNDUP_BYTES 4
|
||||
|
||||
#define STATS_PRINTF( MSG ) \
|
||||
xCurrentLine++; \
|
||||
configPRINTF( MSG )
|
||||
|
||||
#define ETH_MAX_PACKET_SIZE ( ( ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER + ipBUFFER_PADDING + 31 ) & ~0x1FuL )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Objects are allocated and deleted. This structure stores the type
|
||||
* and the size of the object. */
|
||||
typedef struct xTCP_ALLOCATION
|
||||
{
|
||||
TCP_MEMORY_t xMemType;
|
||||
void * pxObject;
|
||||
UBaseType_t uxNumber;
|
||||
size_t uxSize;
|
||||
} TCP_ALLOCATION_t;
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
static void vWriteHeader( void );
|
||||
|
||||
static size_t uxCurrentMallocSize;
|
||||
static TCP_ALLOCATION_t xAllocations[ ipconfigTCP_MEM_STATS_MAX_ALLOCATION ];
|
||||
static size_t uxAllocationCount;
|
||||
static BaseType_t xFirstItem = pdTRUE;
|
||||
UBaseType_t uxNextObjectNumber;
|
||||
static BaseType_t xCurrentLine = 0;
|
||||
static BaseType_t xFirstDumpLine = 0;
|
||||
static BaseType_t xLastHeaderLineNr = 0;
|
||||
static BaseType_t xLoggingStopped = 0;
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void vAddAllocation( TCP_MEMORY_t xMemType,
|
||||
void * pxObject,
|
||||
size_t uxSize )
|
||||
{
|
||||
size_t uxIndex;
|
||||
|
||||
vTaskSuspendAll();
|
||||
{
|
||||
for( uxIndex = 0; uxIndex < uxAllocationCount; uxIndex++ )
|
||||
{
|
||||
if( xAllocations[ uxIndex ].pxObject == pxObject )
|
||||
{
|
||||
/* Already added, strange. */
|
||||
FreeRTOS_printf( ( "vAddAllocation: Pointer %p already added\n", pxObject ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the object has not been found,
|
||||
* and if there is still space, add the object. */
|
||||
if( ( uxIndex == uxAllocationCount ) &&
|
||||
( uxAllocationCount < ipconfigTCP_MEM_STATS_MAX_ALLOCATION ) )
|
||||
{
|
||||
xAllocations[ uxIndex ].pxObject = pxObject;
|
||||
xAllocations[ uxIndex ].xMemType = xMemType;
|
||||
xAllocations[ uxIndex ].uxSize = uxSize;
|
||||
xAllocations[ uxIndex ].uxNumber = uxNextObjectNumber++;
|
||||
uxAllocationCount++;
|
||||
}
|
||||
}
|
||||
xTaskResumeAll();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static TCP_ALLOCATION_t * pxRemoveAllocation( void * pxObject )
|
||||
{
|
||||
size_t uxSource = 0, uxTarget = 0;
|
||||
static TCP_ALLOCATION_t xAllocation = { 0 };
|
||||
BaseType_t xFound = pdFALSE;
|
||||
TCP_ALLOCATION_t * pxReturn;
|
||||
|
||||
vTaskSuspendAll();
|
||||
{
|
||||
for( ; uxSource < uxAllocationCount; uxSource++ )
|
||||
{
|
||||
if( xAllocations[ uxSource ].pxObject == pxObject )
|
||||
{
|
||||
/* This is entry will be removed. */
|
||||
( void ) memcpy( &( xAllocation ), &( xAllocations[ uxSource ] ), sizeof xAllocation );
|
||||
xFound = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
xAllocations[ uxTarget ] = xAllocations[ uxSource ];
|
||||
uxTarget++;
|
||||
}
|
||||
}
|
||||
|
||||
if( xFound != pdFALSE )
|
||||
{
|
||||
uxAllocationCount--;
|
||||
pxReturn = &( xAllocation );
|
||||
}
|
||||
else
|
||||
{
|
||||
pxReturn = NULL;
|
||||
}
|
||||
}
|
||||
xTaskResumeAll();
|
||||
return pxReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static const char * pcTypeName( TCP_MEMORY_t xMemType )
|
||||
{
|
||||
switch( xMemType )
|
||||
{
|
||||
case tcpSOCKET_TCP:
|
||||
return "TCP-Socket";
|
||||
|
||||
case tcpSOCKET_UDP:
|
||||
return "UDP-Socket";
|
||||
|
||||
case tcpSOCKET_SET:
|
||||
return "SocketSet";
|
||||
|
||||
case tcpSEMAPHORE:
|
||||
return "Semaphore";
|
||||
|
||||
case tcpRX_STREAM_BUFFER:
|
||||
return "RX-Buffer";
|
||||
|
||||
case tcpTX_STREAM_BUFFER:
|
||||
return "TX-Buffer";
|
||||
|
||||
case tcpNETWORK_BUFFER:
|
||||
return "networkBuffer";
|
||||
}
|
||||
|
||||
return "Unknown object";
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void vWriteHeader()
|
||||
{
|
||||
size_t uxPacketSize;
|
||||
size_t uxTXSize;
|
||||
size_t uxStaticSize = 0;
|
||||
BaseType_t xFirstLineNr = 0;
|
||||
|
||||
char pucComment[ 64 ] = "";
|
||||
StreamBuffer_t * pxBuffer = NULL;
|
||||
size_t uxTara = sizeof( *pxBuffer ) - sizeof( pxBuffer->ucArray );
|
||||
|
||||
/* The approximate size of a buffer for a Network Packet. */
|
||||
STATS_PRINTF( ( "TCPMemStat,Some important ipconfig items:\n" ) );
|
||||
STATS_PRINTF( ( "TCPMemStat,ipconfig item,Value,Comment\n" ) );
|
||||
STATS_PRINTF( ( "TCPMemStat,NETWORK_MTU,%u\n", ipconfigNETWORK_MTU ) );
|
||||
STATS_PRINTF( ( "TCPMemStat,TCP_MSS,%u\n", ipconfigTCP_MSS ) );
|
||||
STATS_PRINTF( ( "TCPMemStat,USE_TCP,%u\n", ipconfigUSE_TCP ) );
|
||||
STATS_PRINTF( ( "TCPMemStat,USE_TCP_WIN,%u\n", ipconfigUSE_TCP_WIN ) );
|
||||
|
||||
uxTXSize = ( size_t ) FreeRTOS_round_up( ipconfigTCP_TX_BUFFER_LENGTH, ipconfigTCP_MSS );
|
||||
|
||||
STATS_PRINTF( ( "TCPMemStat,TCP_RX_BUFFER_LENGTH,%u,Plus %u bytes\n", ipconfigTCP_RX_BUFFER_LENGTH, uxTara + STREAM_BUFFER_ROUNDUP_BYTES ) );
|
||||
|
||||
if( uxTXSize > ipconfigTCP_TX_BUFFER_LENGTH )
|
||||
{
|
||||
snprintf( pucComment, sizeof pucComment, ",Rounded up to %u x MSS (plus %u bytes)", uxTXSize / ipconfigTCP_MSS, uxTara + STREAM_BUFFER_ROUNDUP_BYTES );
|
||||
}
|
||||
|
||||
STATS_PRINTF( ( "TCPMemStat,TCP_TX_BUFFER_LENGTH,%u%s\n", ipconfigTCP_TX_BUFFER_LENGTH, pucComment ) );
|
||||
STATS_PRINTF( ( "TCPMemStat,USE_DHCP,%u\n", ipconfigUSE_DHCP ) );
|
||||
|
||||
/*
|
||||
* Start of fixed RAM allocations.
|
||||
*/
|
||||
|
||||
STATS_PRINTF( ( "TCPMemStat,\n" ) );
|
||||
STATS_PRINTF( ( "TCPMemStat,RAM that is always allocated either statically or on the heap:\n" ) );
|
||||
STATS_PRINTF( ( "TCPMemStat,ipconfig item,Value,PerUnit,Total\n" ) );
|
||||
xFirstLineNr = xCurrentLine;
|
||||
|
||||
if( xBufferAllocFixedSize != 0 )
|
||||
{
|
||||
size_t uxBytes;
|
||||
|
||||
/* Using BufferAllocation_1.c */
|
||||
uxPacketSize = ( ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER + ipBUFFER_PADDING + 31 ) & ~0x1FuL;
|
||||
uxBytes = ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS * ( uxPacketSize + sizeof( NetworkBufferDescriptor_t ) );
|
||||
|
||||
STATS_PRINTF( ( "TCPMemStat,NUM_NETWORK_BUFFER_DESCRIPTORS,%u,%u,=B%d*C%d,Descriptors + buffers\n",
|
||||
ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS,
|
||||
uxPacketSize + sizeof( NetworkBufferDescriptor_t ),
|
||||
xCurrentLine,
|
||||
xCurrentLine ) );
|
||||
uxStaticSize += uxBytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t uxBytes;
|
||||
|
||||
/* Using BufferAllocation_2.c */
|
||||
uxBytes = ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS * sizeof( NetworkBufferDescriptor_t );
|
||||
STATS_PRINTF( ( "TCPMemStat,NUM_NETWORK_BUFFER_DESCRIPTORS,%u,%u,=B%d*C%d,Descriptors only\n",
|
||||
ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS,
|
||||
sizeof( NetworkBufferDescriptor_t ),
|
||||
xCurrentLine,
|
||||
xCurrentLine ) );
|
||||
uxStaticSize += uxBytes;
|
||||
}
|
||||
|
||||
{
|
||||
#if ( ipconfigUSE_TCP_WIN != 0 )
|
||||
{
|
||||
STATS_PRINTF( ( "TCPMemStat,TCP_WIN_SEG_COUNT,%u,%u,=B%d*C%d\n",
|
||||
ipconfigTCP_WIN_SEG_COUNT, sizeof( TCPSegment_t ), xCurrentLine, xCurrentLine ) );
|
||||
}
|
||||
#else
|
||||
{
|
||||
STATS_PRINTF( ( "TCPMemStat,TCP_WIN_SEG_COUNT,%u,%u\n", 0, 0 ) );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
{
|
||||
size_t uxBytes;
|
||||
size_t uxEntrySize;
|
||||
|
||||
uxBytes = ipconfigEVENT_QUEUE_LENGTH * sizeof( IPStackEvent_t );
|
||||
STATS_PRINTF( ( "TCPMemStat,EVENT_QUEUE_LENGTH,%u,%u,=B%d*C%d\n",
|
||||
ipconfigEVENT_QUEUE_LENGTH,
|
||||
sizeof( IPStackEvent_t ),
|
||||
xCurrentLine,
|
||||
xCurrentLine ) );
|
||||
uxStaticSize += uxBytes;
|
||||
|
||||
uxBytes = ipconfigIP_TASK_STACK_SIZE_WORDS * sizeof( void * );
|
||||
STATS_PRINTF( ( "TCPMemStat,IP_TASK_STACK_SIZE_WORDS,%u,%u,=B%d*C%d\n",
|
||||
ipconfigIP_TASK_STACK_SIZE_WORDS,
|
||||
sizeof( void * ),
|
||||
xCurrentLine,
|
||||
xCurrentLine ) );
|
||||
uxStaticSize += uxBytes;
|
||||
|
||||
uxBytes = ipconfigARP_CACHE_ENTRIES * sizeof( ARPCacheRow_t );
|
||||
STATS_PRINTF( ( "TCPMemStat,ARP_CACHE_ENTRIES,%u,%u,=B%d*C%d\n",
|
||||
ipconfigARP_CACHE_ENTRIES,
|
||||
sizeof( ARPCacheRow_t ),
|
||||
xCurrentLine,
|
||||
xCurrentLine ) );
|
||||
uxStaticSize += uxBytes;
|
||||
|
||||
#if ( ipconfigUSE_DNS_CACHE == 1 )
|
||||
{
|
||||
uxEntrySize = 3u * sizeof( uint32_t ) + ( ( ipconfigDNS_CACHE_NAME_LENGTH + 3 ) & ~0x3u );
|
||||
STATS_PRINTF( ( "TCPMemStat,DNS_CACHE_ENTRIES,%u,%u,=B%d*C%d\n",
|
||||
ipconfigDNS_CACHE_ENTRIES,
|
||||
uxEntrySize,
|
||||
xCurrentLine,
|
||||
xCurrentLine ) );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* End of fixed RAM allocations.
|
||||
*/
|
||||
if( xBufferAllocFixedSize != 0 )
|
||||
{
|
||||
pucComment[ 0 ] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t uxBytes;
|
||||
|
||||
/* BufferAllocation_2.c uses HEAP to store network packets. */
|
||||
uxPacketSize = ( ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER + ipBUFFER_PADDING + 3 ) & ~0x03uL;
|
||||
uxBytes = ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS * uxPacketSize;
|
||||
STATS_PRINTF( ( "TCPMemStat,Network buffers in HEAP,%u,%u,=B%d*C%d\n",
|
||||
ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS,
|
||||
uxPacketSize,
|
||||
xCurrentLine,
|
||||
xCurrentLine ) );
|
||||
uxStaticSize += uxBytes;
|
||||
snprintf( pucComment, sizeof pucComment, "Actual size fluctuates because BufferAllocation_2.c is used" );
|
||||
}
|
||||
|
||||
xLastHeaderLineNr = xCurrentLine;
|
||||
|
||||
STATS_PRINTF( ( "TCPMemStat,Total,,,=SUM(D%d:D%d),%s\n", xFirstLineNr + 1, xLastHeaderLineNr, pucComment ) );
|
||||
|
||||
STATS_PRINTF( ( "TCPMemStat,\n" ) );
|
||||
STATS_PRINTF( ( "TCPMemStat,\n" ) );
|
||||
STATS_PRINTF( ( "TCPMemStat,The following allocations are done on the heap while running:\n" ) );
|
||||
STATS_PRINTF( ( "TCPMemStat,Create/Remove,Object,Size,Heap use,Pointer,Heap-min,Heap-Cur,comment\n" ) );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vTCPMemStatCreate( TCP_MEMORY_t xMemType,
|
||||
void * pxObject,
|
||||
size_t uxSize )
|
||||
{
|
||||
if( xLoggingStopped == pdFALSE )
|
||||
{
|
||||
StreamBuffer_t * pxBuffer = NULL;
|
||||
char pcExtra[ 81 ] = "";
|
||||
|
||||
if( xFirstItem != pdFALSE )
|
||||
{
|
||||
xFirstItem = pdFALSE;
|
||||
vWriteHeader();
|
||||
}
|
||||
|
||||
if( ( xMemType == tcpRX_STREAM_BUFFER ) || ( xMemType == tcpTX_STREAM_BUFFER ) )
|
||||
{
|
||||
size_t uxTara = sizeof( *pxBuffer ) - sizeof( pxBuffer->ucArray );
|
||||
size_t uxNett = uxSize - uxTara;
|
||||
|
||||
snprintf( pcExtra, sizeof pcExtra, ",%u nett", uxNett );
|
||||
}
|
||||
|
||||
if( xFirstDumpLine == 0 )
|
||||
{
|
||||
xFirstDumpLine = xCurrentLine + 1;
|
||||
}
|
||||
|
||||
xCurrentLine++;
|
||||
configPRINTF( ( "TCPMemStat,CREATE,%s,%lu,%lu,%u,%u,%u%s\n",
|
||||
pcTypeName( xMemType ),
|
||||
uxSize,
|
||||
uxCurrentMallocSize + uxSize,
|
||||
uxNextObjectNumber,
|
||||
xPortGetMinimumEverFreeHeapSize(),
|
||||
xPortGetFreeHeapSize(),
|
||||
pcExtra ) );
|
||||
uxCurrentMallocSize += uxSize;
|
||||
vAddAllocation( xMemType, pxObject, uxSize );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vTCPMemStatDelete( void * pxObject )
|
||||
{
|
||||
if( xLoggingStopped == pdFALSE )
|
||||
{
|
||||
TCP_ALLOCATION_t * pxFound = pxRemoveAllocation( pxObject );
|
||||
|
||||
if( xFirstDumpLine == 0 )
|
||||
{
|
||||
xFirstDumpLine = xCurrentLine + 1;
|
||||
}
|
||||
|
||||
if( pxFound == NULL )
|
||||
{
|
||||
FreeRTOS_printf( ( "TCPMemStat: can not find pointer %p\n", pxObject ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
xCurrentLine++;
|
||||
configPRINTF( ( "TCPMemStat,REMOVE,%s,-%lu,%lu,%x,%u,%u\n",
|
||||
pcTypeName( pxFound->xMemType ),
|
||||
pxFound->uxSize,
|
||||
uxCurrentMallocSize - pxFound->uxSize,
|
||||
pxFound->uxNumber,
|
||||
xPortGetMinimumEverFreeHeapSize(),
|
||||
xPortGetFreeHeapSize() ) );
|
||||
|
||||
if( uxCurrentMallocSize < pxFound->uxSize )
|
||||
{
|
||||
uxCurrentMallocSize = 0uL;
|
||||
}
|
||||
else
|
||||
{
|
||||
uxCurrentMallocSize -= pxFound->uxSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vTCPMemStatClose()
|
||||
{
|
||||
if( xLoggingStopped == pdFALSE )
|
||||
{
|
||||
/* name;object;size;Heap;Ppointer;HeapMin;HeapDur;Comment */
|
||||
BaseType_t xLastLineNr = xCurrentLine;
|
||||
|
||||
xLoggingStopped = pdTRUE;
|
||||
|
||||
STATS_PRINTF( ( "TCPMemStat,Totals,,,=MAX(D%d:D%d),,=MIN(F%d:F%d),=MAX(G%d:G%d)\n",
|
||||
xFirstDumpLine,
|
||||
xLastLineNr,
|
||||
xFirstDumpLine,
|
||||
xLastLineNr,
|
||||
xFirstDumpLine,
|
||||
xLastLineNr ) );
|
||||
STATS_PRINTF( ( "TCPMemStat,Maximum RAM usage:,,,=SUM(D%d;D%d)\n",
|
||||
xLastHeaderLineNr + 1,
|
||||
xLastLineNr + 1 ) );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#endif /* ( ipconfigUSE_TCP_MEM_STATS != 0 ) */
|
||||
@ -0,0 +1,45 @@
|
||||
tcp_mem_stats.c : FreeRTOS+TCP Memory Statistics
|
||||
|
||||
This module can be used in any project on any platform that uses FreeRTOS+TCP.
|
||||
|
||||
It creates an overview of the memory usage of FreeRTOS+TCP.
|
||||
It reports the static use of RAM, and also the dynamic usage ( heap ).
|
||||
It relates these numbers to the macro's defined `FreeRTOSIPConfig.h`.
|
||||
|
||||
It writes CSV records to the logging with configPRINTF().
|
||||
|
||||
The resulting log can be filtered by e.g.:
|
||||
|
||||
cat logging.txt | grep ".*TCPMemStat," | sed "s/.*TCPMemStat,//"
|
||||
|
||||
The resulting text can be imported into any spreadsheet at cell "A1" ( top-left ):
|
||||
|
||||
ipconfig item,Value,PerUnit,Total
|
||||
NUM_NETWORK_BUFFER_DESCRIPTORS,12,60,=B13*C13,Descriptors only
|
||||
TCP_WIN_SEG_COUNT,32,64,=B14*C14
|
||||
EVENT_QUEUE_LENGTH,17,8,=B15*C15
|
||||
IP_TASK_STACK_SIZE_WORDS,300,4,=B16*C16
|
||||
|
||||
When the CSV-records are imported at another row or column than "A1", the formulas will be incorrect.
|
||||
|
||||
How to include 'tcp_mem_stats' into a project:
|
||||
|
||||
● Add tools/tcp_sources/tcp_mem_stats.c to the sources
|
||||
● Add the following lines to FreeRTOSIPConfig.h :
|
||||
#define ipconfigUSE_TCP_MEM_STATS ( 1 )
|
||||
#define ipconfigTCP_MEM_STATS_MAX_ALLOCATION ( 128 )
|
||||
#include "tools/tcp_sources/include/tcp_mem_stats.h"
|
||||
|
||||
Later on, the module can disabled by setting `#define ipconfigUSE_TCP_MEM_STATS 0`.
|
||||
|
||||
`ipconfigTCP_MEM_STATS_MAX_ALLOCATION` is the maximum number of objects that can be followed at any time.
|
||||
A socket that has 2 stream buffers counts as 3 objects ( needing 3 x 16 = 48 bytes to store their properties ).
|
||||
|
||||
The **summary** at the bottom will only be written when `iptraceMEM_STATS_CLOSE()` is called.
|
||||
The application is responsible for calling `iptraceMEM_STATS_CLOSE()`.
|
||||
The summary at the bottom looks like this:
|
||||
|
||||
Totals,,,=MAX(D25:D31),,=MIN(F25:F31),=MAX(G25:G31)
|
||||
Maximum RAM usage:,,,=SUM(D20;D32)
|
||||
|
||||
The spreadsheet can be edited further to make estimations with different macro values.
|
||||
@ -0,0 +1,197 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V3.1.0
|
||||
* Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "queue.h"
|
||||
#include "semphr.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
|
||||
#include "tcp_netstat.h"
|
||||
|
||||
extern List_t xBoundUDPSocketsList;
|
||||
|
||||
#if ( ipconfigUSE_TCP == 1 )
|
||||
extern List_t xBoundTCPSocketsList;
|
||||
#endif /* ipconfigUSE_TCP == 1 */
|
||||
|
||||
IOCounters_t xInputCounters = { 0U };
|
||||
IOCounters_t xOutputCounters = { 0U };
|
||||
|
||||
BaseType_t vGetMetrics( MetricsType_t * pxMetrics )
|
||||
{
|
||||
BaseType_t xResult = 0;
|
||||
|
||||
/* Show a simple listing of all created sockets and their connections */
|
||||
const ListItem_t * pxIterator;
|
||||
uint16_t usLastPort;
|
||||
|
||||
memset( pxMetrics, 0, sizeof *pxMetrics );
|
||||
|
||||
pxMetrics->xInput = xInputCounters;
|
||||
pxMetrics->xOutput = xOutputCounters;
|
||||
|
||||
if( !listLIST_IS_INITIALISED( &xBoundUDPSocketsList ) )
|
||||
{
|
||||
FreeRTOS_printf( ( "PLUS-TCP not initialized\n" ) );
|
||||
xResult = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if ( ipconfigUSE_TCP == 1 )
|
||||
const ListItem_t * pxEndTCP = listGET_END_MARKER( &xBoundTCPSocketsList );
|
||||
#endif
|
||||
const ListItem_t * pxEndUDP = listGET_END_MARKER( &xBoundUDPSocketsList );
|
||||
|
||||
usLastPort = 0U;
|
||||
|
||||
#if ( ipconfigUSE_TCP == 1 )
|
||||
{
|
||||
vTaskSuspendAll();
|
||||
{
|
||||
for( pxIterator = listGET_HEAD_ENTRY( &xBoundTCPSocketsList );
|
||||
pxIterator != pxEndTCP;
|
||||
pxIterator = listGET_NEXT( pxIterator ) )
|
||||
{
|
||||
const FreeRTOS_Socket_t * pxSocket = ( const FreeRTOS_Socket_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
|
||||
|
||||
if( pxMetrics->xTCPPortList.uxCount < nstatMAX_TCP_PORTS )
|
||||
{
|
||||
if( usLastPort != pxSocket->usLocalPort )
|
||||
{
|
||||
pxMetrics->xTCPPortList.usTCPPortList[ pxMetrics->xTCPPortList.uxCount ] = pxSocket->usLocalPort;
|
||||
pxMetrics->xTCPPortList.uxCount++;
|
||||
usLastPort = pxSocket->usLocalPort;
|
||||
}
|
||||
}
|
||||
|
||||
if( pxMetrics->xTCPSocketList.uxCount < nstatMAX_TCP_PORTS )
|
||||
{
|
||||
size_t uxCount = pxMetrics->xTCPSocketList.uxCount;
|
||||
|
||||
pxMetrics->xTCPSocketList.xTCPList[ uxCount ].usLocalPort = pxSocket->usLocalPort;
|
||||
pxMetrics->xTCPSocketList.xTCPList[ uxCount ].ulRemoteIP = pxSocket->u.xTCP.ulRemoteIP;
|
||||
pxMetrics->xTCPSocketList.xTCPList[ uxCount ].usRemotePort = pxSocket->u.xTCP.usRemotePort;
|
||||
pxMetrics->xTCPSocketList.uxCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( xTaskResumeAll() == 0 )
|
||||
{
|
||||
taskYIELD();
|
||||
}
|
||||
}
|
||||
#endif /* ( ipconfigUSE_TCP == 1 ) */
|
||||
|
||||
vTaskSuspendAll();
|
||||
{
|
||||
for( pxIterator = listGET_HEAD_ENTRY( &xBoundUDPSocketsList );
|
||||
pxIterator != pxEndUDP;
|
||||
pxIterator = listGET_NEXT( pxIterator ) )
|
||||
{
|
||||
const FreeRTOS_Socket_t * pxSocket = ( const FreeRTOS_Socket_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
|
||||
|
||||
if( pxMetrics->xUDPPortList.uxCount < nstatMAX_UDP_PORTS )
|
||||
{
|
||||
pxMetrics->xUDPPortList.usUDPPortList[ pxMetrics->xUDPPortList.uxCount ] = pxSocket->usLocalPort;
|
||||
pxMetrics->xUDPPortList.uxCount++;
|
||||
}
|
||||
|
||||
if( pxMetrics->xUDPSocketList.uxCount < nstatMAX_UDP_PORTS )
|
||||
{
|
||||
size_t uxCount = pxMetrics->xUDPSocketList.uxCount;
|
||||
pxMetrics->xUDPSocketList.xUDPList[ uxCount ].usLocalPort = pxSocket->usLocalPort;
|
||||
pxMetrics->xUDPSocketList.uxCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
( void ) xTaskResumeAll();
|
||||
}
|
||||
|
||||
return xResult;
|
||||
}
|
||||
|
||||
void vShowMetrics( const MetricsType_t * pxMetrics )
|
||||
{
|
||||
size_t uxIndex;
|
||||
|
||||
FreeRTOS_printf( ( "Bytes in/out:\n" ) );
|
||||
FreeRTOS_printf( ( " Input : %5lu packets, %5lu bytes\n",
|
||||
pxMetrics->xInput.uxPacketCount,
|
||||
pxMetrics->xInput.uxByteCount ) );
|
||||
FreeRTOS_printf( ( " Output : %5lu packets, %5lu bytes\n",
|
||||
pxMetrics->xOutput.uxPacketCount,
|
||||
pxMetrics->xOutput.uxByteCount ) );
|
||||
|
||||
#if ( ipconfigUSE_TCP == 1 )
|
||||
{
|
||||
FreeRTOS_printf( ( "TCP ports:\n" ) );
|
||||
|
||||
for( uxIndex = 0; uxIndex < pxMetrics->xTCPPortList.uxCount; uxIndex++ )
|
||||
{
|
||||
FreeRTOS_printf( ( " local port: %u\n",
|
||||
pxMetrics->xTCPPortList.usTCPPortList[ uxIndex ] ) );
|
||||
}
|
||||
|
||||
FreeRTOS_printf( ( "TCP sockets:\n" ) );
|
||||
|
||||
for( uxIndex = 0; uxIndex < pxMetrics->xTCPSocketList.uxCount; uxIndex++ )
|
||||
{
|
||||
FreeRTOS_printf( ( " local port: %u remote IP %xip:%u\n",
|
||||
pxMetrics->xTCPSocketList.xTCPList[ uxIndex ].usLocalPort,
|
||||
pxMetrics->xTCPSocketList.xTCPList[ uxIndex ].ulRemoteIP,
|
||||
pxMetrics->xTCPSocketList.xTCPList[ uxIndex ].usRemotePort ) );
|
||||
}
|
||||
}
|
||||
#endif /* ( ipconfigUSE_TCP == 1 ) */
|
||||
|
||||
FreeRTOS_printf( ( "UDP ports:\n" ) );
|
||||
|
||||
for( uxIndex = 0; uxIndex < pxMetrics->xUDPPortList.uxCount; uxIndex++ )
|
||||
{
|
||||
FreeRTOS_printf( ( " local port: %u\n",
|
||||
pxMetrics->xUDPPortList.usUDPPortList[ uxIndex ] ) );
|
||||
}
|
||||
|
||||
FreeRTOS_printf( ( "UDP sockets:\n" ) );
|
||||
|
||||
for( uxIndex = 0; uxIndex < pxMetrics->xUDPSocketList.uxCount; uxIndex++ )
|
||||
{
|
||||
FreeRTOS_printf( ( " local port: %u\n",
|
||||
pxMetrics->xUDPSocketList.xUDPList[ uxIndex ].usLocalPort ) );
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
tcp_netstat.c : it introduces the following function:
|
||||
|
||||
`BaseType_t vGetMetrics( MetricsType_t * pxMetrics )`
|
||||
|
||||
It collects information: all port numbers in use, all UDP sockets, all TCP sockets and their connections.
|
||||
|
||||
Make sure that your FreeRTOSIPConfig.h includes tools/tcp_utilities/include/tcp_netstat.h:
|
||||
|
||||
`@include "tcp_netstat.h"`
|
||||
|
||||
because it will define 2 important macro's:
|
||||
|
||||
#define iptraceNETWORK_INTERFACE_INPUT( uxDataLength, pucEthernetBuffer )
|
||||
|
||||
#define iptraceNETWORK_INTERFACE_OUTPUT( uxDataLength, pucEthernetBuffer )
|
||||
|
||||
These macro's will be called when an Ethernet packet has been received or sent.
|
||||
|
||||
When collecting socket and port information, it will iterate through the list of sockets, filling arrays of structures.
|
||||
@ -0,0 +1,160 @@
|
||||
# Uncrustify-0.67
|
||||
input_tab_size = 4 # unsigned number
|
||||
output_tab_size = 4 # unsigned number
|
||||
sp_arith = force # ignore/add/remove/force
|
||||
sp_assign = force # ignore/add/remove/force
|
||||
sp_assign_default = force # ignore/add/remove/force
|
||||
sp_before_assign = force # ignore/add/remove/force
|
||||
sp_after_assign = force # ignore/add/remove/force
|
||||
sp_enum_assign = force # ignore/add/remove/force
|
||||
sp_enum_before_assign = force # ignore/add/remove/force
|
||||
sp_enum_after_assign = force # ignore/add/remove/force
|
||||
sp_pp_stringify = add # ignore/add/remove/force
|
||||
sp_bool = force # ignore/add/remove/force
|
||||
sp_compare = force # ignore/add/remove/force
|
||||
sp_inside_paren = force # ignore/add/remove/force
|
||||
sp_paren_paren = force # ignore/add/remove/force
|
||||
sp_paren_brace = force # ignore/add/remove/force
|
||||
sp_before_ptr_star = force # ignore/add/remove/force
|
||||
sp_before_unnamed_ptr_star = force # ignore/add/remove/force
|
||||
sp_between_ptr_star = remove # ignore/add/remove/force
|
||||
sp_after_ptr_star = force # ignore/add/remove/force
|
||||
sp_before_byref = force # ignore/add/remove/force
|
||||
sp_after_byref = remove # ignore/add/remove/force
|
||||
sp_after_byref_func = remove # ignore/add/remove/force
|
||||
sp_before_angle = remove # ignore/add/remove/force
|
||||
sp_inside_angle = remove # ignore/add/remove/force
|
||||
sp_after_angle = force # ignore/add/remove/force
|
||||
sp_before_sparen = remove # ignore/add/remove/force
|
||||
sp_inside_sparen = force # ignore/add/remove/force
|
||||
sp_after_sparen = force # ignore/add/remove/force
|
||||
sp_sparen_brace = force # ignore/add/remove/force
|
||||
sp_before_semi_for = remove # ignore/add/remove/force
|
||||
sp_before_semi_for_empty = add # ignore/add/remove/force
|
||||
sp_after_semi_for_empty = force # ignore/add/remove/force
|
||||
sp_before_square = remove # ignore/add/remove/force
|
||||
sp_before_squares = remove # ignore/add/remove/force
|
||||
sp_inside_square = force # ignore/add/remove/force
|
||||
sp_after_comma = force # ignore/add/remove/force
|
||||
sp_after_cast = force # ignore/add/remove/force
|
||||
sp_inside_paren_cast = force # ignore/add/remove/force
|
||||
sp_sizeof_paren = remove # ignore/add/remove/force
|
||||
sp_inside_braces_enum = force # ignore/add/remove/force
|
||||
sp_inside_braces_struct = force # ignore/add/remove/force
|
||||
sp_inside_braces = force # ignore/add/remove/force
|
||||
sp_inside_braces_empty = remove # ignore/add/remove/force
|
||||
sp_type_func = force # ignore/add/remove/force
|
||||
sp_func_proto_paren = remove # ignore/add/remove/force
|
||||
sp_func_def_paren = remove # ignore/add/remove/force
|
||||
sp_inside_fparens = remove # ignore/add/remove/force
|
||||
sp_inside_fparen = force # ignore/add/remove/force
|
||||
sp_fparen_brace = add # ignore/add/remove/force
|
||||
sp_func_call_paren = remove # ignore/add/remove/force
|
||||
sp_func_class_paren = remove # ignore/add/remove/force
|
||||
sp_return_paren = remove # ignore/add/remove/force
|
||||
sp_attribute_paren = remove # ignore/add/remove/force
|
||||
sp_defined_paren = remove # ignore/add/remove/force
|
||||
sp_macro = force # ignore/add/remove/force
|
||||
sp_macro_func = force # ignore/add/remove/force
|
||||
sp_brace_typedef = force # ignore/add/remove/force
|
||||
sp_before_dc = remove # ignore/add/remove/force
|
||||
sp_after_dc = remove # ignore/add/remove/force
|
||||
sp_cond_colon = force # ignore/add/remove/force
|
||||
sp_cond_question = force # ignore/add/remove/force
|
||||
sp_case_label = force # ignore/add/remove/force
|
||||
sp_endif_cmt = force # ignore/add/remove/force
|
||||
sp_before_tr_emb_cmt = force # ignore/add/remove/force
|
||||
sp_num_before_tr_emb_cmt = 1 # unsigned number
|
||||
indent_columns = 4 # unsigned number
|
||||
indent_with_tabs = 0 # unsigned number
|
||||
indent_align_string = true # false/true
|
||||
indent_class = true # false/true
|
||||
indent_class_colon = true # false/true
|
||||
indent_member = 3 # unsigned number
|
||||
indent_switch_case = 4 # unsigned number
|
||||
indent_case_brace = 3 # number
|
||||
nl_assign_leave_one_liners = true # false/true
|
||||
nl_class_leave_one_liners = true # false/true
|
||||
nl_start_of_file = remove # ignore/add/remove/force
|
||||
nl_end_of_file = force # ignore/add/remove/force
|
||||
nl_end_of_file_min = 1 # unsigned number
|
||||
nl_assign_brace = add # ignore/add/remove/force
|
||||
nl_func_var_def_blk = 1 # unsigned number
|
||||
nl_fcall_brace = add # ignore/add/remove/force
|
||||
nl_enum_brace = force # ignore/add/remove/force
|
||||
nl_struct_brace = force # ignore/add/remove/force
|
||||
nl_union_brace = force # ignore/add/remove/force
|
||||
nl_if_brace = add # ignore/add/remove/force
|
||||
nl_brace_else = add # ignore/add/remove/force
|
||||
nl_else_brace = add # ignore/add/remove/force
|
||||
nl_getset_brace = force # ignore/add/remove/force
|
||||
nl_for_brace = add # ignore/add/remove/force
|
||||
nl_while_brace = add # ignore/add/remove/force
|
||||
nl_do_brace = add # ignore/add/remove/force
|
||||
nl_switch_brace = add # ignore/add/remove/force
|
||||
nl_multi_line_define = true # false/true
|
||||
nl_before_case = true # false/true
|
||||
nl_after_case = true # false/true
|
||||
nl_func_type_name = remove # ignore/add/remove/force
|
||||
nl_func_proto_type_name = remove # ignore/add/remove/force
|
||||
nl_func_paren = remove # ignore/add/remove/force
|
||||
nl_func_def_paren = remove # ignore/add/remove/force
|
||||
nl_func_decl_start = remove # ignore/add/remove/force
|
||||
nl_func_def_start = remove # ignore/add/remove/force
|
||||
nl_func_decl_args = add # ignore/add/remove/force
|
||||
nl_func_def_args = add # ignore/add/remove/force
|
||||
nl_func_decl_end = remove # ignore/add/remove/force
|
||||
nl_func_def_end = remove # ignore/add/remove/force
|
||||
nl_fdef_brace = add # ignore/add/remove/force
|
||||
nl_after_semicolon = true # false/true
|
||||
nl_after_brace_open = true # false/true
|
||||
nl_after_brace_close = true # false/true
|
||||
nl_squeeze_ifdef = true # false/true
|
||||
nl_before_if = force # ignore/add/remove/force
|
||||
nl_after_if = force # ignore/add/remove/force
|
||||
nl_before_for = force # ignore/add/remove/force
|
||||
nl_after_for = force # ignore/add/remove/force
|
||||
nl_before_while = force # ignore/add/remove/force
|
||||
nl_after_while = force # ignore/add/remove/force
|
||||
nl_before_switch = force # ignore/add/remove/force
|
||||
nl_after_switch = force # ignore/add/remove/force
|
||||
nl_before_do = force # ignore/add/remove/force
|
||||
nl_after_do = force # ignore/add/remove/force
|
||||
nl_max = 4 # unsigned number
|
||||
nl_after_func_proto_group = 1 # unsigned number
|
||||
nl_after_func_body_class = 2 # unsigned number
|
||||
nl_before_block_comment = 2 # unsigned number
|
||||
eat_blanks_after_open_brace = true # false/true
|
||||
eat_blanks_before_close_brace = true # false/true
|
||||
nl_after_return = true # false/true
|
||||
pos_bool = trail # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force
|
||||
align_var_def_amp_style = 1 # unsigned number
|
||||
align_var_def_thresh = 16 # unsigned number
|
||||
align_assign_thresh = 12 # unsigned number
|
||||
align_struct_init_span = 3 # unsigned number
|
||||
align_typedef_gap = 3 # unsigned number
|
||||
align_typedef_span = 5 # unsigned number
|
||||
align_typedef_star_style = 1 # unsigned number
|
||||
align_typedef_amp_style = 1 # unsigned number
|
||||
align_right_cmt_span = 3 # unsigned number
|
||||
align_nl_cont = true # false/true
|
||||
align_pp_define_gap = 4 # unsigned number
|
||||
align_pp_define_span = 3 # unsigned number
|
||||
cmt_cpp_to_c = true # false/true
|
||||
cmt_star_cont = true # false/true
|
||||
mod_full_brace_do = add # ignore/add/remove/force
|
||||
mod_full_brace_for = add # ignore/add/remove/force
|
||||
mod_full_brace_if = add # ignore/add/remove/force
|
||||
mod_full_brace_while = add # ignore/add/remove/force
|
||||
mod_full_paren_if_bool = true # false/true
|
||||
mod_remove_extra_semicolon = true # false/true
|
||||
mod_add_long_ifdef_endif_comment = 10 # unsigned number
|
||||
mod_add_long_ifdef_else_comment = 10 # unsigned number
|
||||
mod_case_brace = remove # ignore/add/remove/force
|
||||
mod_remove_empty_return = true # false/true
|
||||
pp_indent = force # ignore/add/remove/force
|
||||
pp_indent_at_level = true # false/true
|
||||
pp_indent_count = 4 # unsigned number
|
||||
pp_space = remove # ignore/add/remove/force
|
||||
pp_if_indent_code = true # false/true
|
||||
# option(s) with 'not default' value: 158
|
||||
@ -0,0 +1,160 @@
|
||||
# Uncrustify-0.67
|
||||
input_tab_size = 4 # unsigned number
|
||||
output_tab_size = 4 # unsigned number
|
||||
sp_arith = force # ignore/add/remove/force
|
||||
sp_assign = force # ignore/add/remove/force
|
||||
sp_assign_default = force # ignore/add/remove/force
|
||||
sp_before_assign = force # ignore/add/remove/force
|
||||
sp_after_assign = force # ignore/add/remove/force
|
||||
sp_enum_assign = force # ignore/add/remove/force
|
||||
sp_enum_before_assign = force # ignore/add/remove/force
|
||||
sp_enum_after_assign = force # ignore/add/remove/force
|
||||
sp_pp_stringify = add # ignore/add/remove/force
|
||||
sp_bool = force # ignore/add/remove/force
|
||||
sp_compare = force # ignore/add/remove/force
|
||||
sp_inside_paren = force # ignore/add/remove/force
|
||||
sp_paren_paren = force # ignore/add/remove/force
|
||||
sp_paren_brace = force # ignore/add/remove/force
|
||||
sp_before_ptr_star = force # ignore/add/remove/force
|
||||
sp_before_unnamed_ptr_star = force # ignore/add/remove/force
|
||||
sp_between_ptr_star = remove # ignore/add/remove/force
|
||||
sp_after_ptr_star = force # ignore/add/remove/force
|
||||
sp_before_byref = force # ignore/add/remove/force
|
||||
sp_after_byref = remove # ignore/add/remove/force
|
||||
sp_after_byref_func = remove # ignore/add/remove/force
|
||||
sp_before_angle = remove # ignore/add/remove/force
|
||||
sp_inside_angle = remove # ignore/add/remove/force
|
||||
sp_after_angle = force # ignore/add/remove/force
|
||||
sp_before_sparen = remove # ignore/add/remove/force
|
||||
sp_inside_sparen = force # ignore/add/remove/force
|
||||
sp_after_sparen = force # ignore/add/remove/force
|
||||
sp_sparen_brace = force # ignore/add/remove/force
|
||||
sp_before_semi_for = remove # ignore/add/remove/force
|
||||
sp_before_semi_for_empty = add # ignore/add/remove/force
|
||||
sp_after_semi_for_empty = force # ignore/add/remove/force
|
||||
sp_before_square = remove # ignore/add/remove/force
|
||||
sp_before_squares = remove # ignore/add/remove/force
|
||||
sp_inside_square = force # ignore/add/remove/force
|
||||
sp_after_comma = force # ignore/add/remove/force
|
||||
sp_after_cast = force # ignore/add/remove/force
|
||||
sp_inside_paren_cast = force # ignore/add/remove/force
|
||||
sp_sizeof_paren = remove # ignore/add/remove/force
|
||||
sp_inside_braces_enum = force # ignore/add/remove/force
|
||||
sp_inside_braces_struct = force # ignore/add/remove/force
|
||||
sp_inside_braces = force # ignore/add/remove/force
|
||||
sp_inside_braces_empty = remove # ignore/add/remove/force
|
||||
sp_type_func = force # ignore/add/remove/force
|
||||
sp_func_proto_paren = remove # ignore/add/remove/force
|
||||
sp_func_def_paren = remove # ignore/add/remove/force
|
||||
sp_inside_fparens = remove # ignore/add/remove/force
|
||||
sp_inside_fparen = force # ignore/add/remove/force
|
||||
sp_fparen_brace = add # ignore/add/remove/force
|
||||
sp_func_call_paren = remove # ignore/add/remove/force
|
||||
sp_func_class_paren = remove # ignore/add/remove/force
|
||||
sp_return_paren = remove # ignore/add/remove/force
|
||||
sp_attribute_paren = remove # ignore/add/remove/force
|
||||
sp_defined_paren = remove # ignore/add/remove/force
|
||||
sp_macro = force # ignore/add/remove/force
|
||||
sp_macro_func = force # ignore/add/remove/force
|
||||
sp_brace_typedef = force # ignore/add/remove/force
|
||||
sp_before_dc = remove # ignore/add/remove/force
|
||||
sp_after_dc = remove # ignore/add/remove/force
|
||||
sp_cond_colon = force # ignore/add/remove/force
|
||||
sp_cond_question = force # ignore/add/remove/force
|
||||
sp_case_label = force # ignore/add/remove/force
|
||||
sp_endif_cmt = force # ignore/add/remove/force
|
||||
sp_before_tr_emb_cmt = force # ignore/add/remove/force
|
||||
sp_num_before_tr_emb_cmt = 1 # unsigned number
|
||||
indent_columns = 4 # unsigned number
|
||||
indent_with_tabs = 2 # unsigned number
|
||||
indent_align_string = true # false/true
|
||||
indent_class = true # false/true
|
||||
indent_class_colon = true # false/true
|
||||
indent_member = 3 # unsigned number
|
||||
indent_switch_case = 4 # unsigned number
|
||||
indent_case_brace = 3 # number
|
||||
nl_assign_leave_one_liners = true # false/true
|
||||
nl_class_leave_one_liners = true # false/true
|
||||
nl_start_of_file = remove # ignore/add/remove/force
|
||||
nl_end_of_file = force # ignore/add/remove/force
|
||||
nl_end_of_file_min = 1 # unsigned number
|
||||
nl_assign_brace = add # ignore/add/remove/force
|
||||
nl_func_var_def_blk = 1 # unsigned number
|
||||
nl_fcall_brace = add # ignore/add/remove/force
|
||||
nl_enum_brace = force # ignore/add/remove/force
|
||||
nl_struct_brace = force # ignore/add/remove/force
|
||||
nl_union_brace = force # ignore/add/remove/force
|
||||
nl_if_brace = add # ignore/add/remove/force
|
||||
nl_brace_else = add # ignore/add/remove/force
|
||||
nl_else_brace = add # ignore/add/remove/force
|
||||
nl_getset_brace = force # ignore/add/remove/force
|
||||
nl_for_brace = add # ignore/add/remove/force
|
||||
nl_while_brace = add # ignore/add/remove/force
|
||||
nl_do_brace = add # ignore/add/remove/force
|
||||
nl_switch_brace = add # ignore/add/remove/force
|
||||
nl_multi_line_define = true # false/true
|
||||
nl_before_case = true # false/true
|
||||
nl_after_case = true # false/true
|
||||
nl_func_type_name = remove # ignore/add/remove/force
|
||||
nl_func_proto_type_name = remove # ignore/add/remove/force
|
||||
nl_func_paren = remove # ignore/add/remove/force
|
||||
nl_func_def_paren = remove # ignore/add/remove/force
|
||||
nl_func_decl_start = remove # ignore/add/remove/force
|
||||
nl_func_def_start = remove # ignore/add/remove/force
|
||||
nl_func_decl_args = add # ignore/add/remove/force
|
||||
nl_func_def_args = add # ignore/add/remove/force
|
||||
nl_func_decl_end = remove # ignore/add/remove/force
|
||||
nl_func_def_end = remove # ignore/add/remove/force
|
||||
nl_fdef_brace = add # ignore/add/remove/force
|
||||
nl_after_semicolon = true # false/true
|
||||
nl_after_brace_open = true # false/true
|
||||
nl_after_brace_close = true # false/true
|
||||
nl_squeeze_ifdef = true # false/true
|
||||
nl_before_if = force # ignore/add/remove/force
|
||||
nl_after_if = force # ignore/add/remove/force
|
||||
nl_before_for = force # ignore/add/remove/force
|
||||
nl_after_for = force # ignore/add/remove/force
|
||||
nl_before_while = force # ignore/add/remove/force
|
||||
nl_after_while = force # ignore/add/remove/force
|
||||
nl_before_switch = force # ignore/add/remove/force
|
||||
nl_after_switch = force # ignore/add/remove/force
|
||||
nl_before_do = force # ignore/add/remove/force
|
||||
nl_after_do = force # ignore/add/remove/force
|
||||
nl_max = 4 # unsigned number
|
||||
nl_after_func_proto_group = 1 # unsigned number
|
||||
nl_after_func_body_class = 2 # unsigned number
|
||||
nl_before_block_comment = 2 # unsigned number
|
||||
eat_blanks_after_open_brace = true # false/true
|
||||
eat_blanks_before_close_brace = true # false/true
|
||||
nl_after_return = true # false/true
|
||||
pos_bool = trail # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force
|
||||
align_var_def_amp_style = 1 # unsigned number
|
||||
align_var_def_thresh = 16 # unsigned number
|
||||
align_assign_thresh = 12 # unsigned number
|
||||
align_struct_init_span = 3 # unsigned number
|
||||
align_typedef_gap = 3 # unsigned number
|
||||
align_typedef_span = 5 # unsigned number
|
||||
align_typedef_star_style = 1 # unsigned number
|
||||
align_typedef_amp_style = 1 # unsigned number
|
||||
align_right_cmt_span = 3 # unsigned number
|
||||
align_nl_cont = true # false/true
|
||||
align_pp_define_gap = 4 # unsigned number
|
||||
align_pp_define_span = 3 # unsigned number
|
||||
cmt_cpp_to_c = true # false/true
|
||||
cmt_star_cont = true # false/true
|
||||
mod_full_brace_do = add # ignore/add/remove/force
|
||||
mod_full_brace_for = add # ignore/add/remove/force
|
||||
mod_full_brace_if = add # ignore/add/remove/force
|
||||
mod_full_brace_while = add # ignore/add/remove/force
|
||||
mod_full_paren_if_bool = true # false/true
|
||||
mod_remove_extra_semicolon = true # false/true
|
||||
mod_add_long_ifdef_endif_comment = 10 # unsigned number
|
||||
mod_add_long_ifdef_else_comment = 10 # unsigned number
|
||||
mod_case_brace = remove # ignore/add/remove/force
|
||||
mod_remove_empty_return = true # false/true
|
||||
pp_indent = remove # ignore/add/remove/force
|
||||
pp_indent_at_level = true # false/true
|
||||
pp_indent_count = 4 # unsigned number
|
||||
pp_space = remove # ignore/add/remove/force
|
||||
pp_if_indent_code = false # false/true
|
||||
# option(s) with 'not default' value: 158
|
||||
Reference in New Issue
Block a user