Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions IDE/STM32Cube/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,18 @@ void HAL_ETH_MspInit(ETH_HandleTypeDef* heth)
}
```

### BusFault in an atomic operation on STM32H7R/S

Symptom: a precise BusFault (`CFSR.PRECISERR`, with `BFAR` pointing at the variable) in `__atomic_fetch_add` or another atomic, for example in wolfSSL built with `FREERTOS`.

Cause: the MPU region covering the AXI SRAM is marked Shareable. Atomics compile to `LDREX`/`STREX`, and an exclusive access to Shareable memory faults on this family. Set `IsShareable = MPU_ACCESS_NOT_SHAREABLE` for that region.

Shareable memory is also not held in the Cortex-M7 D-cache, so a Shareable AXI SRAM region runs uncached even with the D-cache enabled.

### Task stacks in DTCM or CCM

wolfIP builds outgoing frames on the stack of the task that sends them, and the Ethernet DMA cannot read core-coupled memory. With `STM32_HAL_ETH_TX_BOUNCE` defined, `stm32_hal_eth.c` copies each frame into a static buffer before transmitting, so the stack may be placed anywhere. It is on by default for STM32H7R/S, whose vendor linker scripts put the main stack in DTCM; define `STM32_HAL_ETH_NO_TX_BOUNCE` there to turn it off. Without it, every stack that wolfIP transmits from must be in memory the Ethernet DMA can reach. The driver's own RX and TX buffers are static data, so the section they are linked into (`.bss` by default) must be in DMA-reachable memory as well.

## Using TLS with wolfIP

To use TLS (HTTPS, secure sockets):
Expand Down
18 changes: 18 additions & 0 deletions src/port/stm32_hal/stm32_hal_eth.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,19 @@ static int hal_eth_poll(struct wolfIP_ll_dev *dev, void *frame, uint32_t len)
return (int)frame_len;
}

/* wolfIP builds outgoing frames on the caller's stack. Sending from a static
* buffer keeps the DMA off that stack, which it cannot reach when the stack
* is in core-coupled memory (DTCM, CCM). On by default for STM32H7R/S, where
* the vendor linker scripts put the main stack in DTCM. Like rx_buffers, the
* buffer must be linked into memory the DMA can reach. */
#if defined(STM32H7RS) && !defined(STM32_HAL_ETH_NO_TX_BOUNCE) && \
!defined(STM32_HAL_ETH_TX_BOUNCE)
#define STM32_HAL_ETH_TX_BOUNCE
#endif
#ifdef STM32_HAL_ETH_TX_BOUNCE
static uint8_t tx_frame[ETH_RX_BUFFER_SIZE] __attribute__((aligned(32)));
#endif

/**
* @brief Send an Ethernet frame
*/
Expand All @@ -247,6 +260,11 @@ static int hal_eth_send(struct wolfIP_ll_dev *dev, void *frame, uint32_t len)
return -1;
}

#ifdef STM32_HAL_ETH_TX_BOUNCE
memcpy(tx_frame, frame, len);
frame = tx_frame;
#endif

#ifdef ETH_DCACHE_ENABLED
if (ETH_DCACHE_ENABLED()) {
SCB_CleanDCache_by_Addr((uint32_t *)frame, (int32_t)len);
Expand Down
4 changes: 4 additions & 0 deletions src/port/stm32_hal/stm32_hal_eth.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@
* several descriptors and is dropped
* - On Cortex-M7 with the D-cache enabled, RX buffers are invalidated and
* TX frames cleaned around each DMA transfer
* - With STM32_HAL_ETH_TX_BOUNCE, TX frames are copied into a static buffer
* before transmission, so the caller's stack may be in memory the DMA
* cannot reach (DTCM, CCM). Default on STM32H7R/S; turn it off there with
* STM32_HAL_ETH_NO_TX_BOUNCE
* - Assumes CubeMX generates `heth` and `TxConfig` as extern globals
*/

Expand Down
Loading