cancel
Showing results for 
Search instead for 
Did you mean: 

[bug fixes] STM32H7 Ethernet

alister
Lead

@Amel NASRI​, @ranran​, @Piranha​, @Harrold​, @Pavel A.​ 

V2 of my fixes and improvements to H7_FW V1.5.0/V1.6.0 Ethernet...

Changes include

  • Decoupling receive buffers from receive descriptors so buffers may be held any length time without choking receive.
  • Optionally queuing transmit, so transmit doesn't need to block until complete.
  • Many bug fixes.

Find full details and source in the attached zip. V1 was posted to another developer's question. Please post any questions about V2 here.

97 REPLIES 97
Piranha
Chief II

> There is additional task to handle PHY connection (from CubeH7 example)

Which has the flaws described shortly but pretty clearly in "lwIP API related" part of my topic:

https://community.st.com/s/question/0D50X0000BOtfhnSQB/how-to-make-ethernet-and-lwip-working-on-stm32

Mikhail Z
Senior II

Keil has its own version of the STM32H7 drivers (current version 2.5.0), including the drivers for Ethernet MAC and PHY. Has anybody checked if they have all the same problems as HAL?

I see at https://community.st.com/s/question/0D50X0000BWqXETSQ3/ethernet-complexity you'd mentioned "STM32Cube_FW_H7 1.5.0 does work".

But it doesn't. This page describes FW_H7 1.5.0/1.6.0 bugs and my fixes/improvements to it. I don't use Keil.

When I said that it works I just meant it does the simple things described in the readme (because this example in many other releases of STM32Cube_FW_H7 doesn't even ping); I didn't mean it is bug-free.

My question about Keil drivers still remains for those who do use Keil.

kqian
Associate II

any same fix on the STM32F7 firmware​?

>any same fix on the STM32F7 firmware​?

Check Piranha's issues list at https://community.st.com/s/question/0D50X0000BOtfhnSQB/how-to-make-ethernet-and-lwip-working-on-stm32, and search Community for posts about STM32F7 Ethernet.

Reply form Keil forum:

"Keil STM32H7 DFP pack 2.5.0 (current version) integrates the latest STM32CubeH7 Firmware Package 1.6.0.

There are just a few patches applied on the following files:

  • Drivers\BSP\STM32H7B3I-EVAL\stm32h7b3i_eval_io.h
  • Drivers\BSP\STM32H7B3I-EVAL\stm32h7b3i_eval_lcd.h
  • Drivers\BSP\STM32H743I-EVAL\stm32h743i_eval.c
  • Drivers\BSP\STM32H743I-EVAL\stm32h743i_eval_io.h
  • Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_def.h
  • Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_ll_usb.c

Those are minor patches and the original file is kept with the additional extension .original. So it should be easy to see the changes."

SLuka.1
Associate II

Hi Alister, and other community members. I’ve tested your code on stm32h745 – speed is awesome (90Mbit/s) in comparison to original HAL. But I’ve noticed, that CPU utilization is rather high during TCP transmission from board (about 50% @ 480Mhz M7 Core.) While during reception is only about 20-25%. Could someone show me direction for digging to get more free CPU time. Or, maybe, I’m doing something wrong?

Thank you in advance.

Thanks for the feedback.

I'd only made easy improvements to the ETH driver's transmit code. I'd identified its throughput would be sub-optimal because its implementation is tentative because it doesn't start any descriptors until all its buffers are successfully linked and so it transmits late. But transmit was not a priority for me and, apart from adding the queuing in ethernetif.c, its shape is unchanged.

For transmit's high CPU utilization, are you able to cast fresh eyes over it?

>Could someone show me direction for digging to get more free CPU time.

First, without changing any of the ETH driver...

  1. Is ETH_TX_QUEUE_ENABLE enabled? ETH_TX_QUEUE_ENABLE's HAL_ETH_Transmit_IT should use less cycles than HAL_ETH_Transmit.
  2. In low_level_output, is TxQueueFree ever empty? Try increasing ETH_TX_QUEUE_SIZE.
  3. Is ETH_TX_BUFFERS_ARE_CACHED enabled and is d-cache enabled? Enabling ETH_TX_BUFFERS_ARE_CACHED would be faster than sticking lwIP's heap in an uncached MPU region.
  4. Is i-cache enabled?

Next, determine where the cycles are being used:

  1. At https://community.st.com/s/question/0D50X0000AhNBoWSQW/actually-working-stm32-ethernet-and-lwip-demonstration-firmware, @Piranha​ describes using DWT->CYCCNT to count cycles. You could try instrumenting your application with that or a fast 32-bit timer counter to determine where the cycles are being spent.

Improving the ETH driver:

  1. Don't start this without first determining where the cycles are being spent. Redesign HAL_ETH_Transmit_IT to start the descriptors immediately. I haven't done the reading and couldn't start this without study. But some thoughts and questions to probe it... (a) Are the number of buffers linked per transmit packet deterministic? You'd need to study your app and lwIP. You'd want to avoid counting them prior to transmit because it costs cycles. (b) Assuming you'd link each buffer to a descriptor and start it immediately, if you run out of descriptors, how would you quickly/efficiently resume linking the buffers after a previous transmit's complete? Remember your transmit's performed by lwIP's task, tcpip_thread. (c) As immediately linking and starting a descriptor should be a design goal, would it matter if the app or lwIP linked more buffers than you have descriptors? If it matters you'll need to find a way to recover and drop that packet. (d) Descriptors are cheap. Can you do more than one transmit per interrupt? Interrupts cost cycles too. A bit in the descriptor controls that.

@Piranha, can you share any thoughts please?