FreeRTOS+TCP multi use and examples

Hi I have created a project based on Zynq platform with FreeRTOS+TCP multi, but I don’t found any documentation or example about the use of it. I’m new to FreeRTOS and TCP and i need some helps to start. Are there some documentations or examples on the web? Thanks for help

FreeRTOS+TCP multi use and examples

There are some examples here: https://www.freertos.org/FreeRTOS-Plus/FreeRTOSPlusTCP/TCPNetworkingTutorial.html Also, it might be useful to read about Berkeley sockets (use google). Good luck.

FreeRTOS+TCP multi use and examples

Hi Ken I know this tutorial and I’m using it to test my ethernet port; but my board has two ethernet port and the FreeRTOS+TCP can only manage a single port (i think). In FreeRTOS+TCP download page i found the ‘180222-freeRTOS-plus-TCP-Multi.zip’ file that contains TCP source files to manage more than one ethernet port. Unfortunately in this file there are not documentation nor example.

FreeRTOS+TCP multi use and examples

I see what you mean. Some time ago I have received some test code (with zynqmain.c) from Hein Tibosch. I have used this test code as a starting point. I think Hein can provide you this zynqmain.c test code. The version I have is not up to date.

FreeRTOS+TCP multi use and examples

Hi Claudio, I’m sorry that it takes so much time before FreeRTOS+TCP /multi comes out officially, but eventually it will! It is true that there is no documentation yet. The library has been well tested though, especially by Ken Chang, who is replying here above. He did not make use of IPv6 though, only IPv4. I will attach 3 files: FreeRTOS-Plus-TCP_multi_30_aug_2018.7z : the latest sources, which are only slightly different from the /multi release on freertos.org/tcp plus_tcp_multi_v2.pdf : a short description of what makes /multi different zynq_main.c : an example that uses multiple NIC’s Please define ipconfigMULTI_INTERFACE in your FreeRTOSIPConfig.h, if you want to use the /multi software. I have some projects for testing that can either be linked with the normal FreeRTOS+TCP library, or with FreeRTOS+TCP /multi, depending on the value of ipconfigMULTI_INTERFACE, 0 or 1. If you have any questions, please ask them in this post.

FreeRTOS+TCP multi use and examples

Hi Hein and hi Ken Thanks a lot for your help. Now i am working on a single port using +TCP in order to understand the TCP library (i am new to the argument), then i will try to use multi library with the second ethernet port. Best regards

FreeRTOS+TCP multi use and examples

Now i am working on a single port using +TCP in order to understand the TCP library
Sounds good. Remember that ipconfigMULTI_INTERFACE can be helpful to make the transition from single to multi more gradual

FreeRTOS+TCP multi use and examples

Hi Hein I toke a look in zynqmain.c file and I understood the initialization sequence. Now my question is about the instantiation of one or more sockets. Do i need to use the standard TCP functions (FreeRTOSsocket, FreeRTOSbind, etc)? If yes, how can i create a socket for a particular ethernet channel? If I call FreeRTOSsocket(), the socket is connected to ethernet #0 or ethernet #1? I do not find the connection point between the standard TCP library funtions and the data structures used to manage multi interface. Thanks and best regards

FreeRTOS+TCP multi use and examples

Hello Claudio, we have tried to make the change to /multi as intuitively as possible. Sockets are not bound to a particular interface, with the exception of TCP sockets that are connected with a peer. On a laptop, I can bind several sockets to the same port number, for instance: ~~~ Socket 1: 192.168.2.5 port 23 // LAN Socket 2: 36.75.115.247 port 23 // Internet Socket 3: 10.0.5.112 port 23 // WiFi ~~~ When I put each socket in listening mode, they will each receive connections on their network. Another way to go is bind a sockt to 0.0.0.0, which stands for “any network”. That is the way to go in FreeRTOS+TCP /multi. Every ( UDP or TCP ) port can only be bound once: ~~~ Socket 1: 0.0.0.0 port 23 // LAN + Internet + WiFi ~~~ When the following statement succeeds: ~~~ struct freertossockaddr xAddress; Sockett xSocket = FreeRTOSaccept( xServerSocket, &xAddress, ( socklent )sizeof xAddress ); ~~~ the connected socket xSocket will only use the network interface that leads to it’s peer. About UDP : when sending ( or replying to ) a packet, the stack will find the best matching interface. For broadcast packets, all interfaces will be addressed. In short: the application will not change much when moving from +TCP /single to /multi

FreeRTOS+TCP multi use and examples

Hi Hein if I understand, the socket process is tied to port number instead to IP address, then I need to create a socket for each port I intend to use. For example, in my case I have 2 port: the first at IP 192.168.0.0 and the second at 192.168.1.0. The first port is used for the connection of a telnet client (port 23) and a HTTP client (port 80), while the second port for a FTP client (port 21). So I need to do the following: 1) Create 2 network interface and 2 network node. 2) Call FreeRTOSIpStart function 3) Create a socket set (FreeRTOSCreateSocketSet). 4) Create my 3 socket (for telnet, HTTP, FTP) and initialize them (bind, _setsockopt, _listen) 5) Add sockets with FreeRTOSFDSET(). 6) Create a process(loop) for socket acceptation for each of my sockets (FreeRTOSaccept) If a connection is requested to a port then FreeRTOS_accept function return a socket structure pointer for this connection. Is my procedure correct? But if I connect the FTP client to port 0 (instead of port 1) and try to connect the client to 192.168.0.0:21, the FreeRtosaccept function will accept the connection? If yes, if I want to know the IP address of my connection in order to distinguish the port (and eventually write an error message) can I use the address structure filled by FreeRTOSaccept function? I hope I was clear in my exposition. Thanks and best regards

FreeRTOS+TCP multi use and examples

Hi Claudio,
if I understand, the socket process is tied to port number instead to IP address, then I need to create a socket for each port I intend to use.
Indeed, you create a socket for each port number and not for each IP-address + port-number combination. Just like you would in +TCP /single.
For example, in my case I have 2 port: the first at IP 192.168.0.0 and the second at 192.168.1.0.
Those numbers are IP-addresses, not port numbers.
The first port ( HT: IP-address ) is used for the connection of a telnet client (port 23) and a HTTP client (port 80), while the second port ( IP-address ) for a FTP client (port 21).
You will need 3 sockets and bind them to:
0.0.0.0 prt 23
0.0.0.0 prt 80
0.0.0.0 prt 21
So I need to do the following: 1) Create 2 network interface and 2 network node
In the software the nodes are called end-points The application defines one or more interfaces, and each interface can have one or more end-points ( or IP-addresses ).
2) Call FreeRTOS_IPStart() function 3) Create a socket set ( FreeRTOS_CreateSocketSet ). 4) Create my 3 socket (for telnet, HTTP, FTP) and initialize them ( bind(), setsockopt(), xlisten() ) 5) Add sockets with FreeRTOSFD_SET(). 6) Create a process(loop) for socket acceptation for each of my sockets ( FreeRTOS_accept() )
Looks all good
If a connection is requested to a port then FreeRTOS_accept() function return a socket structure pointer for this connection.
True. FreeRTOS_accept() will return a new socket. Note that this socket will inherit all properties of the parent socket ( i.e. the listening socket ). Once the connection is closed, the socket must be freed by calling FreeRTOS_closesocket(). It is important to set the buffer properties of the parent socket, because once a child-socket is receiving data, the receive buffer-size ( FREERTOS_SO_RCVBUF ) can not be changed any more.
Is my procedure correct?
Looks OK to me.
But if I connect the FTP client to port 0 (instead of port 1)
Where do you bind this socket? On a host? Normally you bind a client socket to port 0, which means a random ( anonymous ) port number. Binding to a low ( non-zero ) port number will most probably fail because they are reserved for the OS. Normally: ● A server socket is bound to a well-known ( non-zero ) port number ● A client socket is bound to port number 0 But this rule is not obligatory. One example: FTP in PASSIVE mode, opens a server socket for a data connection, which is bound to port 0 in order to get a random port number. The client will connect to this socket. The server socket only expects a single client, so xBacklog equals 1:
FreeRTOS_listen( xServerSocket, 1 );
and try to connect the client to 192.168.0.0:21, the FreeRTOS_accept() function will accept the connection?
Yes indeed. Note that you can determine the maximum number of connected clients to a socket. See the second parameter of FreeRTOS_listen(): xBacklog.
If yes, if I want to know the IP address of my connection in order to distinguish the port (and eventually write an error message) can I use the address structure filled by FreeRTOS_accept() function?
Yes the parameter pxAddress of FreeRTOS_accept() will contain the address of the remote peer (in network-endian order).

FreeRTOS+TCP multi use and examples

Hi Hein Thank you for your response, now is more clear.
But if I connect the FTP client to port 0 (instead of port 1)
Where do you bind this socket? On a host? Normally you bind a client socket to port 0, which means a random ( anonymous ) port number. Binding to a low ( non-zero ) port number will most probably fail because they are reserved for the OS. Normally: ● A server socket is bound to a well-known ( non-zero ) port number ● A client socket is bound to port number 0 But this rule is not obligatory.
About port mentioned in my post was my mistake, I meant physical port 0 and port 1. On my board the TCP interface is the server and the board is connected to a windows based PC. On the PC I want to use telnet or filezilla or Web browser application for communication. Moreover I get some compilation error (both in /single and /multi) if I compile a C++ based project, while in a C based project there are not problems. I have modified the sources to correct the problem. Example: -file xemacpsifhw.c ~~~ void cleandmatxdescs(xemacpsif_s *xemacpsif) { int index; unsigned char *ucTxBuffer; /* Clear all TX descriptors and assign uncached memory to each descriptor. “txspace” points to the first available TX buffer. */ ucTxBuffer = xemacpsif->txspace; for( index = 0; index < ipconfigNICNTXDESC; index++ ) { xemacpsif->txSegments[ index ].address = ( uint32t )ucTxBuffer; xemacpsif->txSegments[ index ].flags = XEMACPSTXBUFUSED_MASK;

if( ipconfigZEROCOPYTX_DRIVER != 0 )

    // FIXME crs!!! modified for compilation error in c++
pxDMA_tx_buffers[ index ] = ( unsigned char * )NULL;
//pxDMA_tx_buffers[ index ] = ( void* )NULL;

else

    pxDMA_tx_buffers[ index ] = ( void* )( ucTxBuffer + TX_OFFSET );

endif

    ucTxBuffer += xemacpsif->uTxUnitSize;
}
xemacpsif->txSegments[ ipconfigNIC_N_TX_DESC - 1 ].flags =
    XEMACPS_TXBUF_USED_MASK | XEMACPS_TXBUF_WRAP_MASK;
} ~~~ -file xemacpsifhw.c ~~~ // FIXME crs!!! added include file for c++ compilation error

include “NetworkInterface.h”

~~~ -file xemacpsifphyspeed.c ~~~ // FIXME crs!!! added static (or move into PhySetup?) for c++ compilation error //static unsigned linkspeed; unsigned PhySetup (XEmacPs *xemacpsp) { unsigned long convpresent = 0; unsigned long convspeeddupsetting = 0; unsigned long convphyaddr = 0; unsigned link_speed; ~~~ Similar problem with FreeRTOS+FAT files: ffioman.c in (function FFBlockRead and FFBlockWrite) ~~~ // FIXME crs!!! aggiunto cast a pxBuffer per errori compilazione in c++ slRetVal = pxIOManager->xBlkDevice.fnpReadBlocks((uint8t*) pxBuffer, ulSectorLBA, ulNumSectors, pxIOManager->xBlkDevice.pxDisk ); ~~~ fffile.c ~~~ static FFFILE *prvAllocFileHandle( FF_IOManager_t *pxIOManager, FF_Error_t *pxError ) { FF_FILE *pxFile; // FIXME crs!!! inserito cast (FFFILE*) per errore compilazione in c++ pxFile = (FFFILE *)ffconfigMALLOC( sizeof( FF_FILE ) ); ~~~ Best regards