PIC32MX795 and FreeRTOS TCP/IP Stack

Hi does anybody have a port yet for the PIC32 starter kit to the new FreeRTOS stack? Best regards Dani

PIC32MX795 and FreeRTOS TCP/IP Stack

I’m not aware of anybody using this part. We would be happy to assist as much as we could via this forum and email exchange if you were to create a port provided the result was uploaded to the FreeRTOS interactive site once complete. Regards.

PIC32MX795 and FreeRTOS TCP/IP Stack

Thanks, that is certainly worth to thing about.

PIC32MX795 and FreeRTOS TCP/IP Stack

I’ve used this part in three project, with the standard demo as a start…. Was easy to bring up and make changes for my hardware…. Also used the MZ in a project, again was easy to make work..

PIC32MX795 and FreeRTOS TCP/IP Stack

Sorry for being fuzzy, I’m talking about the TCP/IP Stack, PIC32 port is working fine…. We have the MAC/PHY combo now working, but problem with DHCP client. Can we expect that the DHCP implementation is functional and has been tested in the latest release?

PIC32MX795 and FreeRTOS TCP/IP Stack

Yes – the DHCP has been tested with a lot of different network configurations. Can you post a WireShark capture of the DHCP transactions?

PIC32MX795 and FreeRTOS TCP/IP Stack

it only send dhcp discover request, but for some reason there is no response from the server. We will look into details, server should work, it responds to microchip dhcp request, so I expected something to be wrong in the freertos request….

PIC32MX795 and FreeRTOS TCP/IP Stack

Ok – a wireshark caption could still be helpful, so we can inspect the suspect packet, and see if Wireshark can decode it, or highlight any potential issues with it.

PIC32MX795 and FreeRTOS TCP/IP Stack

Looks like Freertos sends discorver as unicast, should be broadcast….

PIC32MX795 and FreeRTOS TCP/IP Stack

Hi Dani,
Looks like Freertos sends discorver as unicast, should be broadcast…
The DHCP client will try both methods: without and with the BROADCAST flag set. The discovery and all other messages will always be sent to the UDP broadcast address 255.255.255.255 Does your DHCP server allow any client to apply for an IP address? No MAC address filtering? I attached a PCAP file to this post of a +TCP device booting in a LAN. ~~~~~ /* My DHCP server was switched off here: */ 1 0.000 DHCP Discover – unicast 4 5.249 DHCP Discover – broadcast 6 15.498 DHCP Discover – unicast /* Device uses IP 192.168.2.114, answers to ping. */ 20 62.475 +TCP device replies as 192.168.2.114 21 62.475 PING request /* Switched on the DHCP server: */ 38 99.550 Discover – unicast 39 99.550 Offer 40 99.552 Request 41 99.552 ACK ~~~~~ If you doubt, please post some PCAP files. Do other things already work? UDP? TCP? Regards, Hein

PIC32MX795 and FreeRTOS TCP/IP Stack

ok, we got it working with the pic. it uses much memory, can you pls give me a config file with the bare minimum settings for memory consumption?

PIC32MX795 and FreeRTOS TCP/IP Stack

@Hein, thanks we found the DHCP problem, there has been a problem with checksum settings. The rx tx buffers are set in the socket command. Is there a way to set this other then the default for each socket? For example some sockets require only require small rx or tx buffer. Best would be if this could be tuned at runtime…

PIC32MX795 and FreeRTOS TCP/IP Stack

Not at my computer at the moment so I can’t provide a direct link, but if you look on the FreeRTOS+TCP web pages, the tree menu on the left has a page describing how to configure either for performance or to reduce memory usage.

PIC32MX795 and FreeRTOS TCP/IP Stack

yes you can, just use FreeRTOS_setsockopt to adjust buffers at runtime.

PIC32MX795 and FreeRTOS TCP/IP Stack

usBacklog sets the number of sockets that are created when a new messages arrives. It does also use the setsockopt settings, not the default?

PIC32MX795 and FreeRTOS TCP/IP Stack

Hi Dani, About the memory use of FreeRTOS +TCP “Network Buffer Descriptors” are the objects that hold the network messages. They normally have a short life, after a few ms they are delivered to their destination. The UDP protocol uses discrete messages. Therefore these message will stay in their ‘Network Buffer Descriptors’ while waiting to be picked up by FreeRTOS_recvfrom(). When TCP receives new data, the contents of the ‘Network Buffer Descriptors’ is copied to an RX stream buffer. Outgoing data (FreeRTOS_send()) will be copied a the TX stream buffer. The advantage is that if you send many small messages, they will end up into a single contiguous buffer, and sent-out in maximum-size packets (MSS). So every connected TCP socket will get a TX and RX stream buffer. Once a stream buffer is created, its size is fixed. The default stream buffer sizes are defined with: ~~~~~ /* Define the size of Rx buffer for TCP sockets. */

define ipconfigTCPRXBUF_LEN ( 3 * 1460 )

/* Define the size of Tx buffer for TCP sockets. */

define ipconfigTCPTXBUF_LEN ( 2 * 1460 )

~~~~~ But indeed they can be adjusted at runtime, see: http://www.freertos.org/FreeRTOS-Plus/FreeRTOSPlusTCP/API/setsockopt.html Probably the easiest way is to use is FREERTOS_SO_WIN_PROPERTIES. It will overwrite the above defaults in a single call. Set the window properties before a socket gets connected: the listening socket that will accept() a new connection, or a client socket that will connect() to a remote one. Note that when accept() succeeds, all socket properties will be inherited by the new child socket, including stream buffer sizes (and also the local port number will be the same as its parent socket). Using BufferAllocation 1 or 2 ? Have you seen the difference between BufferAllocation1 and BufferAllocation2? Both modules will provide this number of Network Buffer Descriptors: ~~~~~
#define ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS    ??
~~~~~ Version 1 is more efficient, it reserves all buffer space by calling the user-provided vNetworkInterfaceAllocateRAMToBuffers() right after start-up. The advantage of version 1 is that all network buffer descriptors are guaranteed to be available and no more calls to pvPortMalloc() are necessary. In version 2 only the Descriptors are allocated at start-up, and the actual Buffers will be malloc’d when needed. Small messages will use small buffers. In general: platforms with more than enough (SD)RAM will use BufferAllocation_1.c. About the backlog parameter in listen() Looking at http://linux.die.net/man/2/listen :
int listen(int sockfd, int backlog);
The official meaning of backlog is the following: “The backlog argument defines the maximum length to which the queue of pending connections for sockfd may grow.” FreeRTOS is typically running on a smaller system with less resources and the definition is slightly (only slightly) different: “The backlog argument defines the maximum of connections that can be established to the socket simultaneously.” It is important to let +TCP send keep-alive messages in an idle connection: ~~~~~
/* Include support for TCP keep-alive messages. */
#define ipconfigTCP_KEEP_ALIVE              ( 1 )
#define ipconfigTCP_KEEP_ALIVE_INTERVAL     ( 20 ) /* in seconds */
~~~~~ Otherwise a service might become unreachable because of ‘dead’ connections. A TCP connection becomes dead if the remote device is switched off suddenly without properly closing the connection. If keep-alive messages are being used, +TCP device will quickly detect that the remote end doesn’t respond any more. An alternative to the above is it send keep-alive message at the user level. In a Telnet client for instance you could send empty lines (CR/LF) regularly to keep the remote end happy. Enough text for now. I hope it clarifies things, and if not, please ask! Regards

PIC32MX795 and FreeRTOS TCP/IP Stack

Thank you Hein for the explanations.

PIC32MX795 and FreeRTOS TCP/IP Stack

We are sending packets smaller than mss to optimize memory footpring. Looks like Nagle Algorithm is not implemented, we see 200ms delay between the outgoing packets on our http server implementation. There is one outgoing paket per ack. We use browser on microsoft pc https://support.microsoft.com/en-us/kb/214397/

PIC32MX795 and FreeRTOS TCP/IP Stack

Hi Dani, The Nagle algorithm has indeed not been implemented in the +TCP stack. Many real-time programmers tend to disable this feature because they want their messages to be delivered instantly. Can you make an estimate of how many packets of what size you expect to be sending? Normally the delayed ACK of 200 ms (on the remote end) shouldn’t bother you. And if it does bother, you’d have to look at the following: 1) The default size of the socket TX buffer: ~~~~~ /* Define the size of Tx buffer for TCP sockets. */ #define ipconfigTCP_TX_BUF_LEN ( 2 * 1460 ) ~~~~~ 2) Or maybe you’ve set it manually: ~~~~~ The socket option ‘FREERTOSSOSNDBUF’ ~~~~~ 3) Or you can set both the buffer- and WIN-sizes in a single call to FreeRTOS_setsockopt() : ~~~~~ Or the socket option ‘FREERTOSSOWIN_PROPERTIES’ ~~~~~ Explanation: Suppose that your TX buffer size is very small, 1000 bytes. You send 1000 bytes and the remote end delays the ACK for 200 ms. What you can do (without changing buffer sizes), is send 2 times 500 bytes. As there is no Nagle algorithm, the packets will be sent immediately and the remote end will reply with an ACK after the second packet. Regards.

PIC32MX795 and FreeRTOS TCP/IP Stack

Hi Daniel,
we see 200ms delay between the outgoing packets on our http server implementation. There is one outgoing paket per ack.
I already proposed a solution for the 200ms ACK problem in an email, I will repeat it here so that other users can also read it: Use the socket option ‘FREERTOSSOWIN_PROPERTIES’, because it allows you to set both the buffer size and WIN (as a multiple of MSS). This post has two attachments in a ZIP file: html_one.pcap : page loads in 9.3 seconds using a 730-byte buffer : ~~~~~ #define ipconfigTCPMSS ( 730 ) xWinProps.lTxBufSize = ipconfigTCPMSS; xWinProps.lTxWinSize = 1; ~~~~~ This is when WIN == 1 * MSS, very ineffective. +TCP must wait for 200 ms after every packet. html_two.pcap : page loads in 0.3 seconds using a 1072-byte buffer : ~~~~~ #define ipconfigTCPMSS ( 536 ) xWinProps.lTxBufSize = ( 2 * ipconfigTCPMSS ); xWinProps.lTxWinSize = 2; ~~~~~ Now WIN == 2 * MSS and the communication is pretty efficient. Regards.