BKPT LabsDOCS/TRACE DOMAINS/STM32N6 ETHERNET / LWIP BKPT DEBUG & VIEWALYZER RS
TRACE DOMAINS · PRACTICAL GUIDES

STM32N6 Ethernet / lwIP

Follow frames from the MAC through DMA descriptors and lwIP; distinguish receive pressure, wire errors and stack drops.

Download domain JSON · GitHub source · Domain catalog

Probe sampled · Descriptor com.bkpt.stm32-ethernet · version 0.9.0 · domain API 1.

Purpose and prerequisites

Targets the STM32N6570-DK Ethernet/lwIP demo, using STM32N657 secure SVD names ETH_S and RCC_S. Requires the exact ELF/layout: four RX descriptors with 24-byte stride, ownership at +12, and 16-bit lwIP statistics at the offsets listed below. It is not a generic pack for every STM32 Ethernet controller. The Ethernet clock guard must pass. Firmware statistics must be enabled and the debug view of memory must be coherent.

Engineering interpretation

Compare MAC arrivals, software-owned descriptors and lwIP counters to locate receive pressure. MAC packets advancing while IP progress stops suggests the receive path is not keeping up, but cache visibility and different traffic populations must be considered. FIFO overflow, descriptor backlog and UDP drops identify different layers. A quiet receive counter is not necessarily failure when no peer sends traffic. This firmware keeps DMA descriptors in non-cacheable AXISRAM while lwip_stats can lag through cache write-back. The two clear-on-read inputs consume counts that another reader would otherwise see; this is a meaningful observation side effect.

Acquisition and validity

The descriptor declares 21 inputs and 13 derived channels, with a requested default of 100 Hz per input. Unsupported/unsafe rows remain unavailable. The achieved poll rate depends on the probe and selected inputs.

Global guard: (RCC_S.RCC_AHB5ENR & 0x02000000) = 0x02000000. ETH1 clock disabled (RCC_AHB5ENR.ETH1EN clear): the block is unclocked and reads return zeros, not data

SVD device: STM32N657. Target prefix: STM32N65.

Inputs are sampled separately while firmware runs. DWARF paths require the exact Debug ELF; unresolved or null pointers produce unavailable values. A readable object is not proof that it has finished initialization. Firmware can update or reuse it between reads. Missing observations propagate to dependent fields and checks.

Cards with a capacity reference show value / capacity, not a percentage. Both readings must be available, capacity must be positive, and the value must lie between zero and capacity. Otherwise the card is unavailable. Individual fields retain their raw values in traces. Saved observations describe their acquisition time, not fresh target state.

Cards and tables

Traffic

MAC counter observations and derived rates. Host polling can miss brief state transitions.

CARD OR ROW READING AND SIGNIFICANCE UNIT
MAC receive rate · eth.rx_rateInterval average of good unicast MAC receive-counter changes. Broadcast/multicast traffic is excluded.pkts/s
MAC transmit rate · eth.tx_rateInterval average of good MAC transmit-counter changes. It is packet rate, not bit rate.pkts/s
Received good frames · eth.rx_goodGood received unicast packets only. Broadcast and multicast have separate hardware counters and are not included here.pkts
Transmitted good frames · eth.tx_goodGood transmitted MAC packets, a wrapping 32-bit counter. It records MAC activity, not delivery acknowledged by the remote application.pkts

Receive path

Descriptor occupancy and queue/state snapshots describe the instant sampled. A brief stall can occur between observations.

CARD OR ROW READING AND SIGNIFICANCE UNIT
Descriptors awaiting the application · eth.rx_ringCount of four RX descriptors whose OWN bit is clear: DMA has handed ownership to software. It is an instantaneous backlog indicator, not total traffic or proof every descriptor holds a valid packet.desc
Queued receive packets · eth.rxq_packetsPacket count in the receive MTL queue at that instant. Distinct from descriptors awaiting software in RAM.pkts
Receive queue fill state · eth.rxq_fillReceive queue fill category: empty, below threshold, above threshold or full. It is not a percentage. Values.Raw value / decoded state
DMA / Receive DMA state · eth.rx_dma_stateReceive DMA process-state code. Suspension can accompany descriptor starvation, but one sampled state cannot establish duration or root cause. Values.Raw value / decoded state
DMA / Current receive descriptor address · eth.rx_ring_curCurrent RX descriptor address. Compare movement with backlog; it is a pointer, not a packet count.Raw value / decoded state
Queue / Receive queue read state · eth.rxq_read_stateReceive queue read-controller state. Compare with fill and DMA activity. Values.Raw value / decoded state
MAC / MAC receive state · eth.mac_rx_stateReceive MAC state-machine code at the poll instant; short transitions may never be sampled. Values.Raw value / decoded state

Transmit path

Decoded controller states from the sampled status registers.

CARD OR ROW READING AND SIGNIFICANCE UNIT
Transmit DMA state · eth.tx_dma_stateTransmit DMA process-state code. Compare with TX demand/rate; waiting or suspension can be normal without work. Values.Raw value / decoded state
Transmit queue read state · eth.txq_read_stateTransmit queue read-controller state. Interpret with demand, not as a standalone error. Values.Raw value / decoded state
MAC transmit state · eth.mac_tx_stateTransmit MAC state-machine code at the poll instant; it is not a utilization percentage. Values.Raw value / decoded state

Errors and drops

Missed-frame and overflow fields come from consuming counters and describe read intervals. CRC/alignment and stack drops are cumulative.

CARD OR ROW READING AND SIGNIFICANCE UNIT
Wire / CRC errors · eth.rx_crc_errCumulative received CRC-error packets. Increases direct investigation toward physical-link integrity; they do not uniquely identify cable, PHY or EMI as the cause.pkts
Wire / Alignment errors · eth.rx_align_errCumulative alignment-error packets; compare with CRC errors and MAC configuration when investigating wire-side corruption.pkts
Receive / Frames missed in this read interval · eth.rx_missed_framesMissed-packet field of the consuming MTL read. Positive means receive loss in that read interval; compare queue, FIFO and descriptors before assigning a cause.frames
Receive / FIFO overflow count in this read interval · eth.rx_fifo_overflowFIFO overflow count in the consuming MTL read interval. Points to receive buffering/drain pressure, not necessarily wire corruption.frames
DMA / DMA misses in this read interval · eth.dma_missed_framesDMA missed-frame count in the read interval. Counter saturation and other firmware readers can limit observed totals.frames
Stack / IP packets dropped · lwip.ip_drop16-bit IP drop statistic. Inspect alongside IP receive progress; it represents stack-layer drops, not a MAC error counter.Raw value / decoded state
Stack / UDP datagrams dropped · lwip.udp_drop16-bit UDP drop statistic. No listener/PCB or receive-resource pressure can explain growth; compare socket behavior and memory use.Raw value / decoded state

Network stack

Application-owned lwIP counters. Offsets and widths must match this exact N6 demo ELF and its lwIP configuration.

CARD OR ROW READING AND SIGNIFICANCE UNIT
IP packets accepted · lwip.ip_recv16-bit lwIP IP receive statistic at this exact build offset. Compare its progress with MAC unicast arrivals; cache write-back can delay what the probe sees.Raw value / decoded state
UDP datagrams accepted · lwip.udp_recv16-bit UDP receive statistic. It tracks the stack receive path, not guaranteed application consumption.Raw value / decoded state
Heap bytes in use · lwip.mem_usedlwIP heap bytes currently used, a level rather than a lifetime allocation counter. The exact field width/offset depends on this lwIP configuration.B

Raw registers and access limits

Registers, addresses and packed fields are kept out of graphs by default. PHY MDIO access remains unsafe and unavailable; grouping does not authorize a read.

CARD OR ROW READING AND SIGNIFICANCE UNIT
MAC / MMC control · eth.mmc_controlMMC counter control word. RSTONRD bit 2 must be clear before polling the cumulative MMC counters.Raw value / decoded state
MAC / MAC configuration · eth.mac_configMAC configuration programmed by the driver, including speed/duplex and RX/TX enables. This is not a direct PHY link observation.Raw value / decoded state
MAC / MAC debug · eth.mac_debugRaw MAC receive/transmit state-machine snapshot; decoded states below describe one sampled instant.Raw value / decoded state
Queues / Transmit queue debug · eth.mtl_txq_dbgRaw MTL transmit-queue debug snapshot. Decoding extracts its read-controller state.Raw value / decoded state
Queues / Receive queue debug · eth.mtl_rxq_dbgRaw MTL receive-queue debug snapshot. Decoding extracts packet count, fill classification and read state.Raw value / decoded state
Consuming counters / Packed MTL missed/overflow sample · eth.rx_missedPacked MTL missed-packet/FIFO-overflow counters. Reading consumes them; do not graph the packed word as a simple packet total.pkts
Consuming counters / Packed DMA missed sample · eth.dma_missedPacked DMA missed-frame counter, consumed by a read. The derived field isolates its count bits.pkts
DMA / DMA debug · eth.dma_debugRaw DMA debug word. Receive and transmit process states are decoded separately.Raw value / decoded state
DMA / DMA channel status · eth.dma_ch0DMA channel 0 status, with write-one-to-clear flags. A read does not acknowledge these flags.Raw value / decoded state
Access limits / PHY link access (not sampled) · eth.phy_linkUnavailable by design. Direct MDIO transactions through the MAC would race the firmware driver; no physical link state is measured.Raw value / decoded state

Every sampled input

All paths below come from the downloadable definition. Integer types specify width and signedness. No scaling is applied to a raw read. A field without a declared unit is a code, count, address or raw register; its engineering meaning is explained above or below.

INPUT SOURCE / ADDRESS PATH TYPE INTERPRETATION / ACCESS
eth.tx_goodETH_S.ETH_TX_PACKET_COUNT_GOODu32See its card/table above. Counter policy: wrapping. Guard: (ETH_S.ETH_MMC_CONTROL & 0x4) = 0x0. MMC_CONTROL.RSTONRD is set: counter reads self-clear, sampling would destroy the values it reports
eth.rx_goodETH_S.ETH_RX_UNICAST_PACKETS_GOODu32See its card/table above. Counter policy: wrapping. Guard: (ETH_S.ETH_MMC_CONTROL & 0x4) = 0x0. MMC_CONTROL.RSTONRD is set: counter reads self-clear, sampling would destroy the values it reports
eth.rx_crc_errETH_S.ETH_RX_CRC_ERROR_PACKETSu32See its card/table above. Counter policy: wrapping. Guard: (ETH_S.ETH_MMC_CONTROL & 0x4) = 0x0. MMC_CONTROL.RSTONRD is set: counter reads self-clear, sampling would destroy the values it reports
eth.rx_align_errETH_S.ETH_RX_ALIGNMENT_ERROR_PACKETSu32See its card/table above. Counter policy: wrapping. Guard: (ETH_S.ETH_MMC_CONTROL & 0x4) = 0x0. MMC_CONTROL.RSTONRD is set: counter reads self-clear, sampling would destroy the values it reports
eth.mmc_controlETH_S.ETH_MMC_CONTROLu32See its card/table above.
eth.mac_configETH_S.ETH_MACCRu32See its card/table above.
eth.mac_debugETH_S.ETH_MACDRu32See its card/table above.
eth.mtl_txq_dbgETH_S.ETH_MTLTXQ0DRu32See its card/table above.
eth.mtl_rxq_dbgETH_S.ETH_MTLRXQ0DRu32See its card/table above.
eth.rx_missedETH_S.ETH_MTLRXQ0MPOCRu32See its card/table above. Counter policy: clear_on_read.
eth.dma_debugETH_S.ETH_DMADSRu32See its card/table above.
eth.dma_ch0ETH_S.ETH_DMAC0SRu32See its card/table above.
eth.rx_ring_curETH_S.ETH_DMAC0CARXDRu32See its card/table above.
eth.dma_missedETH_S.ETH_DMAC0MFCRu32See its card/table above. Counter policy: clear_on_read.
eth.phy_linkPHY registers go through MDIO (MACMDIOAR/MACMDIODR) and a debug-port transaction races the driver's own use of the address register; link speed is shown from ETH_MACCR insteadu32See its card/table above. PHY registers go through MDIO (MACMDIOAR/MACMDIODR) and a debug-port transaction races the driver's own use of the address register; link speed is shown from ETH_MACCR instead
eth.rx_ringDMARxDscrTab: 4 entries, 24-byte stride; 32-bit ownership word at +12, mask 0x80000000; count clear ownership bits.u32See its card/table above.
lwip.ip_recvlwip_stats + 74 bytesu16See its card/table above. Counter policy: wrapping.
lwip.ip_droplwip_stats + 78 bytesu16See its card/table above. Counter policy: wrapping.
lwip.udp_recvlwip_stats + 122 bytesu16See its card/table above. Counter policy: wrapping.
lwip.udp_droplwip_stats + 126 bytesu16See its card/table above. Counter policy: wrapping.
lwip.mem_usedlwip_stats + 172 bytesu16See its card/table above.

wrapping tells analysis to account for rollover at the declared integer width; a reset can look like a wrap, and multiple wraps between samples cannot be recovered. monotonic uses sampled increases without inventing a reset/wrap delta. clear_on_read reports a consuming read interval, not a lifetime total. A display styled as a counter does not itself establish any of these policies.

Derived fields and rates

CHANNEL CALCULATION MEANING UNIT
eth.rx_dma_state(eth.dma_debug >> 8) & 0xFReceive DMA process-state code. Suspension can accompany descriptor starvation, but one sampled state cannot establish duration or root cause. Values.Code / state
eth.tx_dma_state(eth.dma_debug >> 12) & 0xFTransmit DMA process-state code. Compare with TX demand/rate; waiting or suspension can be normal without work. Values.Code / state
eth.rx_ratemax(0, change in eth.rx_good / elapsed seconds)Interval average of good unicast MAC receive-counter changes. Broadcast/multicast traffic is excluded.pkts/s
eth.tx_ratemax(0, change in eth.tx_good / elapsed seconds)Interval average of good MAC transmit-counter changes. It is packet rate, not bit rate.pkts/s
eth.mac_tx_state(eth.mac_debug >> 17) & 0x3Transmit MAC state-machine code at the poll instant; it is not a utilization percentage. Values.Code / state
eth.mac_rx_state(eth.mac_debug >> 1) & 0x3Receive MAC state-machine code at the poll instant; short transitions may never be sampled. Values.Code / state
eth.txq_read_state(eth.mtl_txq_dbg >> 1) & 0x3Transmit queue read-controller state. Interpret with demand, not as a standalone error. Values.Code / state
eth.rxq_read_state(eth.mtl_rxq_dbg >> 1) & 0x3Receive queue read-controller state. Compare with fill and DMA activity. Values.Code / state
eth.rxq_fill(eth.mtl_rxq_dbg >> 4) & 0x3Receive queue fill category: empty, below threshold, above threshold or full. It is not a percentage. Values.Code / state
eth.rxq_packets(eth.mtl_rxq_dbg >> 16) & 0x3FFFPacket count in the receive MTL queue at that instant. Distinct from descriptors awaiting software in RAM.Code / state
eth.rx_missed_frames(eth.rx_missed >> 16) & 0x7FFMissed-packet field of the consuming MTL read. Positive means receive loss in that read interval; compare queue, FIFO and descriptors before assigning a cause.Code / state
eth.rx_fifo_overflow(eth.rx_missed >> 0) & 0x7FFFIFO overflow count in the consuming MTL read interval. Points to receive buffering/drain pressure, not necessarily wire corruption.Code / state
eth.dma_missed_frames(eth.dma_missed >> 0) & 0x7FFDMA missed-frame count in the read interval. Counter saturation and other firmware readers can limit observed totals.Code / state

Rates need two valid samples at increasing timestamps and are interval averages. Gaps break the calculation. A negative raw delta is clamped to zero by the rate calculation; do not infer an instantaneous event rate from a reset. Unknown map keys pass through numerically; an unmapped code is not a validated physical measurement.

Findings

Application not draining

warning · app-not-draining. lwip.ip_recv does not increase over 250 ms while eth.rx_good advances by at least 50.

Good MAC unicast frames advance while the sampled IP receive counter does not. Check driver scheduling, buffers and the application consumer, but also account for cached statistics and traffic that never reaches IP.

Evidence: lwip.ip_recv, eth.rx_good, eth.rx_ring, eth.rx_dma_state, eth.rx_missed_frames, lwip.mem_used.

RX frames missed by the MAC

error · rx-frames-missed. eth.rx_missed_frames ≥ 1 at a valid sample.

The MTL missed-packet field is positive in a consuming read interval. This establishes reported receive loss, not a unique descriptor-starvation diagnosis. Compare FIFO overflow, queue fill, DMA state and ring ownership.

Evidence: eth.rx_missed_frames, eth.rx_fifo_overflow, eth.rx_ring, eth.rx_dma_state, lwip.ip_recv.

CRC errors on the wire

error · rx-crc-errors. eth.rx_crc_err increases between valid samples.

The CRC counter advanced. Investigate cable/connector, PHY configuration and electrical integrity alongside alignment errors; this observation alone cannot identify a unique cause.

Evidence: eth.rx_crc_err, eth.rx_align_err, eth.mac_config.

RX stopped while TX continues

warning · rx-stopped. eth.rx_good does not increase over 1000 ms while eth.tx_good advances by at least 1.

The MAC keeps transmitting but nothing is being received. Suspect the receive path specifically: RX DMA state, buffer availability, or the peer no longer sending.

Evidence: eth.rx_rate, eth.tx_rate, eth.rx_dma_state, eth.tx_dma_state.

RX FIFO overflowed

error · rx-fifo-overflow. eth.rx_fifo_overflow ≥ 1 at a valid sample.

Frames were lost inside the MAC's receive FIFO: the MTL queue filled faster than the DMA drained it into memory. Unlike missed frames (no descriptor), this points at bus/DMA throughput or a burst above what the queue depth absorbs. Value is frames lost in one poll interval (clear-on-read).

Evidence: eth.rx_fifo_overflow, eth.rxq_fill, eth.rxq_packets, eth.rx_missed_frames, eth.rx_ring.

RX descriptor ring saturated

suspicious · rx-ring-saturated. eth.rx_ring ≥ 3 for 100 ms of observations.

At least three of four descriptors stayed software-owned across 100 ms of sampled evidence. This is a high-backlog threshold, not literally four-of-four fullness; brief saturation can occur between polls.

Evidence: eth.rx_ring, eth.rx_ring_cur, eth.rx_dma_state, eth.rx_missed_frames.

Datagrams dropped by the stack

warning · stack-dropping. lwip.udp_drop increases between valid samples.

The stack received datagrams and threw them away: no PCB is bound for that port, or the receive queue of a socket nobody is reading is full. Loss above the MAC, so the Ethernet counters stay clean.

Evidence: lwip.udp_drop, lwip.udp_recv, lwip.mem_used, eth.rx_good.

Value dictionaries

These are the exact value mappings in this version of the descriptor. Unlisted status codes remain numeric; they are not implicitly success. Decode a value in the context of its field and validity.

Value map 1

RAW VALUE DECODED LABEL / MAPPED VALUE
0EMPTY
1BELOW_THRESH
2ABOVE_THRESH
3FULL

Value map 2

RAW VALUE DECODED LABEL / MAPPED VALUE
0STOPPED
1FETCHING
3WAITING
4SUSPENDED
5CLOSING
6TIMESTAMP_WR
7TRANSFERRING

Value map 3

RAW VALUE DECODED LABEL / MAPPED VALUE
0IDLE
1READING
2STATUS
3FLUSHING

Value map 4

RAW VALUE DECODED LABEL / MAPPED VALUE
0STOPPED
1FETCHING
2WAITING
3READING
4TIMESTAMP_WR
6SUSPENDED
7CLOSING

Value map 5

RAW VALUE DECODED LABEL / MAPPED VALUE
0IDLE
1READ
2WAITING
3FLUSHING

Value map 6

RAW VALUE DECODED LABEL / MAPPED VALUE
0IDLE
1WAITING
2PAUSE
3TRANSFERRING

Definition and contribution

Checked against the N6 demo main.c, ethernetif.c, lwipopts.h, lwIP stats.h, the STM32N657 CMSIS Ethernet register definitions and the domain rate/counter/finding decoder. Firmware layout and SVD compatibility must be rechecked for any adapted build.

View or propose changes to the canonical JSON. Contribution guide.

Download SHA-256: 5df29bdc78a799741cdb3ad76d7b6555bbc44c84319dea64547d10d2dfa7c170.