Skip to content

Drain the STM32 HAL Ethernet RX ring on every poll and wake the FreeRTOS poll task - #191

Merged
aidangarske merged 3 commits into
wolfSSL:masterfrom
dgarske:stm32_hal_eth_rx
Nov 12, 2026
Merged

aidangarske merged 3 commits into
wolfSSL:masterfrom
dgarske:stm32_hal_eth_rx

Conversation

@dgarske

@dgarske dgarske commented Nov 10, 2026 •

Copy link
Copy Markdown
Member

Description

Fixes #190. Three problems in src/port/stm32_hal/stm32_hal_eth.c that together lost or delayed received frames, most visibly under the FreeRTOS port.

1. Only one frame was read per RX interrupt

hal_eth_poll() cleared the interrupt flag and called HAL_ETH_ReadData() once, which returns a single frame. The DMA raises one RX interrupt for a burst, so a frame queued behind another waited for the next interrupt or the every-100th-poll fallback. In a bare-metal loop that fallback comes around almost at once; under the FreeRTOS poll task each poll is a sleep, so it surfaced as TCP retransmission-sized stalls. Each poll now calls HAL_ETH_ReadData(), and wolfIP_poll() keeps calling until the ring is empty.

2. All RX descriptors shared one buffer

HAL_ETH_RxAllocateCallback() handed every descriptor the same buffer, so a back-to-back frame could be written over the one waiting to be copied. The driver now keeps ETH_RX_DESC_CNT + 1 buffers handed out in ring order; the extra one covers HAL_ETH_ReadData() re-arming the descriptor before it returns the frame. The link callback keeps the HAL's frame-start pointer set so every consumed descriptor is detached and refilled in that order; a frame longer than RxBuffLen, which spans several descriptors, is dropped.

3. No cache maintenance on Cortex-M7

With the D-cache enabled and the buffers in cacheable RAM, the CPU could read stale RX data and the DMA could send stale TX data. RX buffers are now invalidated before the copy and TX frames cleaned before transmit when the D-cache is on.

Notes

  • With WOLFIP_USE_FREERTOS defined, the RX interrupt calls wolfip_freertos_notify_from_isr(). It does not mask itself as docs/porting_guide.md suggests: the HAL IRQ handler clears the RX status only while the RX interrupt is enabled, so masking it from the RX callback can leave the interrupt asserted with nothing to clear it.
  • Header and README notes for the above.

CI

Two jobs that also fail on master, each fixed in its own commit:

  • STM32H563 m33mu full test: under the current GitHub runners the emulated firmware runs markedly slower, so a TLS 1.3 handshake now outlasts the timeout 10 around the TLS echo client and the HTTPS test's curl --max-time 20 is close behind. The handshake time does not depend on the wolfSSL, wolfSSH or wolfMQTT versions the job clones; the same firmware built against the versions from the last green run takes as long in the same container. Both client limits are raised to 60 seconds.
  • wolfGuard interop: the runner kernel now comes from a release without a linux-modules-extra package, and the tunnel modules it needs ship in linux-modules. test-interop-wolfguard.sh installs linux-modules-extra only when apt has one.

Testing

Validated on a NUCLEO-H7S3L8 (STM32H7S3, LAN8742, D-cache on, ETH_RX_DESC_CNT 4) under the FreeRTOS port, with a new TCP connection per HTTP request, with and without WOLFIP_USE_FREERTOS, and under sustained ping load alongside a CPU-bound lower-priority task. Not tested on other STM32 families.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

RX buffer ownership and cache coherency depend on family-specific HAL contracts unavailable in this checkout, requiring human validation of descriptor rearming and cache-enabled DMA behavior beyond the tested H7S3.

No open issues 🎉

What changed in this PR

Addresses #190’s receive latency and frame loss in the STM32 HAL Ethernet driver, particularly when used with the FreeRTOS port.

Changes:

  • Reads RX data on every poll, adds separate receive buffers, performs cache maintenance, and optionally wakes the FreeRTOS poll task from the RX interrupt.
  • Documents FreeRTOS integration, interrupt-priority requirements, and updated driver behavior.
  • Raises emulated TLS client timeouts and makes the optional kernel-module package installation conditional.
File Description
tools/​scripts/​test-interop-wolfguard.sh Installs linux-modules-extra only when available.
src/​port/​stm32_hal/​stm32_hal_eth.h Updates polling, buffer, cache, and interrupt documentation.
src/​port/​stm32_hal/​stm32_hal_eth.c Implements RX polling, buffer rotation, cache maintenance, and FreeRTOS wakeups.
src/​port/​freeRTOS/​README.md Documents the STM32 HAL notifier integration and interrupt-masking exception.
IDE/​STM32Cube/​README.md Adds FreeRTOS build and ETH interrupt-priority guidance.
.github/​workflows/​stm32h563-m33mu.yml Increases HTTPS and TLS echo client timeouts to 60 seconds.

Review effort: Balanced

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fenrir Automated Review — PR #191

Scan targets checked: wolfip-src, wolfip-bugs
Not reviewed (no scan target covers them): .github/workflows/stm32h563-m33mu.yml, IDE/STM32Cube/README.md, src/port/freeRTOS/README.md, tools/scripts/test-interop-wolfguard.sh
Coverage: 2 of 2 in-scope changed file(s) opened by the reviewer

Findings: 1
1 finding(s) posted as inline comments (see file-level comments below)

This review was generated automatically by Fenrir. Reported findings require changes before merge.

Review tier: Max

Comment thread src/port/stm32_hal/stm32_hal_eth.c Resolved
@aidangarske
aidangarske merged commit cbfdd87 into wolfSSL:master Nov 12, 2026
34 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

FreeRTOS port: HTTP latency ~1 s with default poll delay

5 participants