Currently i’m using the library LWIP (v1.4.1) with LPC1788 and FreeRTOS(v7.5.3). But the LWIP stops work when occur many lost of packages in a slow network, and for restart work, i need to hard reset, and this is bad in my project. So, i decide to change LWIP for new FreeRTOS+TCP, and i will need help to do this.
First thing, i need to download this library https://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/index.html?
I start the implementation but have many problems on build.
In this files NetworkBufferManagement.h, NetworkInterface.h don’t found the define NetworkBufferDescriptor_t, so i saw the typedef on FreeRTOS_IP.h, so i insert the ‘#include “FreeRTOS_IP.h”’ on NetworkBufferManagement.h.
Now my file NetworkInterface.c for LPC17xx (in my case LPC1788) have many errors:
PINSEL_CFG_Type - unknown type
Emac_Config.Mode - has no member named Mode
BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkBuffer ) - conflicting types, in header was defined like BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkBuffer, BaseType_t xReleaseAfterSend );
I changed, remove the “#include ‘FreeRTOS_IP.h’” from NetworkBufferManagement.h and put on NetworkInterface.c and follow the changes for function xNetworkInterfaceOutput like alager12345 do here FreeRTOS+TCP with LPC17XX .
Now i need to rewrite the function xNetworkInterfaceInitialise.
I used the library NetworkInterface.c of LPC40x8 like Peter Wills said here on https://sourceforge.net/p/freertos/discussion/382005/thread/0d4d999eab/#2b40.
I got it the ip from dns using FreeRTOS_gethostbyname.
But now i have a problem.
I’m testing in a local connection, the board can connect to the server but a lot of times return the code -116 on connection, means pdFREERTOS_ERRNO_ETIMEDOUT but i don’t know why. Some times the connection works well, but lot of times not.
In my code i’m open one socket, open connection, try send, wait response, close connection, and delete this task. For redo the test i restart the board (is only a test now).
The only function in the library that can return a ETIMEDOUT is FreeRTOS_connect().
Now I’m curious about the code that you use: how the socket was created, what properties you have set, and what parameters are given to FreeRTOS_connect().
Normally FreeRTOS_connect() needs a time-out value of at least a few seconds.
Al time-outs are expressed in ticks. Please use pdMS_TO_TICKS() to translate from milliseconds to clock-ticks.
Hi Ulysses, here below your code along with a few changes and comments.
static void task_IOT(void *pvParameters)
struct freertos_sockaddr xRemoteAddress;
BaseType_t xAlreadyTransmitted = 0, xBytesSent = 0;
/* _HT_ : oops, you are assigning a literal string to a non-const char pointer.
That is "not done" but don't use it to receive data. The string might be stored in read-only flash. */
/* char *pcBufferToTransmit = "Hello World FreeRTOS-TCP LPC1788"; */
const char pcBufferToTransmit = "Hello World FreeRTOS-TCP LPC1788";
char pcBufferToReceive[ sizeof pcBufferToTransmit ];
size_t xTotalLengthToSend = strlen(pcBufferToTransmit);
TickType_t x10Seconds = pdMS_TO_TICKS( 10000u );
xRemoteAddress.sin_port = FreeRTOS_htons( 1500 );
xRemoteAddress.sin_addr = FreeRTOS_inet_addr_quick( 192, 168, 0, 10 );
xSocketSend = FreeRTOS_socket(FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP);
/* _HT_ it looks like you have not enabled configASSERT().
The variable 'xSocket' is not declared in this context. */
/* configASSERT( xSocket != FREERTOS_INVALID_SOCKET ); */
configASSERT( xSocketSend != FREERTOS_INVALID_SOCKET );
/* Let both send() and recv() block for at most 10 seconds. */
FreeRTOS_setsockopt( xUDPSocket, 0, FREERTOS_SO_SNDTIMEO, &( x10Seconds ), sizeof( x10Seconds ) );
FreeRTOS_setsockopt( xUDPSocket, 0, FREERTOS_SO_RCVTIMEO, &( x10Seconds ), sizeof( x10Seconds ) );
if( FreeRTOS_connect( xSocketSend, &xRemoteAddress, sizeof( xRemoteAddress ) ) == 0 )
/* How many bytes are left to send? */
xLenToSend = xTotalLengthToSend;// – xAlreadyTransmitted;
xBytesSent = FreeRTOS_send( /* The socket being sent to. */
/* The data being sent. */
&( pcBufferToTransmit[ xAlreadyTransmitted ] ),
/* The remaining length of data to send. */
/* ulFlags. */
if( xBytesSent >= 0 )
/* Data was sent successfully. */
xAlreadyTransmitted += xBytesSent;
/* Error – break out of the loop for graceful socket close. */
/* _HT_ Now shutdown the connection and wait for an acknowledgement. */
FreeRTOS_shutdown( xSocketSend, FREERTOS_SHUT_RDWR );
while( FreeRTOS_recv( xSocketSend, pcBufferToReceive, sizeof( pcBufferToReceive ), 0 ) >= 0 )
/* _HT_ when you use blocking sockets calls, there is no need to call vTaskDelay(). */
/* vTaskDelay(pdMS_TO_TICKS( 250 ) ); */
/* _HT_ Only call shutdown() and recv() if a socket is connected. */
/* The socket has shut down and is safe to close. */
FreeRTOS_closesocket( xSocketSend );
I think there are a lot of things that may be happening, from issues in the USB code, memory starvation, issues with USB interrupt priories, etc… If you are able to provide more information on the behaviour you observe we will be able to narrow down the possibilities. You say FreeRTOS_gethostbyname() works - so networking is working to start with - is that before or after USB activity? Does the issue happen just by creating the USB task, or do you actually need to plug in the USB cable? Once the issue has happened, does the TCP/IP stack still receive incoming packets? Etc.
FreeRTOS_gethostbyname () : mind you that if ipconfigUSE_DNS_CACHE is defined, the results of lookups will be stored in cache.
While testing, it is useful to call FreeRTOS_dnsclear() before each lookup.
USB disturbing: would it be possible to get TCP/IP totally running before adding USB? As Richard comments, there might be many reasons why one feature disturbs something else.
pcBufferToTransmit : i changed like you suggest after my last post.
Yes, i thinking the network is working well, but some buffer was corrupting in runtime.
First i call FreeRTOS_IPInit and after i create all tasks, including USB. The task IOT is called on vApplicationIPNetworkEventHook. The USB task initialize the driver USB, but not mount the until if it isn’t connected. The problem occour without plug usb. The USB used here is Mass Storage. The code called inside is this:
I put two debug on uart to see, on NetworkInterface.
pxNetworkDescriptor->xDataLength = xBytesReceived;
/* pvData is used to point to the network buffer descriptor that now references the received data. */
xRxEvent.pvData = (void *) pxNetworkDescriptor;
Always they are called, without USB the ‘DATARECEIVED’ appers two times, but when USB is enabled both 64 bytes, that is called three times, first 64 bytes, second the length of receive and third 64 bytes too.