FreeRTOS-Plus-TCP - Support for new STM32Fxx Ethernet HAL

Is there a plan to support the new STM32Fxx Ethernet HAL implementation?
The current ST CubeMX version has no option to auto-generate the legacy Ethernet HAL implementation. This behavior breaks the FreeRTOS-Plus-TCP port for STM32Fxx.

I’m not allowed to put a link here, so pls search for:
Ethernet HAL Driver reworked by ST and available in 22Q1

When we created the ST32Fx driver, we used a copy of the HAL files. This would decrease the dependency on “the current HAL release”. It has been compiled and used with many versions of the HAL release.

Please have a look at this stm32fxx_hal_eth.c. When compiling, it is recommended to hide similar files in your HAL library.

What you can also try is using this experimental driver. It makes full use of the HAL drivers that you provide.

The current ST CubeMX version has no option to auto-generate the legacy Ethernet HAL implementation

The FreeRTOS+TCP library doesn’t make use of those possibilities.

1 Like

Hello,
I am trying to port FreeRTOSplus TCP to my STM32F746 FreeRTOS project (v. 202212.01). I have successfully ported FreeRTOS and have few task running. When I tried to port plusTCP using provided steps for FreeRTOSplus TCP.
I am getting a lot of build errors, and I don’t know where I am going wrong.
Most of the build errors are of HAL Ethernet APIs of STM32 drivers in Network interface.c .

Others are for FreeRTOSplus TCP library files.

  • xApplicationDNSQueryHook (dns parser)
  • vApplicationIPNetworkEventHook
  • xApplicationGetRandomNumber
  • ulApplicationGetNextSequenceNumber (tcp state handling)
  • FreeRTOS_debug_printf (these i can comment out, right?)

My end goal is to make HTTP Client over ethernet on STM32.
Are there any other steps that I can follow specifically for STM32?

Have you had a look at this readme.md?

Basicallay it says that you must remove or rename all existing versions of *_hal_eth.[ch]. Some are similar but too different to be useful.

Others are for FreeRTOSplus TCP library files.

  • xApplicationDNSQueryHook (dns parser)
  • vApplicationIPNetworkEventHook
  • xApplicationGetRandomNumber
  • ulApplicationGetNextSequenceNumber (tcp state > handling)
  • FreeRTOS_debug_printf (these i can comment out, right?)

Please check the documentation on each of the missing application hooks.

Yes, HAL related errors are fixed now after enabling #define HAL_ETH_MODULE_ENABLED
But for the mentioned below function :

After looking for these functions in documentation I found out that

Callback functions are implemented by the application writer, but called by the TCP/IP stack

But in which file do I need to provide these definitions and where the prototypes should be placed?
Also , looking at this repo, is it really important to include all of the files ?
Are there any sample for stm32 that’s what I am looking for…

@ashvajit wrote:

Also , looking at this repo, is it really important to include all of the files ?

FreeRTOS+TCP has 42 basic files, plus a few extra from source/portable.

I normally do not make a selection but add a use a wildcard in a makefile:

    # add all library files
    C_SRCS += /
        $(wildcard $(PLUS_TCP_PATH)/source/*.c)

    # add files from portable
    C_SRCS += /
	    $(PLUS_TCP_PATH)/source/portable/BufferManagement/BufferAllocation_1.c \
		$(PLUS_TCP_PATH)/source/portable/NetworkInterface/STM32Fxx/NetworkInterface.c \
		$(PLUS_TCP_PATH)/source/portable/NetworkInterface/STM32Fxx/stm32fxx_hal_eth.c

Library files that are not needed will not be compiled, depending on macros like ipconfigUSE_IPv6 and ipconfigUSE_DNS.

I wrote earlier:

Please check the documentation on each of the missing application hooks.

An easy way to find the proper documentation is to open a search machine and look for “FreeRTOS xApplicationDNSQueryHook”.

This is how I just found the following pages:

vApplicationIPNetworkEventHook_Multi
vApplicationIPNetworkEventHook
xApplicationDNSQueryHook_Multi
xApplicationDNSQueryHook
xApplicationGetRandomNumber
ulApplicationGetNextSequenceNumber

The functions ending with _Multi are used when you use multiple endpoints, that is when ipconfigIPv4_BACKWARD_COMPATIBLE is not defined.

Indeed these functions are “application hooks”, also called “callbacks”. Take care when using them because the hook is called from the IP-task. It may have a higher task priority, and it may have less stack space. Also it is not allowed to call the +TCP API’s, because the code is running in the IP-task.

But in which file do I need to provide these definitions and where the prototypes should be placed?

I normally put them in a module where it is used. Your are free to choose.

Are there any sample for stm32 that’s what I am looking for…

I made a few Makefile projects to test the IP-stack and other software. You can find it here on github here.
Today I upgraded the stm32F40 project. I will also upgrade the stm32F7 project. I will report here when it is ready.

@ashvajit wrote:

Are there any sample for stm32 that’s what I am looking for…

I upgraded my stm32F7 project.
I tested it on an evaluation board 746G disco.

Both STM32F projects are now using the latest kernel (V10.5.1) and FreeRTOS+TCP (V4.0.10).

Please tell us if it helps for you.

I am able to build the project now. I will try to use components from this project to resolve my build errors.

If you want to try to make and run the whole project, you can clone the repo:

    git clone https://github.com/htibosch/freertos_plus_projects.git c:/temp/plus_projects

and the run make from the stm32F7 directory:

c:\temp\plus_projects\plus\stm32F7

You can find .project and .cproject here. They can be used to import a project into Eclipse.

Yes, I did build the project from this and also used the requierd hooks from this project and added to my project and it is now not giving any build errors. But I am not able to ping to my board using my PC.
I suspect that ethernet or PHY handling drivers are not initialized properly.

I have initialized as shown below in main() .

static const uint8_t ucIPAddress[ 4 ] = { 10, 25, 10, 72 };
static const uint8_t ucNetMask[ 4 ] = { 255, 255, 255, 0 };
static const uint8_t ucGatewayAddress[ 4 ] = { 10, 25, 10, 1 };
static const uint8_t ucDNSServerAddress[ 4 ] = { 8, 8, 8, 8 };
 status = FreeRTOS_IPInit(ucIPAddress,ucNetMask,ucGatewayAddress,ucDNSServerAddress,ucMACAddress);
  configASSERT(status == pdPASS);

  vTaskStartScheduler();

#define HAL_ETH_MODULE_ENABLED

is enabled in stm32fxx_hal_conf.h file and also added ethernet MSP_INIT and DeInit functions in

void HAL_ETH_MspInit(ETH_HandleTypeDef* heth)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(heth->Instance==ETH)
  {
  /* USER CODE BEGIN ETH_MspInit 0 */

  /* USER CODE END ETH_MspInit 0 */
    /* Enable Peripheral clock */
    __HAL_RCC_ETH_CLK_ENABLE();

    __HAL_RCC_GPIOG_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**ETH GPIO Configuration
    PG14     ------> ETH_TXD1
    PG13     ------> ETH_TXD0
    PG11     ------> ETH_TX_EN
    PC1     ------> ETH_MDC
    PA1     ------> ETH_REF_CLK
    PC4     ------> ETH_RXD0
    PA2     ------> ETH_MDIO
    PC5     ------> ETH_RXD1
    PA7     ------> ETH_CRS_DV
    */
    GPIO_InitStruct.Pin = GPIO_PIN_14|GPIO_PIN_13|GPIO_PIN_11;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF11_ETH;
    HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF11_ETH;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF11_ETH;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* Peripheral interrupt init */
    HAL_NVIC_SetPriority(ETH_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(ETH_IRQn);
  /* USER CODE BEGIN ETH_MspInit 1 */

  /* USER CODE END ETH_MspInit 1 */
  }
}

Also, I want to mention that I am using LAN8742 IC which is present on the discovery board and not enabling ethernet from CubeMX which I was doing when not working with RTOS.
I am not sure where I am going wrong as this MSP function is being called when I was debugging.

The autogenerated pins are usually wrong, double check those with the datasheet for your board.

Also make sure that the PHY configuration - MII vs. RMII and PHY address match your board design.

And beside that, also please check if your version of HAL_ETH_MspInit() is really called from this stm32fxx_hal_eth.c.
Sometimes there is a weak function that is called in stead.

@ashvajit wrote:

Also, I want to mention that I am using LAN8742

You may want to step go through xPhyDiscover() and see if the LAN8742 gets detected.

I have verified the connection from my BareMetal working project.
Thanks :slightly_smiling_face: ,

Yes the function is called
MSP_Init

Yes, I am detecting a device here and ID matches what is defined in header, phyIDs instance values are shown in snap. But this function is being called repeatedly.

Does the ISR for ETH_IRQ call any FreeRTOS API? Also, can you share your FreeRTOSConfig.h?