FreeRTOS + TCP, tutorial, STM32F7 questions.

abeowitz wrote on Sunday, October 14, 2018:

OK, I will, thanks.

philipp007 wrote on Tuesday, January 29, 2019:

Hello stm32f7 friends,
i think i’m having the same problems. After getting everything up (as i thought). I got many multiple definition errors when compiling:
these are for:
HAL_ETH_DMATxDescListInit, HAL_ETH_DMARxDescListInit and others in
Middlewares\Third_Party\FreeRTOS-Plus\FreeRTOS-Plus-TCP\portable\NetworkInterface\STM32F7xx/stm32f7xx_hal_eth.c
and
\Drivers\STM32F7xx_HAL_Driver\Src/stm32f7xx_hal_eth.c
How can I get rid of this?
Philipp

PS: also in atollic true studio of course. Setting up with cubeMX as described on the freeRTOS website

heinbali01 wrote on Wednesday, January 30, 2019:

Hi Philipp, in this same post you will see references to the latest STM32Fxx driver.
That was an informal (personal) release.

As you see, it includes a source file called “stm32fxx_hal_eth.c”. That version was adapted to enable zero-copy transmission and reception of packets.

It look like your Atollic True Studio has included 2 times “stm32fxx_hal_eth.c”.

Please go to the properties of \Drivers\STM32F7xx_HAL_Driver\Src/stm32f7xx_hal_eth.c and indicate that it should be excluded from building cq. compilation.

That should solve your problem.

Also please make sure that your project has defined:

#define STM32F7xx		1

Hein

philipp007 wrote on Wednesday, January 30, 2019:

Hello Hein,
thank you for the fast response :slight_smile:
i took the files from your link and deleted the ethernet HAL files generated by cubeMX and got the redefinitions error away. But now i got:
phyHandling.c:193: undefined reference to ‘vLoggingPrintf’
But it could also that i missed configuring something. Perhaps, but i dont thinks so, that my FreeRTOSIPconfig.h is not correct. Do you have a sample IPconfig for the f7? I would adapt it for my use…
I would also try to uncomment these loggings…

But i’m a little bit confused now. Which files should one use when bgeinning with the FreeRTOS + TCP with a stm32F7xx. The files from the amazon FreeRTOS github page, the ones from the svn linked on the FreeRTOS website or this one you linked?
And should i enable the ETH connection in cubeMX in RMII model (which seems to generate the duplicated ethernet HAL files but perhaps its important for other things)?

Philipp

philipp007 wrote on Wednesday, January 30, 2019:

Hello again,
so with commenting the vLoggingPrintf’s in the pyHandling i got everything compiled :slight_smile: I will try pinging the board tomorow :slight_smile:
Philipp

heinbali01 wrote on Wednesday, January 30, 2019:

If you’re interesting in the logging, you can replace vLoggingPrintf() with FreeRTOS_printf(()). Please note the double parentheses around the parameter list.

FreeRTOS_printf(()) should be defined in your FreeRTOSIPConfig.h.

philipp007 wrote on Monday, February 04, 2019:

Hello Hein,

thanks for you time again. I have 2 other questions / problems:

I. (not so bad) When I set ipconfigHAS_PRINTF in FreeRTOSIPconfig.h to 1 my application hangs. It stucks inside HardFault_Handler in stm32f7xx_it.c while loop and blocks other tasks. ipconfigHAS_DEBUG_PRINTF with 1 works just fine. I use for both prints (debug and non debuging messages) an SWV the function:

void FreeRTOS_TCP_SWO_debug(const char *s)
{
while (*s!=’\0’) {
ITM_SendChar(*s++);
}
}

II. (worse porblem) After calling FreeRTOS_IPInit(…) with a static IP Adresse vApplicationIPNetworkEventHook is called every ~2 seconds. If I connect the stm32 with the router the eNetworkEvent is recognized as eNetworkUp. But the vApplicationIPNetworkEventHook is not called again after x secs or also (as described in the API) when the cable disconnects. Also no call when reconnecting the cable. The Router also dont recognize the device and I cant ping it. If I use the ipconfigUSE_DHCP 1 the debugger says vDHCPprocess: discover. But the stm doesnt connect.
The only thing i can see is an ARP with wireshark:
44952 3664.979352 Cimsys_33:44:55 Broadcast ARP 60 Gratuitous ARP for 192.168.55.149 (Request) . (static stm ip is 192.168.55.149).
Do you have any Idea what could causes this problem?

regards philipp

philipp007 wrote on Monday, February 04, 2019:

Hello again,
i m sorry to bother you again Hein.
The problem that the application hangs is definitley a problem with the debugging funktion. I fighted the whole day with the problem but without any luck. I also tried UART but same Problem there (HardFault).
I read in the FreeRTOSIPConfigDefaults.h: / * The FreeRTOS_printf() must be thread-safe but does not have to be interrupt-safe */
Could writing a seperate task, and pass the logging-stuff with a queue solve the problem ?
I think it would be important to get the logging/printing work for debugging? In the Demo Application “demo_logging.c” there were many Windows specific types used so i could not implement that.
Or do you know any other sources / threads were i can find information about these problems?

Philipp

heinbali01 wrote on Tuesday, February 05, 2019:

The IP-task doesn’t run ISR code. Most Network Interface’s are defining an EMAC interrupt. That ISR should not produce any logging. It is called when a packet has been received or when it has been sent.

The Windows project indeed has a separate (Windows) thread that prints a queue of logging lines. That has to do with the fact that a FreeRTOS task may not call any Windows System API’s like printf() and fflush().

Here below a simple version of vLoggingPrintf() that is task-safe. I haven’t tested this code yet:

static SemaphoreHandle_t xLoggingSemaphore = NULL;

static BaseType_t xLoggingEnter( void )
{
BaseType_t xResult;

    if( xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED )
    {
        xResult = pdTRUE;
    }
    else
    {
        if( xLoggingSemaphore == NULL )
        {
            /* Create a mutex. */
            xLoggingSemaphore = xSemaphoreCreateMutex();
        }

        if( xLoggingSemaphore != NULL )
        {
        /* Never wait longer than e.g. 100 ms. */
        TickType_t xTicksToWait = pdMS_TO_TICKS( 100 );

            xResult = xSemaphoreTake( xLoggingSemaphore, xTicksToWait );
        }
        else
        {
            xResult = pdFALSE;
        }
    }
    return xResult;
}

static void vLoggingExit( void )
{
    /* Code below has confirmed that the semaphore has been
    created and that it has been taken by vLoggingPrintf().
    Now release it. */
    xSemaphoreGive( xLoggingSemaphore );
}

void vLoggingPrintf( const char *pcFormat, ... )
{
    if( xLoggingEnter() != pdFALSE )
    {
    va_list xArgs;
    /* Watch out with small stacks. */
    char pcBuffer[ 129 ];
    BaseType xLength;

        va_start( xArgs, pcFormat );
        xLength = vsnprintf( pcBuffer, sizeof pcBuffer, pcFormat, xArgs );
        uart_send( pcBuffer, xLength );
        va_end( xArgs );

        vLoggingExit();
    }
}

philipp007 wrote on Tuesday, February 05, 2019:

WOW! thanks Hein,
its working like charm. You are the best :-). Perfect. Logging is now also with SWV possible. There was a spelling mistake in xRestult instead of xResult but…
But the Board is not listed in the Routers list of ips…
If i do an “arp -a” I can see the ip + mac of the board.
Also a strange behaviout: the vApplicationIPNetworkEventHook is only called when I connect the board the first time, as i wrote before. Do you have any idea?
I put the log down here (i connected the ethernet cable after a few secs when the scheduler started…)

Will be launching FreeRTOS…
prvIPTask started
PHY ID 7C130
xPhyReset: phyBMCR_RESET 0 ready
+TCP: advertise: 01E1 config 3100
prvEthernetUpdateConfig: LS mask 00 Force 1
xPhyReset: phyBMCR_RESET timed out ( done 0x00 )
Network buffers: 56 lowest 56
Link Status still low
Link Status still low
Link Status still low
Link Status still low
xPhyCheckLinkStatus: PHY LS now 01
prvEthernetUpdateConfig: LS mask 01 Force 0

Autonego ready: 00000004: full duplex 100 mbit high status
Link Status is high
Network buffers: 55 lowest 55
Network buffers: 54 lowest 54
TX DMA buffers: lowest 2
Network buffers: 53 lowest 53
TX DMA buffers: lowest 1
Network buffers: 52 lowest 52
TX DMA buffers: lowest 0
Network buffers: 51 lowest 51

I will also try to continue with the tutorial creating a socket, but i thought that now the stm should be visible to the Router…

Thanks again!!! Hein the master :slight_smile:

Greetings Philipp

philipp007 wrote on Thursday, February 07, 2019:

Hello Hein,
Thank you again for the earlier replies. Unfortunately the driver is still not working :frowning:
I think there is something corrupt with the xARPCache. As I said before:
I connect the uC. These function are called:

prvHandleEternetPackage -> 
prvProcessEthernetPacket ->
eARPProcessPacket:
ulTargetProtocolAddress != *ipLOCAL_IP_ADDRESS_POINTER  ->break

wait a few secs

FreeRTOS_OutputARPRequest ->
vARPGenerateRequestPacket ->
xNetworkInterfaceOutput ->
iptraceNETWORK_INTERFACE_TRANSMIT()

wireshark: source:“STM_MAC”: “Gratuitous ARP for (Request)” broadcast
Seems ok, but nothing is in the xARPCache.
If i do a ping, the the Cache is filled with one entry, the Pings destinations IP, but no MAC.

I also tried:

  • arpGRATUITOUS_ARP_PERIOD ( pdMS_TO_TICKS( 20000 ) )
  • bigger buffer allocation
  • polling and interrupt receving
  • arptable size changed

So do you have any idea. Any help would be great. I just dont know what to do.

Kind regards
Philipp

heinbali01 wrote on Friday, February 08, 2019:

prvHandleEternetPackage →
prvProcessEthernetPacket →
eARPProcessPacket:
ulTargetProtocolAddress != *ipLOCAL_IP_ADDRESS_POINTER ->break

That’s good, it receives a packet.
Can you lookup or log both ulTargetProtocolAddress and *ipLOCAL_IP_ADDRESS_POINTER?

Do you use a fixed IP-address or use DHCP?

The fixed IP-address would be defined in FreeRTOSConfig.h, as configIP_ADDR[0..3]

FreeRTOS_OutputARPRequest →
vARPGenerateRequestPacket →
xNetworkInterfaceOutput →
iptraceNETWORK_INTERFACE_TRANSMIT()

wireshark: source:“STM_MAC”: “Gratuitous ARP for (Request)”
broadcast. Seems ok, but nothing is in the xARPCache.

No, the gratuitous ARP request ( see wiki ) is an outgoing broadcast packet and it won’t create an ARP entry.

ARP entries are created for incoming packets that have the device as a target.

If i do a ping, the the Cache is filled with one entry,
the Pings destinations IP, but no MAC.

Are you talking about a ping to or from the STM?

I also tried:

  • arpGRATUITOUS_ARP_PERIOD ( pdMS_TO_TICKS( 20000 ) )
  • bigger buffer allocation
  • polling and interrupt receving
  • arptable size changed

If you want, attach your latest FreeRTOSIPConfig.h to your post. Regards.

philipp007 wrote on Friday, February 08, 2019:

Hello Hain,
thanks for your reply. And sorry for the unprecise statment.
without a Router, direct to (192.168.100.2, PC) and static IP (192.168.100.66, stm32), the

  • ulTargetProtocolAddress:
    Adresse of my PC: 0x264a8c0 “192.168.100.2” (0x264a8c0)
  • ipLOCAL_IP_ADDRESS_POINTER:
    static IP of the STM32F7: “192.168.100.66” (0xC0A86442)
    And I meant a ping from the stm to the PC. When pinging the STM i got nothing back. even with:
    ipconfigREPLY_TO_INCOMING_PINGS 1 and ipconfigREPLY_TO_INCOMING_PINGS and a vApplicationPingReplyHook() I will atach the FreeRTOSIPConfig.h and the FreeRTOSConfig.h.

Strange thing is, I also tried to connect the stm (192.168.55.66) to the router (192.168.55.1), but then the ulTargetProtocolAddress stays “192.168.100.2” and the ipLOCAL_IP_ADDRESS_POINTER changes to the “192.168.55.66” of the stm. But i think that is another story.

So i will atach the FreeRTOSIPConfig.h and the FreeRTOSConfig.h.

Thanks for you time!!!
Regards Philipp

philipp007 wrote on Friday, February 08, 2019:

i also created a log. After the eNetworkUp event, I print out the arp table every 5 secs and ping every 20secs to my PC from the STM:

Will be launching FreeRTOS... 
prvIPTask started
PHY ID 7C130
xPhyReset: phyBMCR_RESET 0 ready
+TCP: advertise: 01E1 config 3100
prvEthernetUpdateConfig: LS mask 00 Force 1
>> Autonego ready: 00000004: full duplex 100 mbit high status
Network buffers: 56 lowest 56
Link Status is high
Network buffers: 55 lowest 55
Network buffers: 55 lowest 54
prvProcessEthernetPacket(): pxEthernetHeader->usFrameType:  0x 608 
eARPProcessPacket(): ulTargetProtocollAddress: 0x 264a8c0, ipLOCAL_IP_ADDRESS_POINTER:  0x4264a8c0 
prvProcessEthernetPacket(): pxEthernetHeader->usFrameType:  0x   8 
prvProcessEthernetPacket(): pxEthernetHeader->usFrameType:  0x   8 
prvProcessEthernetPacket(): pxEthernetHeader->usFrameType:  0x   8 
prvProcessEthernetPacket(): pxEthernetHeader->usFrameType:  0x   8 
prvProcessEthernetPacket(): pxEthernetHeader->usFrameType:  0x   8 
prvProcessEthernetPacket(): pxEthernetHeader->usFrameType:  0x   8 
prvProcessEthernetPacket(): pxEthernetHeader->usFrameType:  0x   8 
prvProcessEthernetPacket(): pxEthernetHeader->usFrameType:  0x   8 
prvProcessEthernetPacket(): pxEthernetHeader->usFrameType:  0x   8 
prvProcessEthernetPacket(): pxEthernetHeader->usFrameType:  0x   8 
Arp has 0 entries
prvProcessEthernetPacket(): pxEthernetHeader->usFrameType:  0x   8 
prvProcessEthernetPacket(): pxEthernetHeader->usFrameType:  0x   8 
prvProcessEthernetPacket(): pxEthernetHeader->usFrameType:  0x   8 
Arp has 0 entries
prvProcessEthernetPacket(): pxEthernetHeader->usFrameType:  0x   8 
prvProcessEthernetPacket(): pxEthernetHeader->usFrameType:  0x   8 
prvProcessEthernetPacket(): pxEthernetHeader->usFrameType:  0x   8 
prvProcessEthernetPacket(): pxEthernetHeader->usFrameType:  0x   8 
Arp has 0 entries
prvProcessEthernetPacket(): pxEthernetHeader->usFrameType:  0x   8 
Arp has 0 entries
i send ping to 192.168.100.2 (0x264a8c0) 
Arp  0:  10 -          264a8c0ip : 00:00:00 : 00:00:00
Arp has 1 entries
Arp  0:   9 -          264a8c0ip : 00:00:00 : 00:00:00
Arp has 1 entries
Arp  0:   9 -          264a8c0ip : 00:00:00 : 00:00:00
Arp has 1 entries
Arp  0:   8 -          264a8c0ip : 00:00:00 : 00:00:00
Arp has 1 entries
i send ping to 192.168.100.2 (0x264a8c0) 
Arp  0:   8 -          264a8c0ip : 00:00:00 : 00:00:00
Arp has 1 entries
Arp  0:   7 -          264a8c0ip : 00:00:00 : 00:00:00
Arp has 1 entries
Arp  0:   7 -          264a8c0ip : 00:00:00 : 00:00:00
Arp has 1 entries
Arp  0:   6 -          264a8c0ip : 00:00:00 : 00:00:00
Arp has 1 entries
i send ping to 192.168.100.2 (0x264a8c0) 
Arp  0:   6 -          264a8c0ip : 00:00:00 : 00:00:00
Arp has 1 entries
Arp  0:   5 -          264a8c0ip : 00:00:00 : 00:00:00
Arp has 1 entries

Seems like the stmf7 is receiving ARPFrames and IPFrames. But he doesnt know what to do with them… ?
Thanks again!!!
Philipp

heinbali01 wrote on Saturday, February 09, 2019:

A few remarks about your FreeRTOSIPConfig.h :

/* USE_WIN: Let TCP use windowing mechanism. */
#define ipconfigUSE_TCP_WIN ( 0 )

Not important yet, but I recommend using the sliding TCP windows

#define ipconfigTCP_WIN_SEG_COUNT 240

I recommend a lower number. This defines the maximum number of outstanding TCP segments at any time.

#define ipconfigTCP_RX_BUFFER_LENGTH ( 1000 )

/* Define the size of Tx buffer for TCP sockets. */
#define ipconfigTCP_TX_BUFFER_LENGTH ( 1000 )

1000 bytes is very little. Normally this would be defined as minimal:

#define ipconfigTCP_RX_BUFFER_LENGTH                   ( 4 * ipconfigTCP_MSS )
#define ipconfigTCP_TX_BUFFER_LENGTH                   ( 2 * ipconfigTCP_MSS )

In the above case, the buffers are defined as a multiple of ipconfigTCP_MSS, which depends on ipconfigNETWORK_MTU, or up to 1460 bytes.

#define ipconfigREPLY_TO_INCOMING_PINGS 1

That is OK, but it is defined 2 times.

static uint8_t ucMACAddress[ 6 ] = { configMAC_ADDR0, configMAC_ADDR1, configMAC_ADDR2,
configMAC_ADDR3, configMAC_ADDR4, configMAC_ADDR5 };

You are defining static variables/arrays in a header file. I think that all these declarations should be placed in your main.c.

Especially ucMACAddress : are you sure it must be accessible in all modules that include FreeRTOSIPConfig.h?
If you change ucMACAddress in e.g. main.c, it will not change in other modules.
Normally FreeRTOS_GetMACAddress() is used to read the 6-byte MAC-address.
Can you see where (in what modules) ucMACAddress[] is being used?

philipp007 wrote on Sunday, February 10, 2019:

hey hein,
i followed your instructions. With the following instruction in the FreeRTOSIPConfig.h

 #define ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM 1

i am now able to ping the board from my Windows PC sometimes. A zero in the ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM calculates a wrong checksum.
I moved the ucMACAddress[] and the other declarations to the main.c. The ucMACAddress[] was also used in the NetworkInterace.c line 251. I used the files you linked in an earlier post. I solved this like you described earlier.
I also changed the linker you described in another post for the stm32f7 with the .first_data section (https://www.freertos.org/FreeRTOS_Support_Forum_Archive/June_2017/freertos_FreeRTOS_TCP_and_FAT_drivers_STM32F4_and_STM32F7_8ddf9629j.html) from the 26 Juni.
I dont know it seems to depend everything on the arptable. When this is filled correctly everything works find, but that happens not very often… :frowning:
Perhaps you have another idea?
I will try more things out…
Philipp

philipp007 wrote on Sunday, February 10, 2019:

hey hein,
are there any other settings you changed on he freeRTOS? Or do you have a working example for the stm32f7 in atollic?
Its an university project (diploma thesis) and it would be so great to use the +TCP package…
Philipp

heinbali01 wrote on Sunday, February 10, 2019:

Hi Philipp, if you drop an email to me on hein[at]htibosch[dot]net, I will send you a working example for stm32f7. It won’t be specifally for Atollic but a generic Makefile project.
Cheers

heinbali01 wrote on Monday, February 11, 2019:

Solved.

I wrote Philipp a detailed email about his Atollic project. Here below a summary:

The biggest problem that I found was the small heap, only 15 KB. That is possible, but then you’d have to reconfigure the whole project to get a smaller usage of RAM.

The STM32F767 has a lot of RAM, so why not make use of it. I attach an example of vInitHeap() that uses heap_5.c.

The STM32F7 has checsum offloading, meaning the the IP-task doesn’t have to waste time on calculating checksums of incoming and outgoing packets. Therefore FreeRTOSIPConfig.h should define:

    #define ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM     1
    #define ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM     1

After making these changes, the +TCP project worked well.

pavanshah2001 wrote on Monday, August 19, 2019:

Hi Hein,

I followed all of the above steps to solve most of the common problems mentioned above. ANd im able to compile project. Although my device doesnt get connected.

While debugging, I found out that i’m not receiving “MACMIIAR” value in “HAL_ETH_ReadPHYRegister” function of stm32fxx_hal_eth.c

I’m using IAR IDE and initial code for freertos and ethernet was generated using STM32CubeMX.

Can you please help me?