2025-09-29 6:08 AM - last edited on 2025-09-29 8:13 AM by STackPointer64
void MPU_Config(void)
{
MPU_Region_InitTypeDef MPU_InitStruct = {0};
/* Disable the MPU */
HAL_MPU_Disable();
/* Region 0: Internal RAM (320KB) - Non-cacheable for DMA */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.BaseAddress = 0x20000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_256KB; /* First 256KB */
MPU_InitStruct.SubRegionDisable = 0x0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE; /* For DMA */
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE; /* Non-cacheable for DMA */
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Region 1: Remaining Internal RAM (64KB) */
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
MPU_InitStruct.BaseAddress = 0x20040000;
MPU_InitStruct.Size = MPU_REGION_SIZE_64KB;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Region 2: Internal FLASH (1MB) - Cacheable */
MPU_InitStruct.Number = MPU_REGION_NUMBER2;
MPU_InitStruct.BaseAddress = 0x08000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_1MB;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Region 3: QSPI Flash (16MB) - Cacheable */
MPU_InitStruct.Number = MPU_REGION_NUMBER3;
MPU_InitStruct.BaseAddress = 0x90000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_16MB;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Region 4: SDRAM (8MB) - Cacheable for graphics */
MPU_InitStruct.Number = MPU_REGION_NUMBER4;
MPU_InitStruct.BaseAddress = 0xC0000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_8MB;
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE; /* For DMA2D/LTDC */
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Enable the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT] __attribute__((section(".RxDecripSection"), aligned(32)));
ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT] __attribute__((section(".TxDecripSection"), aligned(32)));
uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUF_SIZE] __attribute__((section(".RxArraySection"), aligned(32)));
uint8_t Tx_Buff[ETH_TX_DESC_CNT][ETH_TX_BUF_SIZE] __attribute__((section(".TxArraySection"), aligned(32)));
#define MEM_SIZE 24576
/*----- Default Value for F7 devices: 0x20048000 -----*/
#define LWIP_RAM_HEAP_POINTER 0x20048000
#define PBUF_POOL_BUFSIZE 1536 and my linker Script
/*
******************************************************************************
** @file : STM32F746NGHX_FLASH.ld
** @brief : Linker script for STM32F746NGHx (1024KB FLASH, 320KB RAM)
** - DTCM (64KB) used for stack/heap (fast, CPU-only)
** - AXI SRAM cached (176KB low + optional 48KB high)
** - ETH descriptors in SRAM2 (16KB, non-cacheable)
** - ETH Rx/Tx buffers in AXI 64KB non-cacheable window
** - TouchGFX buffers in SDRAM, assets in QSPI
******************************************************************************
*/
ENTRY( Reset_Handler)
/* ====== Memory map ====== */
MEMORY
{
/* TCMs */
ITCM_RAM (xrw) : ORIGIN = 0x00000000, LENGTH = 16K
DTCM_RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K /* stack/heap, fast */
/* AXI SRAM (cached regions) */
AXI_SRAM_C (xrw) : ORIGIN = 0x20020000, LENGTH = 176K /* main .data/.bss */
AXI_SRAM_C_HI(xrw) : ORIGIN = 0x20050000, LENGTH = 48K /* optional extras */
/* AXI SRAM non-cacheable carve-outs (must match MPU) */
ETHBUFF_NC (xrw) : ORIGIN = 0x20010000, LENGTH = 64K /* ETH Rx/Tx buffers */
SRAM2_NC (xrw) : ORIGIN = 0x2004C000, LENGTH = 16K /* ETH descriptors */
/* Non-volatile / external */
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
QUADSPI (r ) : ORIGIN = 0x90000000, LENGTH = 16M
SDRAM (xrw) : ORIGIN = 0xC0000000, LENGTH = 8M
}
/* ====== Stacks & libc heap placed in DTCM ====== */
_estack = ORIGIN(DTCM_RAM) + LENGTH(DTCM_RAM);
_Min_Heap_Size = 0x0A00; /* libc heap (if used) */
_Min_Stack_Size = 0x0A00; /* process stack reserve */
/* Used by startup to copy .data from FLASH */
_sidata = LOADADDR(.data);
/* ====== Sections ====== */
SECTIONS
{
/* Vector table in FLASH */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector))
. = ALIGN(4);
}> FLASH
/* Code */
.text :
{
. = ALIGN(4);
*(.text) *(.text*)
*(.glue_7) *(.glue_7t)
*(.eh_frame)
KEEP(*(.init)) KEEP(*(.fini))
. = ALIGN(4);
_etext = .;
}> FLASH
/* Constants */
.rodata :
{
. = ALIGN(4);
*(.rodata) *(.rodata*)
. = ALIGN(4);
}> FLASH
/* ARM exception tables */
.ARM.extab (READONLY) :
{
. = ALIGN(4);
*(.ARM.extab* .gnu.linkonce.armextab.*)
. = ALIGN(4);
}> FLASH
.ARM (READONLY) :
{
. = ALIGN(4);
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
. = ALIGN(4);
}> FLASH
.preinit_array (READONLY) :
{
. = ALIGN(4);
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
}> FLASH
.init_array (READONLY) :
{
. = ALIGN(4);
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
}> FLASH
.fini_array (READONLY) :
{
. = ALIGN(4);
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
. = ALIGN(4);
}> FLASH
/* --------- Initialized data in AXI cached RAM --------- */
.data :
{
. = ALIGN(4);
_sdata = .;
*(.data) *(.data*)
/* Optional: fast functions in RAM */
*(.RamFunc) *(.RamFunc*)
. = ALIGN(4);
_edata = .;
}> AXI_SRAM_C AT > FLASH
/* --------- Uninitialized data in AXI cached RAM --------- */
.bss (NOLOAD) :
{
. = ALIGN(4);
_sbss = .;
__bss_start__ = _sbss;
*(.bss) *(.bss*) *(COMMON)
. = ALIGN(4);
_ebss = .;
__bss_end__ = _ebss;
}> AXI_SRAM_C
/* --------- Optional high cached RAM (place large arrays manually) --------- */
.ram_high (NOLOAD) :
{
. = ALIGN(4);
*(.ram_high) *(.ram_high.*)
. = ALIGN(4);
}> AXI_SRAM_C_HI
/* --------- DTCM-only data (fast, CPU-only) OPTIONAL --------- */
.dtcm_data :
{
. = ALIGN(4);
*(.dtcm_data) *(.dtcm_data.*)
. = ALIGN(8);
}> DTCM_RAM AT > FLASH
.dtcm_bss (NOLOAD) :
{
. = ALIGN(8);
*(.dtcm_bss) *(.dtcm_bss.*)
. = ALIGN(8);
}> DTCM_RAM
/* --------- C library heap + main stack in DTCM --------- */
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE(end = .);
PROVIDE(_end = .);
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
}> DTCM_RAM
/* --------- Ethernet: NON-CACHEABLE --------- */
/* Descriptors in SRAM2 (16KB) */
.RxDecripSection (NOLOAD) :
{
. = ALIGN(32);
*(.RxDecripSection) /* ETH_DMADescTypeDef Rx */
. = ALIGN(32);
}> SRAM2_NC
.TxDecripSection (NOLOAD) :
{
. = ALIGN(32);
*(.TxDecripSection) /* ETH_DMADescTypeDef Tx */
. = ALIGN(32);
}> SRAM2_NC
/* Rx/Tx buffers in 64KB non-cacheable window */
.ETH_NC_Buffers (NOLOAD) :
{
. = ALIGN(32);
*(.ETH_NC_Buffers) /* uint8_t Rx/Tx buffers */
. = ALIGN(32);
}> ETHBUFF_NC
/* --------- TouchGFX in SDRAM --------- */
BufferSection (NOLOAD) :
{
. = ALIGN(64);
*(TouchGFX_Framebuffer TouchGFX_Framebuffer.*)
. = ALIGN(64);
}> SDRAM
TouchGFX_ScratchbufferA (NOLOAD) :
{
. = ALIGN(64);
*(TouchGFX_ScratchbufferA TouchGFX_ScratchbufferA.*)
. = ALIGN(64);
}> SDRAM
TouchGFX_ScratchbufferB (NOLOAD) :
{
. = ALIGN(64);
*(TouchGFX_ScratchbufferB TouchGFX_ScratchbufferB.*)
. = ALIGN(64);
}> SDRAM
/* --------- External QSPI (RO assets) --------- */
ExtFlashSection :
{
. = ALIGN(4);
*(ExtFlashSection ExtFlashSection.*)
. = ALIGN(4);
}> QUADSPI
FontFlashSection :
{
. = ALIGN(4);
*(FontFlashSection FontFlashSection.*)
. = ALIGN(4);
}> QUADSPI
TextFlashSection :
{
. = ALIGN(4);
*(TextFlashSection TextFlashSection.*)
. = ALIGN(4);
}> QUADSPI
/* Discard unused standard libs */
/DISCARD/ :
{
libc.a(*)
libm.a(*)
libgcc.a(*)
}
.ARM.attributes 0 : {*(.ARM.attributes)}
}
Call MPU_Config() before enabling caches.
Then SCB_EnableICache(); SCB_EnableDCache();
linker matches:
.ETH_NC_Buffers at 0x20010000 (64 KB NC)
.RxDecripSection/.TxDecripSection at 0x2004C000 (16 KB NC)
General .data/.bss in AXI cacheable (0x20020000…)
Stack/heap in DTCM (0x20000000…)
/* Descriptors: 32-byte aligned in SRAM2_NC */
ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT] __attribute__((section(".RxDecripSection"), aligned(32)));
ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT] __attribute__((section(".TxDecripSection"), aligned(32)));
/* Rx/Tx buffers: 32-byte aligned in AXI non-cacheable window */
uint8_t ETH_Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUF_SIZE] __attribute__((section(".ETH_NC_Buffers"), aligned(32)));
uint8_t ETH_Tx_Buff[ETH_TX_DESC_CNT][ETH_TX_BUF_SIZE] __attribute__((section(".ETH_NC_Buffers"), aligned(32)));
please could someone guide me and correct my linker script and MPU configuration. I assume the DTCM and DMA are overlapping with the RAM memory and the buffer is not able to communicate with ARP from pc.
Looking forward for your inputs. Thank you.
@stm32f746 discovery board
2025-09-29 7:11 AM
Did you check Ethernet stack size and usage ? when you enable both, you need to increase cache size.
2025-09-29 7:59 AM - edited 2025-09-29 7:59 AM
Hi @mbarg.1
thank you so much for your response and supporting me. Yes, I have update few inputs in "lwipopts.h" file but i am currently not sure about the configuration. It would be really appreciated if there is any standard configuration for Lwip Ethernet that works with stm32f746NGHS discovery board. Pleae
/* USER CODE BEGIN 1 */
#define LWIP_TCP 1
#define LWIP_NETCONN 1
//#define LWIP_DHCP 1
#define LWIP_DNS 1 // handy for MQTT later
#define LWIP_NETIF_HOSTNAME 1
#define LWIP_MDNS_RESPONDER 1 // mDNS (.local)
#define LWIP_IGMP 1 // required for IPv4 multicast 224.0.0.251
#define LWIP_NETBIOSNS 1 // optional: Windows NetBIOS name
#define LWIP_NUM_NETIF_CLIENT_DATA 1 /* required by mDNS */
#define LWIP_SO_RCVTIMEO 1
#define LWIP_AUTOIP 0
#define LWIP_DHCP_AUTOIP_COOP 0
#define LWIP_MQTT 1
#define TCPIP_THREAD_STACKSIZE 3072
#define DEFAULT_THREAD_STACKSIZE 1536
#define MEM_SIZE 16*1024
#define PBUF_POOL_SIZE 16
#define PBUF_POOL_BUFSIZE 1536
#define LWIP_RAM_HEAP_POINTER 0x2004C140
/* USER CODE END 1 */
I am adding screenshots ioc information and manual changes in code for reference for better understanding.
I assume DMA Rx and Tx buffer and DTCM non sharable and non cacheable are causing problem.
Stm32f746 host device updated NET link up but when i tried to ping on laptop I get host unreachable. this is due to DMA bufferes are not recognized or dont have memory is not handled properly.
Any further suggestions would be really appreciated.