FreeRTOS+TCP for LPC17xx

Hi,

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:

  1. PINSEL_CFG_Type - unknown type
  2. Emac_Config.Mode - has no member named Mode
  3. BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkBuffer ) - conflicting types, in header was defined like BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkBuffer, BaseType_t xReleaseAfterSend );

and many other errors in this file.

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.

Hi,

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 @htibosch

This is my task created after network connection.
With this code, the connection with local server was opened but don’t send nothing because on FreeRTOS_connect return pdFREERTOS_ERRNO_ETIMEDOUT.

static void task_IOT(void *pvParameters){
Socket_t xSocketSend;
struct freertos_sockaddr xRemoteAddress;
BaseType_t xAlreadyTransmitted = 0, xBytesSent = 0;
char *pcBufferToTransmit = "Hello World FreeRTOS-TCP LPC1788";
size_t xTotalLengthToSend = strlen(pcBufferToTransmit);
size_t xLenToSend;

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);
configASSERT( xSocket != FREERTOS_INVALID_SOCKET );

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. */
			xSocketSend,
			/* The data being sent. */
			&( pcBufferToTransmit[ xAlreadyTransmitted ] ),
			/* The remaining length of data to send. */
			xLenToSend,
			/* ulFlags. */
			0 );

	if( xBytesSent >= 0 )
	{
		/* Data was sent successfully. */
		xAlreadyTransmitted += xBytesSent;
	}
	else
	{
		/* Error – break out of the loop for graceful socket close. */
	}
}

FreeRTOS_shutdown( xSocketSend, FREERTOS_SHUT_RDWR );

while( FreeRTOS_recv( xSocketSend, pcBufferToTransmit, xTotalLengthToSend, 0 ) >= 0 ){
	vTaskDelay(pdMS_TO_TICKS( 250 ) );
}

/* The socket has shut down and is safe to close. */
FreeRTOS_closesocket( xSocketSend );

DEBUGOUT("task_IOT stop\n");
vTaskDelete(hdl_IOT);
}

Hi @htibosch

I saw other think now when i was debugging with jtag step-by-step inside FreeRTOS_connect the code stablished connection and send now. I think is the period of waiting for stablish connection.

Another thing, when is waiting the response from server some times occour an HardFault. This part.

while( FreeRTOS_recv( xSocketSend, pcBufferToTransmit, xTotalLengthToSend, 0 ) >= 0 ){
		vTaskDelay(pdMS_TO_TICKS( 250 ) );
}

Hi,

Works now.
I put a vTaskDelay(2000) before FreeRTOS_connect and solve the problem of timeout error.

Hi Ulysses, here below your code along with a few changes and comments.


static void task_IOT(void *pvParameters)
{
    Socket_t xSocketSend;
    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);
    size_t xLenToSend;

    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. */
                xSocketSend,
                /* The data being sent. */
                &( pcBufferToTransmit[ xAlreadyTransmitted ] ),
                /* The remaining length of data to send. */
                xLenToSend,
                /* ulFlags. */
                0 );

        if( xBytesSent >= 0 )
        {
            /* Data was sent successfully. */
            xAlreadyTransmitted += xBytesSent;
        }
        else
        {
            /* 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 );

    DEBUGOUT("task_IOT stop\n");
    vTaskDelete(hdl_IOT);
}

I hope it helps to understand it better.

Hi @htibosch,

About your suggestions.

  • pcBufferToTransmit : i changed like you suggest after my last post.
  • pcBufferToReceive : i done it too.
  • configASSERT( xSocket != FREERTOS_INVALID_SOCKET ) : i hadn’t see this, thanks.
  • FreeRTOS_setsockopt : i had changing this on the defines at FreeRTOSIPconfig, but like you show is best.
  • “Only call shutdown() and recv() if a socket is connected.” : I saw this, and i though strange, but was in this way on examples. However i will change this.

Hi,

Now i have another problem, when i enabled the task of USB the FreeRTOS+TCP don’t receive nothing. But the function FreeRTOS_gethostbyname works.

what may be happening?

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.
  • pcBufferToReceive : i done it too.

Does this code work well now?

yes, work well now without USB.

But that’s after reboot? restart all system.

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:

USB_Init(FlashDisk_MS_Interface.Config.PortNumber, USB_MODE_Host);
fs_usb = malloc(sizeof (FATFS));

I don’t know, because i’m not a expert on ethernet, i tried get but i didn’t catch nothing. I saw that the interrupt keeps working.

I will create a repo for share the code.

Hi,

I put two debug on uart to see, on NetworkInterface.

memcpy(pxNetworkDescriptor->pucEthernetBuffer, 
(void*)VacEnetData.RxDescriptor[ConsumeIdx].Packet, xBytesReceived);;
pxNetworkDescriptor->xDataLength = xBytesReceived;
DEBUGOUT("DATARECEIVED:%d\n",pxNetworkDescriptor->xDataLength);
/* pvData is used to point to the network buffer descriptor that now references the received data. */
xRxEvent.pvData = (void *) pxNetworkDescriptor;
DEBUGOUT("DATA:%s\n",xRxEvent.pvData);

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.

Here are the source.
https://bitbucket.org/ulyssesfonseca/freertos-tcp-lpc1788

Hi,

I tried, create USB task before IOT was working. So after the first connection success, send and receive, i create the task USB. But after this the IOT don’t receive more.

Hi,

Problem solved.
What was happend, the configTOTAL_HEAP_SIZE is few for the new tasks, so i increase this value and work.
Thanks for all helped me.

1 Like

Very good, thanks for reporting back.

Does that mean that the network interface for the LPC17xx works well?

What was happend, the configTOTAL_HEAP_SIZE is few for the new tasks

In all new network interfaces I am adding logging about essential resources: free heap size, free network buffers, etc. The logging is done from a function prvMonitorResources().

That function is only enabled when logging is enabled (ipconfigHAS_PRINTF).

1 Like

Hi @htibosch

Does that mean that the network interface for the LPC17xx works well?

Yes, using the driver of LPC40x8.

In all new network interfaces I am adding logging about essential resources: free heap size, free network buffers, etc. The logging is done from a function prvMonitorResources() .
That function is only enabled when logging is enabled ( ipconfigHAS_PRINTF ).

I’ll see this.

I don’t know if i can do this here, or create a new topic. But i need change DHCP and static in runtime.

1 Like

I’m going to mark this question as solved to help anyone else in the future to discover the solution. Please feel free to create a new topic @ulysses. Thank you

1 Like