Migration from lwip to freertos+tcp

rim72 wrote on Monday, June 11, 2018:

Dear AWS staffs.
Hi, my name is CHANG_KYUN RIM in KOREA(south).
I am struggling to finish my “FreeRTOS+TCP” migration project.

  1. My development environment
  1. MCU : STM32F407VGT , PHY : DP83848 ( RMII pinout )
  2. CubeMX(4.25) like this url :
    https://www.freertos.org/FreeRTOS-Plus/BSP_Solutions/ST/STM32CubeMX.html
  3. IDE : IAR(7.50.2)
  1. Questions that I want to solve
  1. IAR project (lwip) which codes are generated automatically by CubeMX(4.25), compiles very well and run very well on my board STM32F407VGT + DP83848.
  2. and I want to migrate my lwip project to FreeRTOS + TCP.
  3. To do this, I checked FreeRTOS(9.0.0) on CubeMX(4.25) and generated IAR Project automatically,
    And manually I added the TCP/IP Source Files to the IAR Project, like this url,
    https://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_Networking_Tutorial_Adding_Source_Files.html
  4. then, it compiles very very well, but dons’t work. Ping does’t reach to my board STM32F407VGT + DP83848.
  1. Of course, I already studied the projects you give, like below url.
  1. Truestudio project : compiles very well. (MII pinout)
    https://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP-IP_FAT_Examples_ST_STM32F407.html
  2. windows VC2010 : compiles very well and runs very well too.
    https://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_Echo_Clients.html
  3. for example, in the NetworkInterface.c file,
    I fixed the codes, like below lines.
    // xETH.Init.MediaInterface = ETH_MEDIA_INTERFACE_MII; //rim 2018.1.4
    xETH.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;
    it means that I tried a lot to make my board to work.
  1. How can I solve this problem ?.
    And if you need costs, I am willing to pay for it.
    Thanks in advance.

heinbali01 wrote on Monday, June 11, 2018:

Hi Chang_Kyn Rim, coudl you check if you see packets arriving at the lowest level, i.e. in NetworkInterface?

As you have a working Ethernet project for lwIP, can you compare the port settings of all pens related to the PHY and Ethernet? Do they all get the correction peripheral function?

I have this table:

                                        MII         RMII
	ETH_MDIO -------------------------> PA2		==	PA2
	ETH_MDC --------------------------> PC1		==	PC1
	ETH_PPS_OUT ----------------------> PB5			x
	ETH_MII_CRS ----------------------> PH2			x
	ETH_MII_COL ----------------------> PH3			x
	ETH_MII_RX_ER --------------------> PI10		x
	ETH_MII_RXD2 ---------------------> PH6			x
	ETH_MII_RXD3 ---------------------> PH7			x
	ETH_MII_TX_CLK -------------------> PC3			x
	ETH_MII_TXD2 ---------------------> PC2			x
	ETH_MII_TXD3 ---------------------> PB8			x
	ETH_MII_RX_CLK/ETH_RMII_REF_CLK---> PA1		==	PA1
	ETH_MII_RX_DV/ETH_RMII_CRS_DV ----> PA7		==	PA7
	ETH_MII_RXD0/ETH_RMII_RXD0 -------> PC4		==	PC4
	ETH_MII_RXD1/ETH_RMII_RXD1 -------> PC5		==	PC5
	ETH_MII_TX_EN/ETH_RMII_TX_EN -----> PG11	<>	PB11
	ETH_MII_TXD0/ETH_RMII_TXD0 -------> PG13	<>	PB12
	ETH_MII_TXD1/ETH_RMII_TXD1 -------> PG14	<>	PB13

Here below I attach the latest version of the STM32Fx driver. I am not sure which version you used?
The driver uses a generic driver for the PHY. The DP83848 will be properly recognised.
Can you first check if the recognition and initialisation of the PHY works well?

heinbali01 wrote on Monday, June 11, 2018:

… and here is the promised attachment: NetworkInterface_STM32Fx.zip
which contains the latest driver for STM32Fx ( both F4 and F7 ).

rim72 wrote on Thursday, June 14, 2018:

Hein, thanks for your help.
And I am trying to compile the NetworkInterface_STM32Fx.zip files that you gave.
But in the networkinterface.c file, 23 compile-errors come out.(refer to the attached jpg file ).
I am using IAR c-compiler.
Which compiler do you recommend ?

rim72 wrote on Thursday, June 14, 2018:

another capture !!

heinbali01 wrote on Thursday, June 14, 2018:

It is easier when you write the error messages as ASCII text, so that I can copy/paste the text.

Can you make sure that NetworkInterface.c includes these two header files properly:

portable\NetworkInterface\STM32Fxx\stm32fxx_hal_eth.h
portable\NetworkInterface\include\phyHandling.h

It looks like these two are missing.

Which compiler do you recommend ?

Just take the compiler and IDE that you like.
FreeRTOS and +TCP have been tested with all major compilers, including IAR

rim72 wrote on Friday, June 15, 2018:

Dear, Hein.
I referred to this URL :
https://sourceforge.net/p/freertos/discussion/382005/thread/5e32c8c6/?limit=25#c2c8/1de9
And succeed to make my board work(^^).
Thanks.

rim72 wrote on Wednesday, July 11, 2018:

–> NEW problem.

Dear, Hein.

AS I said, I succeed to make my board work.
Actually, it means that my board works very well as a DHCP client.
I could check it on my DHCP server.
But problem is that below function doesn’t work (of course, it works very well in windows simulation VC2010 project ).
As you can see, “FreeRTOS_sendto” UDP function is the key function and is used in the DHCP client code too. However, it seems that this function does not work here in below function.

What will be the cause??

Thanks in advance.

////////////////// below function //////////////////////////////////////
static void prvSimpleZeroCopyUDPClientTask( void pvParameters )
{
Sockett xClientSocket;
uint8t pucUDPPayloadBuffer;
struct freertossockaddr xDestinationAddress;
BaseTypet lReturned;
uint32t ulCount = 0UL, ulIPAddress;
const uint32t ulLoopsPerSocket = 100UL;
const char pcStringToSend = "Server received (using zero copy): Message number ";
const TickTypet x150ms = 150UL / portTICKPERIODMS;
/ 15 is added to ensure the number, \r\n and terminating zero fit. /
const sizet xStringLength = strlen( pcStringToSend ) + 15;
*
/* Remove compiler warning about unused parameters. */
( void ) pvParameters;

/* It is assumed that this task is not created until the network is up,
so the IP address can be obtained immediately.  store the IP address being
used in ulIPAddress.  This is done so the socket can send to a different
port on the same IP address. */
//FreeRTOS_GetAddressConfiguration( &ulIPAddress, NULL, NULL, NULL );

/* This test sends to itself, so data sent from here is received by a server
socket on the same IP address.  Setup the freertos_sockaddr structure with
this nodes IP address, and the port number being sent to.  The strange
casting is to try and remove compiler warnings on 32 bit machines. */
//xDestinationAddress.sin_addr = ulIPAddress;
//xDestinationAddress.sin_port = ( uint16_t ) ( ( uint32_t ) pvParameters ) & 0xffffUL;
//xDestinationAddress.sin_port = FreeRTOS_htons( xDestinationAddress.sin_port );

xDestinationAddress.sin_port = FreeRTOS_htons( echoECHO_PORT );
xDestinationAddress.sin_addr = FreeRTOS_inet_addr_quick( configECHO_SERVER_ADDR0, 
                                                            configECHO_SERVER_ADDR1,
                                                            configECHO_SERVER_ADDR2,
                                                           	configECHO_SERVER_ADDR3 );

//for( ;; )
//{
	/* Create the socket. */
	xClientSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP );
	configASSERT( xClientSocket != FREERTOS_INVALID_SOCKET );

	/* The count is used to differentiate between different messages sent to
	the server, and to break out of the do while loop below. */
	ulCount = 0UL;

	do
	{
		/* This task is going to send using the zero copy interface.  The
		data being sent is therefore written directly into a buffer that is
		passed into, rather than copied into, the FreeRTOS_sendto()
		function.

		First obtain a buffer of adequate length from the IP stack into which
		the string will be written.  Although a max delay is used, the actual
		delay will be capped to ipconfigMAX_SEND_BLOCK_TIME_TICKS, hence
		the do while loop is used to ensure a buffer is obtained. */
		do
		{
		} while( ( pucUDPPayloadBuffer = ( uint8_t * ) FreeRTOS_GetUDPPayloadBuffer( xStringLength, portMAX_DELAY ) ) == NULL );

		/* A buffer was successfully obtained.  Create the string that is
		sent to the server.  First the string is filled with zeros as this will
		effectively be the null terminator when the string is received at the other
		end.  Note that the string is being written directly into the buffer
		obtained from the IP stack above. */
		memset( ( void * ) pucUDPPayloadBuffer, 0x00, xStringLength );
		sprintf( ( char * ) pucUDPPayloadBuffer, "%s%lu\r\n", pcStringToSend, ulCount );

		/* Pass the buffer into the send function.  ulFlags has the
		FREERTOS_ZERO_COPY bit set so the IP stack will take control of the
		buffer rather than copy data out of the buffer. */
		lReturned = FreeRTOS_sendto( xClientSocket,  				/* The socket being sent to. */
                                                ( void * ) pucUDPPayloadBuffer,             /* A pointer to the the data being sent. */
					    strlen( ( const char * ) pucUDPPayloadBuffer ) + 1, /* The length of the data being sent - including the string's null terminator. */
                                                FREERTOS_ZERO_COPY, 			/* ulFlags with the FREERTOS_ZERO_COPY bit set. */
                                                &xDestinationAddress, 			/* Where the data is being sent. */
                                                sizeof( xDestinationAddress ) );

		if( lReturned == 0 )
		{
			/* The send operation failed, so this task is still responsible
			for the buffer obtained from the IP stack.  To ensure the buffer
			is not lost it must either be used again, or, as in this case,
			returned to the IP stack using FreeRTOS_ReleaseUDPPayloadBuffer().
			pucUDPPayloadBuffer can be safely re-used after this call. */
			FreeRTOS_ReleaseUDPPayloadBuffer( ( void * ) pucUDPPayloadBuffer );
		}
		else
		{
			/* The send was successful so the IP stack is now managing the
			buffer pointed to by pucUDPPayloadBuffer, and the IP stack will
			return the buffer once it has been sent.  pucUDPPayloadBuffer can
			be safely re-used. */
                      
                            //vTaskDelay(1000); //rim
		}

		ulCount++;
		
	    vTaskDelay(4000);


	} while( ( lReturned != FREERTOS_SOCKET_ERROR ) && ( ulCount < ulLoopsPerSocket ) );

	FreeRTOS_closesocket( xClientSocket );

	/* A short delay to prevent the messages scrolling off the screen too
	quickly. */
	vTaskDelay( x150ms );
//} for

}
/-----------------------------------------------------------/