NOTICE: The Processors Wiki will End-of-Life on January 15, 2021. It is recommended to download any files or other content you may need that are hosted on processors.wiki.ti.com. The site is now set to read only.
NDK RAM Sizing: Concerto Example
Contents
The TI-RTOS product installation includes a tcpEcho example. You can download the TI-RTOS installer. The example runs on the TMDXDOCKH52C1 (Concerto) board. RAM is limited on this board, so steps were taken to reduce the RAM requirements by the application. The following is a discussion of the actions taken.
Example overview[edit]
The tcpSendReceive host tool in TI-RTOS sends a TCP packet to the specified IP address on a specified port (for example, port 1000). The tcpEcho example echoes that TCP packet back to a host application. This send and echo sequence is repeated until the host application is stopped. Up to 3 host tools can run at the same time. When the host tools attempts to establish the connection, the tcpHandler task in the tcpEcho application creates a new task (tcpWorker), which does the actual echoing. Once the socket is terminated by the host, the tcpWorker terminates also. The size of the TCP payload was 1024 bytes.
Default RAM usage[edit]
The following table shows RAM usage based on the number of TCP connections. All sizes are in bytes. The application uses the default SYS/BIOS heap size of 20480.
# Connections | Memory Manager | Network Packets | Used Heap | Total |
---|---|---|---|---|
0 | 24800 | 25792 | 5544 | 56136 |
1 | 24800 | 25792 | 11872 | 62464 |
2 | 24800 | 25792 | 18200 | 68792 |
3 | 24800 | 25792 | OOM | N/A |
- # Connections: Number of tcpSendReceive sessions running.
- Memory Manager: Statically defined character arrays See NDK Static Internal Memory Manager.
- Network Packets: Statically defined character arrays. See NDK Static Network Buffers.
- Used Heap: Amount of memory that was used in the SYS/BIOS default heap. This includes allocation by non-networking components also. See NDK Dynamic Memory Manager.
Note: The third connection failed because the target was out of memory (OOM).
The amount of heap usage increases by 6328 bytes for each additional connection. Here is where this number comes from:
1024 bytes for new task 2048 bytes for socket Tx Buffer 2048 bytes for socket Rx Buffer 1024 bytes tcpHandler task allocates + 184 bytes miscellaneous (Task Object, etc.) -------------------------------------- 6328 bytes total
RAM usage after modifications[edit]
The following changes were made within the .cfg file to reduce the RAM requirements.
Network buffers[edit]
By default for M3, M4, and M4F, there are 16 network buffers. Each buffer is 1536 bytes (by default). Since this is a fairly simple application, the number of network packets was reduced to 6.
<syntaxhighlight lang='javascript'> Global.pktNumFrameBufs = 6; </syntaxhighlight>
The risk of reducing the number of packets is greater when a burst (receive or transmit) occurs. In such cases, the packets could all be used, resulting in dropping packets. Since this application uses TCP, the TCP protocol handles the retransmission of dropped packets.
Memory manager[edit]
By default for M3, M4, and M4F, there are 8 buckets with the Memory Manager. Each bucket is 3072 bytes (by default). After running the application and looking at _mmCheck results, it was determined that not all the buckets were being used. So the count was reduced to 6.
<syntaxhighlight lang='javascript'> Global.memRawPageCount = 6; </syntaxhighlight>
Heap reductions[edit]
After running the application, the "Detailed" view of the Task Module in ROV was examined. The stack sizes for the NDK tasks were too large. The following properties were changed to reduce the stack sizes:
<syntaxhighlight lang='javascript'> Global.ndkThreadStackSize = 1536; Global.lowTaskStackSize = 1024; Global.normTaskStackSize = 1024; Global.highTaskStackSize = 1024; </syntaxhighlight>
Additionally, since the application was only sending TCP packets of size 1024, the following properties were changed to further reduce the amount of heap size that was used.
<syntaxhighlight lang='javascript'> Tcp.transmitBufSize = 1024; Tcp.receiveBufSize = 1024; </syntaxhighlight>
Additional SYS/BIOS changes[edit]
The "Detailed" view of the Task Module in ROV also showed that the Idle task stack size was too large. The Hwi module in ROV showed that the system stack was also too large. These were reduced by changing the following properties:
<syntaxhighlight lang='javascript'> Task.idleTaskStackSize = 768; Program.stack = 2048; </syntaxhighlight>
Results[edit]
After making the above changes, the application was rebuilt and run again. Here are the new numbers:
# connections | Memory Manager | Network Packets | Used Heap | Total RAM | RAM Saved from default |
---|---|---|---|---|---|
0 | 18600 | 9824 | 4520 | 32944 | 23192 |
1 | 18600 | 9824 | 8800 | 37224 | 25240 |
2 | 18600 | 9824 | 13080 | 41504 | 27288 |
3 | 18600 | 9824 | 17360 | 45784 | N/A |
The amount of heap usage increased by 4280 bytes for each additional connection. Here is where this number comes from:
1024 bytes for new task 1024 bytes for socket Tx Buffer 1024 bytes for socket Rx Buffer 1024 bytes tcpHandler task allocates + 184 bytes miscellaneous (Task Object, etc.) ------------------------------------- 4280 bytes total
We might have reduced the Global.memRawPageSize
property to 1536. This would save an additional 9216 bytes, but we wanted to keep the application somewhat flexible in case additional functionality was needed (for example, to add an HTTP server).