FreeRTOS+TCP Multi: One Interface with two different IP Addresses (Two or more endpoints)

Hello Team,

Platform: STM32H7 Series

I would like to know if it’s possible to have support of two different IP addresses using FreeRTOS+TCP Multi on a STM32H7 Platform.

Here is the link of the STM Ethernet module:

I’m wondering if we have kind of VLAN support on FreeRTOS now.

Any help will be appreciated!

Thanks

To be clear, are you asking if you can have two IP addresses assigned to the same MAC address?

We have one EMAC on STM32. So we will have one MAC address. Actually, I’m not sure if we can have more than one mac addresses in that EMAC of STM32.

But yeah support two IP addresses on same MAC address or different MAC address if supported in EMAC of STM32.

Basically, I want support of two different IP Addresses on single physical port. Once it’s working, the plan is to have a switch and route the packets to the desired MAC.

The new version of FreeRTOS+TCP will allow the use of multiple interfaces, multiple IP-addresses and optionally IPv6.
Each interface will have one or more end-points.

An end-point is not only an IP-address, it also has properties like:

  • IP version (4 or 6)
  • Net mask
  • Gateway address
  • DNS server address
  • MAC-address
  • DHCP- or RA-client (RA = Router Advertisement)

Suppose you have one Network Interface. It can have several end-points, e.g.:

  1. 192.168.1.23 (assigned by DHCP), with gateway
  2. 2001:470:36:a6::1002 (obtained from RA)
  3. 172.16.0.15 (static IP-address)

It is allowed to have two end-points with the same netmask, e.g. 192.168.1.10 and 192.168.1.11 (with netmask 192.168.2.x). This design is not recommended, because the IP stack can not determine which end-point to use (x.10 or x.11). It will take the first matching end-point.

Is it possible to share a MAC-address among IP-addresses? Yes! That is no problem. This is also sometimes called IP-aliasing.

The opposite is not allowed: the same IP-address on different MAC-addresses. That is considered an IP-conflict.

We have one EMAC on STM32. So we will have one MAC address

Not necessarily. Every EMAC has a MAC-address filter. You can configure up to 4 MAC-addresses. Also it has an algorithmic approach which filters on the hash value of a MAC-address (often used for multicast addresses).

But yeah support two IP addresses on same MAC address or
different MAC address if supported in EMAC of STM32.

Both will be possible

Normally, a unique MAC address is obtained from a MAC-address chip. You can not just use a random number. So the more MAC-addresses you use, the higher the cost of the hardware.

Hello Hein,

I hope you are doing good. Thank you for your response.

I am new to FreeRTOS.

I have FreeRTOSv10.3.1. Does this one has multi interfaces and multi endpoints support?
I looked for FreeRTOSIPConfig.h file and it seems like now it has been changed
to FreeRTOSIPConfigDefaults.h and did not see “ipconfigMULTI_INTERFACE”. It looks
like this version of FreeRTOS does not have multi support.

I am trying to port FreeRTOS on STM32H743 series. I would like to know which tool
are recommended to use for ST. The example of FreeRTOS demo is not available for
STM32H743.

Currently Trying to design and develop software supporting three IPs (IPv4)
over 2 interfaces.

Hardware Design:
PC <----Interface_1----> (Target with IP_1) Telnet server Port 23 and
HTTP Port 80
PC <----Interface_1----> (Target with IP_2) Telnet Serevr Port 30

PC <----Interface_2----> (Target with IP_3) FTP Server Port 22

To test above behviour, Access one application from physical ethernet port 
at one time as I don not have two independent physical ports yet on the Target.

OR

PC <----- Port Interface_1---
                            |
                         (SWITCH)--------> [TARGET with IP_1, IP_2 and IP_3]
                            |
PC <----- Port Interface_2---


Endpoint Constants:

static const uint8_t IPAddress_1[4] = { 192, 168, 227, 125 };
static const uint8_t Netmask_1[4] = { 255, 255, 255, 0 };
static const uint8_t GatewayAddress_1[4] = { 0, 0, 0, 0};
static const uint8_t DNSServerAddress_1[4] = { 0, 0, 0, 0 };
static const uint8_t MACAddress_1[6] = { configMAC_ADDR0, configMAC_ADDR1, configMAC_ADDR2, configMAC_ADDR3, configMAC_ADDR4, configMAC_ADDR5 };

static const uint8_t IPAddress_2[4] = { 192, 168, 0, 125 };
static const uint8_t Netmask_2[4] = { 255, 255, 0, 0 };
static const uint8_t GatewayAddress_2[4] = { 0, 0, 0, 0};
static const uint8_t DNSServerAddress_@[4] = { 0, 0, 0, 0 };
static const uint8_t MACAddress_2[6] = { configMAC_ADDR0, configMAC_ADDR1, configMAC_ADDR2, configMAC_ADDR3, configMAC_ADDR4, configMAC_ADDR5 };


static const uint8_t IPAddress_3[4] = { 192, 168, 227, 100 };
static const uint8_t NetMask_3[4] = { 255, 255, 255, 0 };
static const uint8_t GatewayAddress_3[4] = { 0, 0, 0, 0};
static const uint8_t DNSServerAddress_3[4] = { 0, 0, 0, 0 };
static const uint8_t MACAddress_3[6] = { configMAC_ADDR0, configMAC_ADDR1, configMAC_ADDR2, configMAC_ADDR3, configMAC_ADDR4, configMAC_ADDR5 + 1 };


Init:
static NetworkInterface_t xInterfaces[2];
static NetworkEndPoint_t xEndPoints[3];

Create the network interfaces and fill the endpoints

stm32h7xx_FillInterfaceDescriptor(0, &(xInterfaces[0]));
FreeRTOS_FillEndPoint(&(xEndPoints[0]), IPAddress1, Netmask1, GatewayAddress1, DNSServerAddress1, MACAddress1);
xEndPoints[0].bits.bWantDHCP = pdTRUE_UNSIGNED;

FreeRTOS_FillEndPoint(&(xEndPoints[1]), IPAddress2, Netmask2, GatewayAddress2, DNSServerAddress2, MACAddress2);
xEndPoints[1].bits.bWantDHCP = pdTRUE_UNSIGNED;

stm32h7xx_FillInterfaceDescriptor(1, &(xInterfaces[1]));
FreeRTOS_FillEndPoint(&(xEndPoints[2]), IPAddress3, Netmask3, GatewayAddress3, DNSServerAddress3, MACAddress3);
xEndPoints[2].bits.bWantDHCP = pdTRUE_UNSIGNED;


FreeRTOS_IPStart();

Once above steps are done, I believe I can start using socket programming
concept by following below steps:

1. Create a socket set ( FreeRTOS_CreateSocketSet ).
2. Create 4 sockets (for telnet1 and telnet2, HTTP, FTP) and 
            initialize them (bind(), setsockopt(), xlisten())
        0.0.0.0 Port 23
        0.0.0.0 Port 30
        0.0.0.0 Port 80
        0.0.0.0 Port 22
3. FreeRTOS_FD_SET( xSocket, xFD_Set );
4. Create a loop for socket acceptation for each of the sockets 
   (FreeRTOS_accept())

I have FreeRTOSv10.3.1. Does this one has multi interfaces and multi endpoints support?

When you say “FreeRTOSv10.3.1.”, you are referring to the kernel.

FreeRTOS+TCP is a different FreeRTOS project, and it is at version V2.2.1.

The kernel can be downloaded here. the TCP/IP libraries is here.

FreeRTOSIPConfig.h is a file that you maintain and it belongs to a FreeRTOS project.

FreeRTOSIPConfigDefaults.h is distributed and maintained by FreeRTOS. It defines the default value of all macro’s, after the compiler has seen FreeRTOSIPConfig.h.

Another important configuration file is called FreeRTOSConfig.h. It also belongs to the project, and not to the kernel.

FreeRTOS+TCP /multi is a new version of the existing FreeRTOS+TCP. It is not officially out yet, although you can have a peek at it here. The mentioned URL is not an official release, it just shows the current status.
The software is still being tested before it will be released.

Your setup with IP-addresses looks OK to me.

Hello Hein,

Thank you for your help. I could able to successfully port the FreeRTOS+TCP to STM32H7 Series using Keil IDE. Currently, I’m using this SimpleTCPServerDemo example to verify the FreeRTOS+TCP if it’s working or not.

The problem here is I’m getting this DMA error every time only once.

  /* if fatal bus error occured */
  if (__HAL_ETH_DMA_GET_IT(heth, ETH_DMACSR_FBE))
  {
    /* Get DMA error code  */
    heth->DMAErrorCode = READ_BIT(heth->Instance->DMACSR, (ETH_DMACSR_FBE | ETH_DMACSR_TPS | ETH_DMACSR_RPS));

    /* Disable all interrupts */
    __HAL_ETH_DMA_DISABLE_IT(heth, ETH_DMACIER_NIE | ETH_DMACIER_AIE);

    /* Set HAL state to ERROR */
    heth->gState = HAL_ETH_STATE_ERROR;

================================================================

Above code snippet is part of Ethernet ISR Handler of STM32H7 Hal. It calls once and gets into the above block and ISR never getting called again.

I feel like some kind of memory settings but now sure what’s wrong in the project. Probably something to do with Network Interface? I’ve ported the Networkinterface.c file from your github branch. Please find the attachment of the file.

Any advice will be appreciated.

Thanks

Attached: NetworkInterface.c here.NetworkInterface.c (20.5 KB)

I was able to port FreeRTOS-TCP Multi using STM32IDE for STM32F746ZG and build successfully with many warnings. When I went through the warnings I found all of them related to NetworkInterface.c and FreeRTOS-Plus multi source files.

I do see warnings mainly in files NetworkInterface.c and FreeRTOS_IP.c and FreeRTOS_UDP.c file. I’m trying to see if I can make multi interfaces work using FreeRTOS+TCP Multi.

Could you please confirm the NetworkInterface.c file, FreeRTOS_IP.c and FreeRTOS_UDP.c files are upto date? I picked from the link as shared above.

What about the HEAP Size expected when we work with FreeRTOS+TCP Multi. Currently, it’s 15X1024. Do I need to increase to 20X1024 for the case as mentioned in above thread?

This is what my main function looks like:
int main( void )
{
/* Configure the MPU attributes as Device memory for ETH DMA descriptors */
MPU_Config();

/* Enable the CPU Cache */
CPU_CACHE_Enable();

/* STM32F7xx HAL library initialization:
- Configure the Flash ART accelerator on ITCM interface
- Configure the Systick to generate an interrupt each 1 msec
- Set NVIC Group Priority to 4
- Global MSP (MCU Support Package) initialization
*/
HAL_Init();

/* Configure the system clock to 216 MHz */
SystemClock_Config();

/*configure LED1 and LED3 */
BSP_LED_Init(LED1);
BSP_LED_Init(LED3);

/* Initialise the network interface.

***NOTE*** Tasks that use the network are created in the network event hook
when the network is connected and ready for use (see the definition of
vApplicationIPNetworkEventHook() below).  The address values passed in here
are used if ipconfigUSE_DHCP is set to 0, or if ipconfigUSE_DHCP is set to 1
but a DHCP server cannot be	contacted. */

static NetworkInterface_t xInterfaces[2];
static NetworkEndPoint_t xEndPoints[3];

pxSTM32Fxx_FillInterfaceDescriptor(0, &(xInterfaces[0]));
FreeRTOS_FillEndPoint(&(xInterfaces[0]), &(xEndPoints[0]), IPAddress_1, Netmask_1, GatewayAddress_1, DNSServerAddress_1, MACAddress_1);
xEndPoints[0].bits.bWantDHCP = pdTRUE_UNSIGNED;

FreeRTOS_FillEndPoint(&(xInterfaces[0]), &(xEndPoints[1]), IPAddress_2, Netmask_2, GatewayAddress_2, DNSServerAddress_2, MACAddress_2);
xEndPoints[1].bits.bWantDHCP = pdTRUE_UNSIGNED;

pxSTM32Fxx_FillInterfaceDescriptor(1, &(xInterfaces[1]));
FreeRTOS_FillEndPoint(&(xInterfaces[1]), &(xEndPoints[2]), IPAddress_3, Netmask_3, GatewayAddress_3, DNSServerAddress_3, MACAddress_3);
xEndPoints[2].bits.bWantDHCP = pdTRUE_UNSIGNED;

FreeRTOS_printf( ( "FreeRTOS_IPInit\n" ) );
FreeRTOS_IPStart();
//FreeRTOS_IPInit( ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress );

/* Start the RTOS scheduler. */
FreeRTOS_debug_printf( ("vTaskStartScheduler\n") );
vTaskStartScheduler();
for( ;; )
{
}

}

Any inputs will be appreciated!

Thanks