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 librarySounds 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 nodeIn 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) CallLooks all goodFreeRTOS_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()
)
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.
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;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.But if I connect the FTP client to port 0 (instead of port 1)
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