-
Notifications
You must be signed in to change notification settings - Fork 1.9k
FreeRTOS+TCP : add memory statistics and dump packets #44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Here below an example of a spread sheet as produced by an STMF32F7xx, in an FTP-session.
|
|
And here is an example of the network packet dump in C: It is a frame of type IPv4, and it is a SYN packet in a TCP conversation. The file will also include an array of all available network packets: DumpPacket_t *xPacketList[ dumpPACKET_COUNT ] =
{
&xPacket_0000,
&xPacket_0001,
&xPacket_0002,
&xPacket_0003,
/* etc. */
};So the testing software can search for certain types of packets.
#define flag_ICMP4 0x00000001uL
#define flag_ICMP6 0x00000002uL
#define flag_UDP 0x00000004uL
#define flag_TCP 0x00000008uL
#define flag_DNS 0x00000010uL
/* etc */
#define flag_FRAME_6 0x00020000uL
#define flag_Unknown_FRAME 0x00040000uL |
| } | ||
| else | ||
| { | ||
| if( xIsInputStream != 0 ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we do if( xIsInputStream != pdFALSE )? Just for consistency and 0 is technically a magic number.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes sure, pdFALSE is better.
Also, now I combined the macro calls with existing code:
- if( xIsInputStream != 0 )
+ if( xIsInputStream != pdFALSE )
{
+ iptraceMEM_STATS_CREATE( tcpRX_STREAM_BUFFER, pxBuffer, uxSize );
pxSocket->u.xTCP.rxStream = pxBuffer;
}
else
{
+ iptraceMEM_STATS_CREATE( tcpTX_STREAM_BUFFER, pxBuffer, uxSize );
pxSocket->u.xTCP.txStream = pxBuffer;
}There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you have a look at this?
AniruddhaKanhere
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some changes are trivial but one change regarding vTCPMemStatRemove is important
| 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 ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not to nitpick but shouldn't all these functions begin with a 'prv' since they are all private functions?
Note: I would not hold a merge for this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right: v is used for public functions returning void, prv is used for static (private) functions.
I changed the names to prvAddProtocolTags etc.
|
|
||
| void vTCPMemStatCreate( TCP_MEMORY_t xMemType, void *pxObject, size_t uxSize ); | ||
|
|
||
| void vTCPMemStatRemove( void *pxObject ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you mean to declare vTCPMemStatsDelete here?
Because vTCPMemStatsRemove is neither defined nor used anywhere. Line 37 seems correct since it uses a function defined in tcp_mem_stats.c.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops yes, you are correct. In an earlier version, I called them "create/remove", which are not really opposites.
Now it is "create/delete". I changed the header file, thank.
| if( xIsInputStream != 0 ) | ||
| if( xIsInputStream != pdFALSE ) | ||
| { | ||
| iptraceMEM_STATS_CREATE( tcpRX_STREAM_BUFFER, pxBuffer, uxSize ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Hein,
I just have one question, does the memset on line 2986 memset( pxBuffer, '\0', sizeof( *pxBuffer ) - sizeof( pxBuffer->ucArray ) ); affect the way the iptraceMEM_STATS_CREATE( tcpRX_STREAM_BUFFER, pxBuffer, uxSize ); behaves?
Just making sure that moving iptraceMEM_STATS_CREATE( tcpRX_STREAM_BUFFER, pxBuffer, uxSize ); from before memset to current location doesn't have any unintended effects.
Similarly for the else case...
Except that, all seems to be good. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good to notice this change in code, but no, the call to memset() and setting pxBuffer->LENGTH have no relation with iptraceMEM_STATS_CREATE().
The latter will only log and register the pointer along with the type and the size.
Thanks.
| /*-----------------------------------------------------------*/ | ||
|
|
||
| /* The Windows thread that actually writes the network packets to a C source and header file. */ | ||
| static DWORD WINAPI prvWritePackets( LPVOID lpParameter ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we use some abstraction so this code can be reused on other platforms? I am going to approve, but this could be useful for the Linux port
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose we may as well shelf that for later, as the Linux port does not have networking added to it yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can add that later, as soon as the Linux port also has TCP.
And there is also FreeRTOS+FAT: the module tcp_dump_packets.c could also run on any device that has a disk ( SD/MMC, or a RAM-disk ).
In that case, mentioned function would become a normal task:
static void prvWritePackets( void *pvParameter );I have thought of adding some +FAT code, but the problem is that there are no AWS projects yet that use FreeRTOS+FAT.
( and once you have a disk, it would also be nice to be able to produce regular PCAP files ).
The tcp_mem_stats.c module, on the contrary, can run on any device that has logging.
lundinc2
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have some concerns about using the windows' APIs
|
@htibosch also you will need to rebase once this is approved, this repo has much stricter branch rules. |
| } | ||
| else | ||
| { | ||
| if( xProtocol == FREERTOS_IPPROTO_UDP ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than add these new branches, we could replace the various malloc calls in this module with a macro (e.g. pvPortSocketsMalloc). The macro could accept whatever additional call site-specific parameters are required for stats. Would there be disadvantages with that approach?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dcgaws: I have thought of doing so, but the macro pvPortMallocSocket() only takes one parameter: the size. I think we'de like to see in the logging what type of socket was created, UDP or TCP.
Likewise, pvPortMallocLarge() only takes a parameter uxSize. That function creates the stream buffers of TCP.
A socket-set is allocated with the standard FreeRTOS function pvPortMalloc(), which is too generic.
The new macro's like iptraceMEM_STATS_CREATE() get their default values in IPTraceMacroDefaults.h. Users can define them for their own use ( in FreeRTOSIPConfig.h ), or use the new modules.
| @@ -0,0 +1,61 @@ | |||
| /* | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could packet dumping please be separated into its own PR? (At least, based on the assumption that it's independent of the mem stats changes, above.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dcgaws:
I combined the two because they want to change a common file: include/IPTraceMacroDefaults.h.
Also they want to create a new directory /tools, which sits next to source and include.
And a last reason is time: I saved a lot of time by testing them in one go and writing a single PR.
|
/bot run checks |
1 similar comment
|
/bot run checks |
|
Hi @htibosch, |
Yes sure, I will. Closing this PR in order to create a new one. |
* Create manifest.yml * Remove trailing whitespace * Update manifest.yml * Corrected a typo * Uncrustify C files * Uncrustify header files * Update ci.yml * Update ci.yml * Uncrustify with version 0.67 * Spelling corrections
See also an earlier equivalent PR 1828 on aws/amazon-freertos
Description
Sometimes it is difficult to get an overview of how much RAM is actually used by FreeRTOS+TCP.
When enabled,
tcp_mem_stats.cwill write CSV records to the standard logging. With the use of grep and sed, these lines can be taken out and copied into a spreadsheet.The result is a sheet (with formulas), that shows all relevant ipconfig macros, their values and how many objects are declared, either statically or dynamically. The user can test several scenarios by changing the macro values.
When not enabled (
ipconfigUSE_TCP_MEM_STATSnot defined ), the module is not compiled and no extra code is added.I tested the module on several platforms, notably ESP32, Xilinx and WinSim.
There is also some documentation in tools/tcp_mem_stats.md
Also: added
tcp_dump_packets.c: it can be included in the WinSim project. It will write selected network packets to a C source files. This source file can later be include in testing projects to test the TCP software.Test Steps
tcp_mem_stats.c: I had it run for a few minutes in a aws_tests project. AftervTCPMemStatClose()was called, I did the following on the logging:tcp_dump_packets.c: I filled in the desired packet types and had it run until all packet types were collected. I compiled the output into a testing module.I opened the CSV file as a spreadsheet.
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.