Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ethernet support for STM32H747 #24767

Closed
i-and opened this issue Apr 28, 2020 · 22 comments
Closed

Ethernet support for STM32H747 #24767

i-and opened this issue Apr 28, 2020 · 22 comments
Assignees
Labels
platform: STM32 ST Micro STM32

Comments

@i-and
Copy link

i-and commented Apr 28, 2020

Did I understand correctly from the description STM32H747 that the built-in Ethernet controller is not supported for STM32H747 in Zephyr?

If this is the case, then:

  1. how difficult is it to support Ethernet on my own?
  2. are you planning to support Ethernet in the near future?
  3. if Ethernet is supported, will the IEEE1588/802.1 AS time synchronization subsystem with hardware timestamping be available?
@carlescufi
Copy link
Member

@gmarull any advice for @i-and?

@gmarull
Copy link
Member

gmarull commented Apr 28, 2020

I haven't used Ethernet on H7 series, but it looks like F7 has support for it (see for example nucleo_f746zg board). In general existing drivers require little adjustments to function with other STM32 series, so unless H7 silicon has changed a lot, adding support for it may only consist on defining the peripheral in DT files and a few other small adjustments.

@erwango
Copy link
Member

erwango commented Apr 29, 2020

I haven't used Ethernet on H7 series, but it looks like F7 has support for it (see for example nucleo_f746zg board). In general existing drivers require little adjustments to function with other STM32 series, so unless H7 silicon has changed a lot, adding support for it may only consist on defining the peripheral in DT files and a few other small adjustments.

Additionally, I should mention that on this board, ethernet controller is not connected to MCU by default and you have to do some hw modifications to get it working. You'll get more information in the following post:
ARMmbed/mbed-os#11827
By advance, sorry for the inconvenience.

@i-and
Copy link
Author

i-and commented Apr 29, 2020

To continue the conversation, please clarify: is Zephyr supported on two Cortex-M7 and Cortex-M4 cores of STM32H747, or on one of them? If both cores are supported, in which mode (AMP, SMP, ,...)?

@erwango
Copy link
Member

erwango commented Apr 29, 2020

@i-and Zephyr is supported on both cores in AMP. Though for now only a limited range of peripherals are supported. Also we still miss inter-core communication

@KozhinovAlexander
Copy link
Collaborator

KozhinovAlexander commented May 4, 2020

@erwango Is it possible to use Hardware semaphore (HSEM) for peripheral ( ETH module etc. ) synching between the cores?

@erwango
Copy link
Member

erwango commented May 4, 2020

@erwango Is it possible to use Hardware semaphore (HSEM) for peripheral ( ETH module etc. ) synching between the cores?

@Nukersson Depends on your need. If this is to protect usage between cores, we're currently trying to improve to existing code with #24862.
Does it answer your question ?

@KozhinovAlexander
Copy link
Collaborator

@erwango It completely does answering my question. Hopefully I can join to #24862 later, as I get more experience with Zephyr.

@KwonTae-young
Copy link
Collaborator

@erwango I am trying to use Ethernet on STM32H742VG.
I want to use Ethernet on H7 by referring to the source of F7 series. What sources of F7 should I reference?(dts, samples, ..)
I currently only know pinmux.c.
https://github.com/zephyrproject-rtos/zephyr/blob/master/boards/arm/nucleo_f756zg/pinmux.c#L37-L47

#ifdef CONFIG_ETH_STM32_HAL
	{ STM32_PIN_PC1, STM32F7_PINMUX_FUNC_PC1_ETH },
	{ STM32_PIN_PC4, STM32F7_PINMUX_FUNC_PC4_ETH },
	{ STM32_PIN_PC5, STM32F7_PINMUX_FUNC_PC5_ETH },
	{ STM32_PIN_PA1, STM32F7_PINMUX_FUNC_PA1_ETH },
	{ STM32_PIN_PA2, STM32F7_PINMUX_FUNC_PA2_ETH },
	{ STM32_PIN_PA7, STM32F7_PINMUX_FUNC_PA7_ETH },
	{ STM32_PIN_PG11, STM32F7_PINMUX_FUNC_PG11_ETH },
	{ STM32_PIN_PG13, STM32F7_PINMUX_FUNC_PG13_ETH },
	{ STM32_PIN_PB13, STM32F7_PINMUX_FUNC_PB13_ETH },
#endif  /* CONFIG_ETH_STM32_HAL */

I have a nucleo_h743zi board that I can test.
I am new to Ethernet on Zephyr. 😅

@KwonTae-young
Copy link
Collaborator

I am trying to use Ethernet on the nucleo_h743zi board.
zephyr: https://github.com/KwonTae-young/zephyr/tree/stm32h743_ethernet
hal_stm32: https://github.com/KwonTae-young/hal_stm32

First of all, I have no experience using Ethernet in STM32. So I am very immature. 😅
My first goal was the occurrence of a receive interrupt(HAL_ETH_RxCpltCallback()).
However, the current Ethernet function does not operate normally.

west init zephyrproject_stm32h743_ethernet -m https://github.com/KwonTae-young/zephyr --mr stm32h743_ethernet
cd zephyrproject_stm32h743_ethernet
west update
cd zephyr
source zephyr.sh
west build -b nucleo_h743zi samples/net/sockets/echo
west flash

1. Receive Buffer Unavailable(ETH_DMACSR)

Receive Buffer Unavailable occurs in ETH_DMACSR register when the driver under test is operating.
image

I don't know the exact reason, but changing the STM32 HAL Ethernet driver eliminated this symptom.

Bug in ETH_DMARxDescListInit - reported in the forum

diff --git a/stm32cube/stm32h7xx/drivers/src/stm32h7xx_hal_eth.c b/stm32cube/stm32h7xx/drivers/src/stm32h7xx_hal_eth.c
index a34d44e1cc9520032d42f46967b1a45157e768e1..29631ff647fc1be49cca4da1b01d2295c355c90e 100644
--- a/stm32cube/stm32h7xx/drivers/src/stm32h7xx_hal_eth.c
+++ b/stm32cube/stm32h7xx/drivers/src/stm32h7xx_hal_eth.c
@@ -2703,7 +2703,7 @@ static void ETH_DMARxDescListInit(ETH_HandleTypeDef *heth)
   WRITE_REG(heth->Instance->DMACRDLAR, (uint32_t) heth->Init.RxDesc);

   /* Set Receive Descriptor Tail pointer Address */
-  WRITE_REG(heth->Instance->DMACRDTPR, ((uint32_t)(heth->Init.RxDesc + (((uint32_t)(ETH_RX_DESC_CNT - 1))*sizeof(ETH_DMADescTypeDef)))));
+  WRITE_REG(heth->Instance->DMACRDTPR, ((uint32_t)(heth->Init.RxDesc) + ((uint32_t)(ETH_RX_DESC_CNT - 1))));
 }

 /**

before

[00:00:00.000,000] <dbg> eth_stm32_hal.eth_iface_init: eth_iface_init() 625Line
[00:00:00.000,000] <dbg> eth_stm32_hal.eth_stm32_hal_get_capabilities: eth_stm32_hal_get_capabilite
[00:00:00.500,000] <dbg> eth_stm32_hal.rx_thread: ETH_DMACSR: 0x80
[00:00:00.500,000] <dbg> eth_stm32_hal.rx_thread: ETH_MTLQICSR: 0x0
[00:00:00.500,000] <dbg> eth_stm32_hal.rx_thread: ETH_MACPCSR: 0x0
[00:00:00.500,000] <dbg> eth_stm32_hal.rx_thread: ETH_MACLCSR: 0x0
[00:00:00.500,000] <dbg> eth_stm32_hal.rx_thread:
[00:00:01.000,000] <dbg> eth_stm32_hal.rx_thread: ETH_DMACSR: 0x80
[00:00:01.000,000] <dbg> eth_stm32_hal.rx_thread: ETH_MTLQICSR: 0x0
[00:00:01.000,000] <dbg> eth_stm32_hal.rx_thread: ETH_MACPCSR: 0x0
[00:00:01.000,000] <dbg> eth_stm32_hal.rx_thread: ETH_MACLCSR: 0x0

after

[00:00:00.000,000] <dbg> eth_stm32_hal.eth_iface_init: eth_iface_init() 625Line
[00:00:00.000,000] <dbg> eth_stm32_hal.eth_stm32_hal_get_capabilities: eth_stm32_hal_get_capabilite
[00:00:00.500,000] <dbg> eth_stm32_hal.rx_thread: ETH_DMACSR: 0x0
[00:00:00.500,000] <dbg> eth_stm32_hal.rx_thread: ETH_MTLQICSR: 0x0
[00:00:00.500,000] <dbg> eth_stm32_hal.rx_thread: ETH_MACPCSR: 0x0
[00:00:00.500,000] <dbg> eth_stm32_hal.rx_thread: ETH_MACLCSR: 0x0
[00:00:00.500,000] <dbg> eth_stm32_hal.rx_thread:
[00:00:01.000,000] <dbg> eth_stm32_hal.rx_thread: ETH_DMACSR: 0x0
[00:00:01.000,000] <dbg> eth_stm32_hal.rx_thread: ETH_MTLQICSR: 0x0
[00:00:01.000,000] <dbg> eth_stm32_hal.rx_thread: ETH_MACPCSR: 0x0
[00:00:01.000,000] <dbg> eth_stm32_hal.rx_thread: ETH_MACLCSR: 0x0

2. Receive Queue Overflow Interrupt Status(ETH_MTLQICSR)

After resolving 1. Receive Buffer Unavailable(ETH_DMACSR), it becomes LINKUP and Receive Queue Overflow Interrupt Status((ETH_MTLQICSR)) occurs.
image
I am not sure how to solve this.

[00:00:02.000,000] <dbg> eth_stm32_hal.rx_thread: Link UP!
[00:00:02.000,000] <dbg> eth_stm32_hal.rx_thread: ETH_DMACSR: 0x0
[00:00:02.000,000] <dbg> eth_stm32_hal.rx_thread: ETH_MTLQICSR: 0x0
[00:00:02.000,000] <dbg> eth_stm32_hal.rx_thread: ETH_MACPCSR: 0x0
[00:00:02.000,000] <dbg> eth_stm32_hal.rx_thread: ETH_MACLCSR: 0x0
[00:00:02.000,000] <dbg> eth_stm32_hal.rx_thread:
[00:00:02.500,000] <dbg> eth_stm32_hal.rx_thread: ETH_DMACSR: 0x0
[00:00:02.500,000] <dbg> eth_stm32_hal.rx_thread: ETH_MTLQICSR: 0x0
[00:00:02.500,000] <dbg> eth_stm32_hal.rx_thread: ETH_MACPCSR: 0x0
[00:00:02.500,000] <dbg> eth_stm32_hal.rx_thread: ETH_MACLCSR: 0x0
[00:00:02.500,000] <dbg> eth_stm32_hal.rx_thread:
[00:00:03.000,000] <dbg> eth_stm32_hal.rx_thread: ETH_DMACSR: 0x0
[00:00:03.000,000] <dbg> eth_stm32_hal.rx_thread: ETH_MTLQICSR: 0x10000
[00:00:03.000,000] <dbg> eth_stm32_hal.rx_thread: ETH_MACPCSR: 0x0
[00:00:03.000,000] <dbg> eth_stm32_hal.rx_thread: ETH_MACLCSR: 0x0
[00:00:03.000,000] <dbg> eth_stm32_hal.rx_thread:
[00:00:03.500,000] <dbg> eth_stm32_hal.rx_thread: ETH_DMACSR: 0x0
[00:00:03.500,000] <dbg> eth_stm32_hal.rx_thread: ETH_MTLQICSR: 0x10000
[00:00:03.500,000] <dbg> eth_stm32_hal.rx_thread: ETH_MACPCSR: 0x0
[00:00:03.500,000] <dbg> eth_stm32_hal.rx_thread: ETH_MACLCSR: 0x0

The register of PHY chip is read well.

[00:00:00.000,000] <dbg> eth_stm32_hal.eth_initialize: Basic Control Register: 0x3000
[00:00:00.000,000] <dbg> eth_stm32_hal.eth_initialize: Basic Status Register: 0x7809
[00:00:00.000,000] <dbg> eth_stm32_hal.eth_initialize: PHY Identifier 1 Register: 0x7
[00:00:00.000,000] <dbg> eth_stm32_hal.eth_initialize: PHY Identifier 2 Register: 0xc131

Can someone please advise on this phenomenon? 😖

@alister-f
Copy link

The RBU and other problems with ST's STM32H7 HAL ethernet driver are discussed and fixed at https://community.st.com/s/question/0D50X0000C6eNNSSQ2/bug-fixes-stm32h7-ethernet.

@KozhinovAlexander
Copy link
Collaborator

The RBU and other problems with ST's STM32H7 HAL ethernet driver are discussed and fixed at https://community.st.com/s/question/0D50X0000C6eNNSSQ2/bug-fixes-stm32h7-ethernet.

Would you like to implement the STM32H7's ETH driver for Zephyr?

@alister-f
Copy link

alister-f commented May 31, 2020 via email

@KozhinovAlexander
Copy link
Collaborator

KozhinovAlexander commented Jun 16, 2020

With some help of STM32H745_Ethernet repository I was able to provide first working version of #26226 of stm32h7 ethernet driver tested on nucleo-h745zi-q dev board and with existing socket based zephyr samples. Corresponding issue #26174 were also opened.
Please feel free to provide your proposals to this PR. Also testers are greatly welcome!

@KozhinovAlexander
Copy link
Collaborator

I am trying to use Ethernet on the nucleo_h743zi board.
zephyr: https://github.com/KwonTae-young/zephyr/tree/stm32h743_ethernet
hal_stm32: https://github.com/KwonTae-young/hal_stm32

First of all, I have no experience using Ethernet in STM32. So I am very immature. 😅
My first goal was the occurrence of a receive interrupt(HAL_ETH_RxCpltCallback()).
However, the current Ethernet function does not operate normally.

west init zephyrproject_stm32h743_ethernet -m https://github.com/KwonTae-young/zephyr --mr stm32h743_ethernet
cd zephyrproject_stm32h743_ethernet
west update
cd zephyr
source zephyr.sh
west build -b nucleo_h743zi samples/net/sockets/echo
west flash

1. Receive Buffer Unavailable(ETH_DMACSR)

Receive Buffer Unavailable occurs in ETH_DMACSR register when the driver under test is operating.
image

I don't know the exact reason, but changing the STM32 HAL Ethernet driver eliminated this symptom.

Bug in ETH_DMARxDescListInit - reported in the forum

diff --git a/stm32cube/stm32h7xx/drivers/src/stm32h7xx_hal_eth.c b/stm32cube/stm32h7xx/drivers/src/stm32h7xx_hal_eth.c
index a34d44e1cc9520032d42f46967b1a45157e768e1..29631ff647fc1be49cca4da1b01d2295c355c90e 100644
--- a/stm32cube/stm32h7xx/drivers/src/stm32h7xx_hal_eth.c
+++ b/stm32cube/stm32h7xx/drivers/src/stm32h7xx_hal_eth.c
@@ -2703,7 +2703,7 @@ static void ETH_DMARxDescListInit(ETH_HandleTypeDef *heth)
   WRITE_REG(heth->Instance->DMACRDLAR, (uint32_t) heth->Init.RxDesc);

   /* Set Receive Descriptor Tail pointer Address */
-  WRITE_REG(heth->Instance->DMACRDTPR, ((uint32_t)(heth->Init.RxDesc + (((uint32_t)(ETH_RX_DESC_CNT - 1))*sizeof(ETH_DMADescTypeDef)))));
+  WRITE_REG(heth->Instance->DMACRDTPR, ((uint32_t)(heth->Init.RxDesc) + ((uint32_t)(ETH_RX_DESC_CNT - 1))));
 }

 /**

before

[00:00:00.000,000] <dbg> eth_stm32_hal.eth_iface_init: eth_iface_init() 625Line
[00:00:00.000,000] <dbg> eth_stm32_hal.eth_stm32_hal_get_capabilities: eth_stm32_hal_get_capabilite
[00:00:00.500,000] <dbg> eth_stm32_hal.rx_thread: ETH_DMACSR: 0x80
[00:00:00.500,000] <dbg> eth_stm32_hal.rx_thread: ETH_MTLQICSR: 0x0
[00:00:00.500,000] <dbg> eth_stm32_hal.rx_thread: ETH_MACPCSR: 0x0
[00:00:00.500,000] <dbg> eth_stm32_hal.rx_thread: ETH_MACLCSR: 0x0
[00:00:00.500,000] <dbg> eth_stm32_hal.rx_thread:
[00:00:01.000,000] <dbg> eth_stm32_hal.rx_thread: ETH_DMACSR: 0x80
[00:00:01.000,000] <dbg> eth_stm32_hal.rx_thread: ETH_MTLQICSR: 0x0
[00:00:01.000,000] <dbg> eth_stm32_hal.rx_thread: ETH_MACPCSR: 0x0
[00:00:01.000,000] <dbg> eth_stm32_hal.rx_thread: ETH_MACLCSR: 0x0

after

[00:00:00.000,000] <dbg> eth_stm32_hal.eth_iface_init: eth_iface_init() 625Line
[00:00:00.000,000] <dbg> eth_stm32_hal.eth_stm32_hal_get_capabilities: eth_stm32_hal_get_capabilite
[00:00:00.500,000] <dbg> eth_stm32_hal.rx_thread: ETH_DMACSR: 0x0
[00:00:00.500,000] <dbg> eth_stm32_hal.rx_thread: ETH_MTLQICSR: 0x0
[00:00:00.500,000] <dbg> eth_stm32_hal.rx_thread: ETH_MACPCSR: 0x0
[00:00:00.500,000] <dbg> eth_stm32_hal.rx_thread: ETH_MACLCSR: 0x0
[00:00:00.500,000] <dbg> eth_stm32_hal.rx_thread:
[00:00:01.000,000] <dbg> eth_stm32_hal.rx_thread: ETH_DMACSR: 0x0
[00:00:01.000,000] <dbg> eth_stm32_hal.rx_thread: ETH_MTLQICSR: 0x0
[00:00:01.000,000] <dbg> eth_stm32_hal.rx_thread: ETH_MACPCSR: 0x0
[00:00:01.000,000] <dbg> eth_stm32_hal.rx_thread: ETH_MACLCSR: 0x0

2. Receive Queue Overflow Interrupt Status(ETH_MTLQICSR)

After resolving 1. Receive Buffer Unavailable(ETH_DMACSR), it becomes LINKUP and Receive Queue Overflow Interrupt Status((ETH_MTLQICSR)) occurs.
image
I am not sure how to solve this.

[00:00:02.000,000] <dbg> eth_stm32_hal.rx_thread: Link UP!
[00:00:02.000,000] <dbg> eth_stm32_hal.rx_thread: ETH_DMACSR: 0x0
[00:00:02.000,000] <dbg> eth_stm32_hal.rx_thread: ETH_MTLQICSR: 0x0
[00:00:02.000,000] <dbg> eth_stm32_hal.rx_thread: ETH_MACPCSR: 0x0
[00:00:02.000,000] <dbg> eth_stm32_hal.rx_thread: ETH_MACLCSR: 0x0
[00:00:02.000,000] <dbg> eth_stm32_hal.rx_thread:
[00:00:02.500,000] <dbg> eth_stm32_hal.rx_thread: ETH_DMACSR: 0x0
[00:00:02.500,000] <dbg> eth_stm32_hal.rx_thread: ETH_MTLQICSR: 0x0
[00:00:02.500,000] <dbg> eth_stm32_hal.rx_thread: ETH_MACPCSR: 0x0
[00:00:02.500,000] <dbg> eth_stm32_hal.rx_thread: ETH_MACLCSR: 0x0
[00:00:02.500,000] <dbg> eth_stm32_hal.rx_thread:
[00:00:03.000,000] <dbg> eth_stm32_hal.rx_thread: ETH_DMACSR: 0x0
[00:00:03.000,000] <dbg> eth_stm32_hal.rx_thread: ETH_MTLQICSR: 0x10000
[00:00:03.000,000] <dbg> eth_stm32_hal.rx_thread: ETH_MACPCSR: 0x0
[00:00:03.000,000] <dbg> eth_stm32_hal.rx_thread: ETH_MACLCSR: 0x0
[00:00:03.000,000] <dbg> eth_stm32_hal.rx_thread:
[00:00:03.500,000] <dbg> eth_stm32_hal.rx_thread: ETH_DMACSR: 0x0
[00:00:03.500,000] <dbg> eth_stm32_hal.rx_thread: ETH_MTLQICSR: 0x10000
[00:00:03.500,000] <dbg> eth_stm32_hal.rx_thread: ETH_MACPCSR: 0x0
[00:00:03.500,000] <dbg> eth_stm32_hal.rx_thread: ETH_MACLCSR: 0x0

The register of PHY chip is read well.

[00:00:00.000,000] <dbg> eth_stm32_hal.eth_initialize: Basic Control Register: 0x3000
[00:00:00.000,000] <dbg> eth_stm32_hal.eth_initialize: Basic Status Register: 0x7809
[00:00:00.000,000] <dbg> eth_stm32_hal.eth_initialize: PHY Identifier 1 Register: 0x7
[00:00:00.000,000] <dbg> eth_stm32_hal.eth_initialize: PHY Identifier 2 Register: 0xc131

Can someone please advise on this phenomenon? 😖

I've tested your development branch for the driver some weeks ago and found the problem in dma_tx/rx buffers allocation. I've also got same issue (RBU/TBU). Since the buffers have been moved to non-cachable SRAM area (AXI-SRAM, AHB-SRAM), which is accessible by the ETH-DMA, the driver works fine with sample projects like samples/net/sockets/dumb_http_server_mt. I've also created according PR (see above).

@KozhinovAlexander
Copy link
Collaborator

KozhinovAlexander commented Jul 10, 2020

@lochej @erwango @ABOSTM

Dear all I've tested the interrupt approach (see comments in #26226) from @lochej on my nucleo-h745zi-q board. The branch itself is in my repo and is ready for @lochej to be integrated after the current PR is merged.

The performance were tested with following ping configuration on 1k ping packets with 0.01 sec. ping interval:
ping -i 0.01 <my_ipv4> -c 1000 > log_file.log

The board has static IP address and were connected to my FritzBox 7590 router. My Mac laptop were connected over 5GHz WiFi to the same router. The distance between the router and the laptop was just about 1 meter.

Note: Due to used WiFi my performance tests may vary from @lochej ones and can face lost packets.

The results of the tests are the following:

  1. Old approach: Polling TX:
    1000 packets transmitted, 133 packets received, +2 duplicates, 86.7% packet loss round-trip min/avg/max/stddev = 1.037/347.861/1002.657/372.646 ms

  2. New approach (thnx to @lochej ): Interrupt TX:
    1000 packets transmitted, 508 packets received, 49.2% packet loss round-trip min/avg/max/stddev = 1.154/65.999/742.486/150.473 ms

Thus we see the increase in performance by factor ~2 (372ms / 150ms and 86.7%/49.2%) in ping response deviation time and number of the lost packets. Especially interesting is the average ping response time decrease by almost factor of ~5.3 = avg(348ms) / avg(66 ms). Thus the gain of the improvement can be clearly seen and the improvement from @lochej must be implemented.

P.S.: @lochej Please feel free to use my repo to create your own PR, since this my branch is only copy/paste of your solution.

@lochej
Copy link
Collaborator

lochej commented Jul 11, 2020

@lochej @erwango @ABOSTM

Dear all I've tested the interrupt approach (see comments in #26226) from @lochej on my nucleo-h745zi-q board. The branch itself is in my repo and is ready for @lochej to be integrated after the current PR is merged.

The performance were tested with following ping configuration on 1k ping packets with 0.01 sec. ping interval:
ping -i 0.01 <my_ipv4> -c 1000 > log_file.log

The board has static IP address and were connected to my FritzBox 7590 router. My Mac laptop were connected over 5GHz WiFi to the same router. The distance between the router and the laptop was just about 1 meter.

Note: Due to used WiFi my performance tests may vary from @lochej ones and can face lost packets.

The results of the tests are the following:

1. Old approach: Polling TX:
   `1000 packets transmitted, 133 packets received, +2 duplicates, 86.7% packet loss round-trip min/avg/max/stddev = 1.037/347.861/1002.657/372.646 ms`

2. New approach (thnx to @lochej ): Interrupt TX:
   `1000 packets transmitted, 508 packets received, 49.2% packet loss round-trip min/avg/max/stddev = 1.154/65.999/742.486/150.473 ms`

Thus we see the increase in performance by factor ~2 (372ms / 150ms and 86.7%/49.2%) in ping response deviation time and number of the lost packets. Especially interesting is the average ping response time decrease by almost factor of ~5.3 = avg(348ms) / avg(66 ms). Thus the gain of the improvement can be clearly seen and the improvement from @lochej must be implemented.

P.S.: @lochej Please feel free to use my repo to create your own PR, since this my branch is only copy/paste of your solution.

Thanks for your feedback on my method :) Sure that will be a great addition to the ethernet driver for both performance et reliability. I will need a bit of time to PR my method due to vacations.

To complete your benchmarks:
I didn't notice packet losses when connecting to the board (Nucleo-H743ZI) directly or when passing through my router to connect to the board (with DHCPv4 functionality working perfectly).

Also my ping response time where excellent with very low stddev and avg response time of less than 5ms even when passing through wifi to the router down to the board. Note that my system clock was 96MHz.

I will provide more benchmarks in the future and additionnal support for the nucleo-h743zi board especially for the ethernet and system clocks support.

@KozhinovAlexander
Copy link
Collaborator

@lochej @erwango @ABOSTM
Dear all I've tested the interrupt approach (see comments in #26226) from @lochej on my nucleo-h745zi-q board. The branch itself is in my repo and is ready for @lochej to be integrated after the current PR is merged.
The performance were tested with following ping configuration on 1k ping packets with 0.01 sec. ping interval:
ping -i 0.01 <my_ipv4> -c 1000 > log_file.log
The board has static IP address and were connected to my FritzBox 7590 router. My Mac laptop were connected over 5GHz WiFi to the same router. The distance between the router and the laptop was just about 1 meter.
Note: Due to used WiFi my performance tests may vary from @lochej ones and can face lost packets.
The results of the tests are the following:

1. Old approach: Polling TX:
   `1000 packets transmitted, 133 packets received, +2 duplicates, 86.7% packet loss round-trip min/avg/max/stddev = 1.037/347.861/1002.657/372.646 ms`

2. New approach (thnx to @lochej ): Interrupt TX:
   `1000 packets transmitted, 508 packets received, 49.2% packet loss round-trip min/avg/max/stddev = 1.154/65.999/742.486/150.473 ms`

Thus we see the increase in performance by factor ~2 (372ms / 150ms and 86.7%/49.2%) in ping response deviation time and number of the lost packets. Especially interesting is the average ping response time decrease by almost factor of ~5.3 = avg(348ms) / avg(66 ms). Thus the gain of the improvement can be clearly seen and the improvement from @lochej must be implemented.
P.S.: @lochej Please feel free to use my repo to create your own PR, since this my branch is only copy/paste of your solution.

Thanks for your feedback on my method :) Sure that will be a great addition to the ethernet driver for both performance et reliability. I will need a bit of time to PR my method due to vacations.

To complete your benchmarks:
I didn't notice packet losses when connecting to the board (Nucleo-H743ZI) directly or when passing through my router to connect to the board (with DHCPv4 functionality working perfectly).

Also my ping response time where excellent with very low stddev and avg response time of less than 5ms even when passing through wifi to the router down to the board. Note that my system clock was 96MHz.

I will provide more benchmarks in the future and additionnal support for the nucleo-h743zi board especially for the ethernet and system clocks support.

Which project have you used to ping the board for the performance tests? I've used dumb_http_server_mt from Zephyr's examples pool.

@lochej
Copy link
Collaborator

lochej commented Jul 13, 2020

@Nukersson I have used the single threaded Dumb HTTP Server and the Coap Server from the zephyr socket samples :)

@KozhinovAlexander
Copy link
Collaborator

KozhinovAlexander commented Jul 18, 2020

@lochej Just tried to ping with 1ms and 500us. It won't work properly on my machine. I'll try it later (at the time you PR is prepared) with proper router settings or even direct connection to my laptop.

@KozhinovAlexander
Copy link
Collaborator

@carlescufi Actually solved by #26226. Should it be closed now?

@erwango
Copy link
Member

erwango commented Jul 21, 2020

Fixed by #26226

@erwango erwango closed this as completed Jul 21, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
platform: STM32 ST Micro STM32
Projects
None yet
Development

No branches or pull requests

8 participants