Skip to content

feat(freertos-s32z2): bring up lwIP over NETC Ethernet in poll mode - #23

Merged
youtalk merged 7 commits into
feat/freertos-s32z2-bootfrom
feat/freertos-s32z2-net
Jun 8, 2026
Merged

youtalk merged 7 commits into
feat/freertos-s32z2-bootfrom
feat/freertos-s32z2-net

Conversation

@youtalk

@youtalk youtalk commented Jun 1, 2026 •

Copy link
Copy Markdown
Member

Summary

Part 3 of the S32Z2 FreeRTOS stack (on top of #22). Adds the lwIP + NETC
networking path, run in poll mode (no RX IRQ, avoiding the R52 lazy-FPU
ISR wall):

  • lwip_bringup.c — initialises the NETC switch + Ethernet controller, brings
    the interface up with a deterministic static IP matching the DDS bind, and
    enables the ETH0 RX RGMII clock (MC_CGM_1 MUX_7, PHY-driven external RXC)
    that the default clock config left disabled — so the MAC RX state machine had
    no clock and received nothing while TX worked.
  • vendor_patched/eth_port.c — fixes the upstream poll (STD_OFF) path: seed the
    RX ring in STD_OFF; recycle freed RX pbufs via pbuf->if_idx/rx_buf (the ring
    otherwise stalled after ETH_RXBD_NUM frames); balance the pbuf_coalesce ref
    count on TX (a double-free that spun lwIP's assert); and make the netif
    linkoutput non-blocking (bounded retry + sys_mbox_trypost_fromisr, never
    sleeping under LOCK_TCPIP_CORE).
  • ethif_shim.c — bridges the AUTOSAR EthIf RxIndication/TxConfirmation
    callbacks and supplies OsIf_TimeDelay for the poll thread.
  • lwipopts.h — sizes the netconn / UDP-PCB / mailbox pools for CycloneDDS.
  • platform_network.h — dispatches PLATFORM_FREERTOS_S32Z2 to the new
    freertos_network.h.

The non-blocking linkoutput is the key fix: a blocking linkoutput under the TCP/IP
core lock deadlocked tcpip_thread and froze both RX and TX once the TX ring
filled (the long-standing "one discovery burst then DDS-silent" symptom).

Evidence — RX and TX both flow on hardware (gdb datapath probe)

After the fix, RX delivery (rxind0) and TX confirmations (txconf0) both climb,
the TCP/IP core lock is free, and the INPKT pool drains:

[NETCNT t~5s]  poll_iters=703   eth_recv=827    eth_got=124  tx_calls=462  rxind0=124  txconf0=126
[NETCNT t~12s] poll_iters=7052  eth_recv=7299   eth_got=248  tx_calls=531  rxind0=248  txconf0=195
[NETCNT t~20s] poll_iters=14567 eth_recv=14924  eth_got=357  tx_calls=594  rxind0=357  txconf0=258
[NETCNT t~28s] poll_iters=22264 eth_recv=22650  eth_got=386  tx_calls=631  rxind0=386  txconf0=295

[MEMP t~28s] 9:TCPIP_MSG_INPKT used=0 max=8 avail=8      # drains (no starvation)
[HANDOFF t~28s] core_lock_count=0 core_lock_holder=0x0   # core lock FREE

(The temporary gdb-only datapath counters used to capture this are stripped from
the committed eth_port.c.)

Stack

#21 → #22 → this PR → DDS round-trip. No CI files touched.

Copilot AI 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.

Pull request overview

This PR adds the FreeRTOS S32Z2 networking backend by bringing up lwIP over the NXP NETC Ethernet controller in poll mode, wiring the platform dispatch to the new backend, and introducing a patched NETC↔lwIP port to avoid core-lock deadlocks and RX ring stalls.

Changes:

  • Add S32Z2-specific lwIP configuration headers and a NETC/lwIP bring-up implementation.
  • Add an EthIf/OsIf shim to bridge AUTOSAR-style driver callbacks into the lwIP port and provide missing OS hooks.
  • Introduce a vendor-patched eth_port.c intended to fix poll-mode RX/TX lifecycle issues and make linkoutput non-blocking.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 24 comments.

Show a summary per file
File Description
actuation_module/include/platform/platform_network.h Routes PLATFORM_FREERTOS_S32Z2 to the new S32Z2 FreeRTOS networking backend.
actuation_module/include/platform/freertos/s32z2/lwipopts.h Adds lwIP configuration tuned for S32Z2 + CycloneDDS usage.
actuation_module/include/platform/freertos/s32z2/lwipcfg.h Provides a minimal stub required by NXP lwIP glue headers.
actuation_module/include/platform/freertos/s32z2/lwip_init.h Declares the S32Z2 lwIP bring-up entry point.
actuation_module/include/platform/freertos/s32z2/freertos_network.h Implements configure_network() for the S32Z2 FreeRTOS target.
actuation_module/freertos_s32z2/vendor_patched/eth_port.c Adds a patched NETC↔lwIP integration layer (poll-mode focus).
actuation_module/freertos_s32z2/lwip_bringup.c Initializes NETC + lwIP and configures the network interface.
actuation_module/freertos_s32z2/ethif_shim.c Bridges EthIf callbacks to the lwIP port and supplies missing OS hooks.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@youtalk
youtalk force-pushed the feat/freertos-s32z2-boot branch from 9e0777f to 03ff0a6 Compare June 1, 2026 20:43
@youtalk
youtalk force-pushed the feat/freertos-s32z2-net branch from 2ef0c7f to e4508ea Compare June 1, 2026 20:43
@youtalk
youtalk marked this pull request as ready for review June 1, 2026 20:58
youtalk added 3 commits June 1, 2026 14:01
Add the lwIP + NETC networking path for the S32Z2 port:

- lwip_bringup.c initialises the NETC switch and Ethernet controller, brings up
  the interface with a deterministic static IP that matches the DDS bind, and
  enables the ETH0 RX RGMII clock (MC_CGM_1 MUX_7, sourced from the PHY-driven
  external RXC) which the default clock config left disabled, so the MAC RX
  state machine had no clock and received nothing while TX worked.
- vendor_patched/eth_port.c runs NETC RX/TX completion in poll mode (STD_OFF);
  the upstream poll path was never exercised and is fixed here: seed the RX ring
  in STD_OFF, recycle freed RX pbufs via pbuf->if_idx/rx_buf (the ring otherwise
  stalled after ETH_RXBD_NUM frames), balance the pbuf_coalesce ref count on TX
  (a double-free that spun lwIP's assert), and make the netif linkoutput
  non-blocking (bounded retry + sys_mbox_trypost_fromisr, never sleeping under
  LOCK_TCPIP_CORE) — a blocking linkoutput deadlocked tcpip_thread and froze
  both RX and TX once the TX ring filled.
- ethif_shim.c bridges the AUTOSAR EthIf RxIndication/TxConfirmation callbacks
  to eth_port.c and supplies OsIf_TimeDelay for the poll thread.
- lwipopts.h sizes the netconn / UDP-PCB / mailbox pools for CycloneDDS's five
  sockets per participant and the tcpip mailbox.
- platform_network.h dispatches the PLATFORM_FREERTOS_S32Z2 branch to the new
  freertos_network.h (lwIP-backed configure_network()).

Stacked on the boot PR.

Signed-off-by: Yutaka Kondo <yutaka.kondo@youtalk.jp>
- Rename the freertos_network.h include guard to PLATFORM__FREERTOS__S32Z2__*
  so it no longer collides with the POSIX simulator's freertos_network.h, and
  match the closing #endif comment.
- Correct the network bring-up comments: the path configures a static IP and
  blocks only on tcpip_init; it does not request DHCP or wait for a lease
  (freertos_network.h, lwip_init.h, lwipopts.h). Disable LWIP_DHCP accordingly
  (unused with static IP).
- lwip_bringup.c: delete the one-shot tcpip_done semaphore after init completes
  (was leaked), and check ip4addr_aton() return values so an invalid
  LWIP_STATIC_* override fails loudly instead of silently configuring 0.0.0.0.

Signed-off-by: Yutaka Kondo <yutaka.kondo@youtalk.jp>
Address PR review (eth_port.c:12): the vendored NXP lwIP NETC glue carried the
NXP Confidential and Proprietary header and must not live in this public repo.
Replace it with vendor_patched/eth_port.c.patch (our poll-mode datapath fixes:
RX-ring seeding, pbuf recycling, balanced pbuf_coalesce ref, non-blocking
linkoutput); the build copies the pristine NXP eth_port.c from $LWIP_PATH and
applies this patch at configure time.

Signed-off-by: Yutaka Kondo <yutaka.kondo@youtalk.jp>
youtalk added 3 commits June 5, 2026 14:04
main() ignored configure_network()'s return value, so the firmware could
construct the DDS/controller stack and report "Live" even after lwIP/NETC
failed to come up. Every platform's configure_network() returns 0 on
success and nonzero on failure, so check it and std::exit(1) on failure,
matching the file's existing error-handling idiom.

Addresses PR #23 review (oguzkaganozt).

Signed-off-by: Yutaka Kondo <yutaka.kondo@youtalk.jp>
tcpip_init_done() received &tcpip_done, the address of
lwip_bring_up_blocking()'s local handle. On the 5 s timeout path the
function returns and its stack frame dies while the tcpip thread may still
run the callback and dereference that dead address. Pass the
SemaphoreHandle_t value directly (it is a pointer typedef) so the callback
never touches our stack.

Addresses PR #23 review (oguzkaganozt).

Signed-off-by: Yutaka Kondo <yutaka.kondo@youtalk.jp>
…gnostically

eth_port.c.patch carried mixed CRLF/LF endings and trailing whitespace,
which `git diff --check` flagged extensively and made review and apply
fragile. Normalize it to pure LF with no trailing whitespace.

GNU patch refuses to apply across a CRLF/LF mismatch ("different line
endings") and the NXP vendor sources are CRLF, so s32z2_apply_vendor_patch()
now strips CRs from both the copied source and the patch before applying --
robust to either ending (port.c.patch, still CRLF, is unaffected). A
unified-diff context line for tab-indented vendor code intrinsically begins
"<space><tab>", which `git diff --check` reports as space-before-tab; a
scoped .gitattributes exempts the committed patches from whitespace checks.

Verified: both vendor patches apply (rc=0) with byte-identical output and
`git diff --check` is clean.

Addresses PR #23 review (oguzkaganozt).

Signed-off-by: Yutaka Kondo <yutaka.kondo@youtalk.jp>
@youtalk
youtalk requested a review from oguzkaganozt June 5, 2026 21:11

@oguzkaganozt oguzkaganozt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM

@youtalk
youtalk merged commit 5d60d82 into feat/freertos-s32z2-boot Jun 8, 2026
1 check failed
@oguzkaganozt
oguzkaganozt deleted the feat/freertos-s32z2-net branch October 11, 2026 13:59
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.

3 participants