iMXRT1024 - Ethernet MAC not transmitting data

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

iMXRT1024 - Ethernet MAC not transmitting data

Jump to solution
3,451 Views
GUnderdown
Contributor IV

I have an RT1024 on a custom board, but the hardware regarding the ethernet and memory is the same. Phy ksz8081, dram IS42S16160-6 at 125MHz. My issue is that for some reason, I never see any data coming out of the MAC over the RMII interface, and as a result, no data is ever transmitted to the network. I receive zero errors regarding this, and the phy registers/configuration matches the SDK example for the given connection (10Mbps half duplex vs 100Mbps full duplex, etc). I am confident that the phy is able to establish a link with the other side of the network, indicated by lights on both ends, and the fact that the link waiting period goes by and passes (see code below). 

Physically, I have verified that there is no data on the TX lines of the RMII, and that the RMII clock output from the CPU is a clean 50MHz (both verified with scope). I have defined "FSL_FEATURE_PHYKSZ8081_USE_RMII50M_MODE", and like I said earlier, the phy registers match what I would expect.

 

I've also verified that it is not a hardware problem. If I modify the lwip_ping_freertos sdk example to link to RAM (DRAM), it runs perfectly. I have compared the register stacks for the ENET module between my code and the SDK example, and the only differences were the TDAR, MII data register, MIB (which I set to enable the counters), RDSR, and TDSR.

 

My memory map is setup like this:

  • Code/data: SDRAM loaded/copied by uTasker bootloader
  • Stack/Heap: DTCM, which has been resized to take the full 256k on the CPU. Heap size is 64k, stack is only 4k but the rtos task stack is derived from the heap so it's ok.
  • Cache is disabled globally in main(), right after the MPU configuration. I have also tried this with the driver cache control enable define, but there was no change.

 

 

class Hardware {
    ........
public:
	/**
	 * Phy resource object for the phy.
	 * Must be public so that the LWIP task can get it
	 */
	phy_ksz8081_resource_t g_phy_resource;

	/**
	 * Phy Handle
	 */
	phy_handle_t phyHandle;


	netif lwip_netif;
}

 

extern const phy_operations_t phyksz8081_ops;
static void lwIP_init(void *arg) {

	Hardware * hw = (Hardware *)arg;

	hw->g_phy_resource.write = MDIO_Write;
	hw->g_phy_resource.read = MDIO_Read;



	// Enable the 50MHz RMII Clock derived from ENET PLL
    IOMUXC_EnableMode(IOMUXC_GPR, kIOMUXC_GPR_ENET1TxClkOutputDir, true);

	ethernetif_config_t lwIP_netif0_enet_config = {
			.phyHandle = 	&hw->phyHandle,
			.phyAddr = 		BECK_PHYKSZ8081_ADDRESS,
			.phyOps = 		&phyksz8081_ops,
			.phyResource =	&hw->g_phy_resource,
			.srcClockHz =	125000000UL,
	};
	// gotta memcpy in the MAC address
	// though we could just directly bit bang the registers later
	memcpy(&lwIP_netif0_enet_config.macAddress, hw->GetMACAddr(), 6);


	uint8_t * ip_addr = hw->GetIPAddr();
	uint8_t * ip_netmask = hw->GetSubnetMask();
	uint8_t * ip_gateway = hw->GetGateway();

	/* lwIP IP address initialization */
	IP4_ADDR(&lwIP_netif0_ipaddr, ip_addr[0], ip_addr[1],
			ip_addr[2], ip_addr[3]);
	/* lwIP netmask initialization */
	IP4_ADDR(&lwIP_netif0_netmask, ip_netmask[0], ip_netmask[1],
			ip_netmask[2], ip_netmask[3]);
	/* lwIP gateway initialization */
	IP4_ADDR(&lwIP_netif0_gw, ip_gateway[0], ip_gateway[1], ip_gateway[2],
			ip_gateway[3]);
	/* lwIP module initialization */
	tcpip_init(tcpip_init_done, NULL);
	/* ENET peripheral initialization */
	/* ENET clock enable */
    (void)CLOCK_EnableClock(s_enetClock[ENET_GetInstance(ENET)]);
	/* ENET set SMI (serial management interface) */
	ENET_SetSMI(ENET, CLOCK_GetFreq(kCLOCK_IpgClk), false);



	/* lwIP network interface initialization */
	netifapi_netif_add(&hw->lwip_netif, &lwIP_netif0_ipaddr, &lwIP_netif0_netmask,
			&lwIP_netif0_gw, &lwIP_netif0_enet_config, ethernetif0_init,
			tcpip_input);
	netifapi_netif_set_default(&hw->lwip_netif);
	netifapi_netif_set_up(&hw->lwip_netif);

#if (BECK_BOARD_REVISION_MAJOR == 1U)	// Board Revision A
#warning Forcing Ethernet Phy RMII Mode (BA5533A)
	// Strapping options are f'd up
	// Force RMII mode override
	MDIO_Write(1, 0x16, 2);
#endif

#ifdef DEBUG
	xTaskCreate(get_phyregs, "Phy Debug", 128, NULL,0, NULL);
    // enable the ethenet statistics counters
    ENET->MIBC &= 0x7FFF;	// set b31 0
#endif
	/* lwIP interface auto-negotiation check */
	while (ethernetif_wait_linkup(&hw->lwip_netif, 5000UL) != ERR_OK) {
		PRINTF(
				"PHY Auto-negotiation failed. Please check the cable connection and link partner setting.\r\n");
	}
	// link status is now UP
	// print debug stuff
    PRINTF("\r\n************************************************\r\n");
    PRINTF(" BA-5533 Network Configuration\r\n");
    PRINTF("************************************************\r\n");
    PRINTF(" IPv4 Address     : %u.%u.%u.%u\r\n", ((u8_t *)&lwIP_netif0_ipaddr)[0], ((u8_t *)&lwIP_netif0_ipaddr)[1],
           ((u8_t *)&lwIP_netif0_ipaddr)[2], ((u8_t *)&lwIP_netif0_ipaddr)[3]);
    PRINTF(" IPv4 Subnet mask : %u.%u.%u.%u\r\n", ((u8_t *)&lwIP_netif0_netmask)[0], ((u8_t *)&lwIP_netif0_netmask)[1],
           ((u8_t *)&lwIP_netif0_netmask)[2], ((u8_t *)&lwIP_netif0_netmask)[3]);
    PRINTF(" IPv4 Gateway     : %u.%u.%u.%u\r\n", ((u8_t *)&lwIP_netif0_gw)[0], ((u8_t *)&lwIP_netif0_gw)[1],
           ((u8_t *)&lwIP_netif0_gw)[2], ((u8_t *)&lwIP_netif0_gw)[3]);
    /*PRINTF(" MAC Address      : %02X:%02X:%02X:%02X:%02X:%02X\r\n", (u8_t *)(&hw->lwip_netif.hwaddr[0]), &hw->lwip_netif.hwaddr[1],
    		&hw->lwip_netif.hwaddr[2], &hw->lwip_netif.hwaddr[3], &hw->lwip_netif.hwaddr[4], &hw->lwip_netif.hwaddr[5]);
    		*/
    PRINTF("************************************************\r\n");

    ping_init(&lwIP_netif0_gw);

    // because tasks must not return, call task delete
	vTaskDelete(NULL);
}

 

the stack size for the init task is 512, but I don't think it really needs all that much. The TCPIP thread spawns just fine, as well as the LWIP RX thread.

 

Any help or insight is appreciated.

Labels (1)
0 Kudos
Reply
1 Solution
2,798 Views
GUnderdown
Contributor IV

@nxf77486I have solved most of the issues (at least related to this topic).

 

In summary:

 

The MAC not working at all seemed to be caused by my use of NewLibNano. How the libc implementation breaks the MAC is beyond me, but that was the change I made and it started working.

 

Then once the MAC worked, the receiving did not work. This was due to USE_RTOS not being defined.

 

@nxf77486is there a list of all the #defines used in the SDK, and what they control?

 

I am going to close this issue now.

View solution in original post

0 Kudos
Reply
22 Replies
2,799 Views
GUnderdown
Contributor IV

@nxf77486I have solved most of the issues (at least related to this topic).

 

In summary:

 

The MAC not working at all seemed to be caused by my use of NewLibNano. How the libc implementation breaks the MAC is beyond me, but that was the change I made and it started working.

 

Then once the MAC worked, the receiving did not work. This was due to USE_RTOS not being defined.

 

@nxf77486is there a list of all the #defines used in the SDK, and what they control?

 

I am going to close this issue now.

0 Kudos
Reply
2,966 Views
GUnderdown
Contributor IV

@nxf77486Have you had any luck reproducing my issue?

0 Kudos
Reply
3,091 Views
nxf77486
NXP TechSupport
NXP TechSupport

Hello,

 

Its possible to use this by managing the linker script with the MCUXpresso? Just to make sure there could not be any troubles with it. Also if it is possible can we reduce the Task Init value to the minimum possible.

0 Kudos
Reply
3,060 Views
GUnderdown
Contributor IV

I neglected to provide the code in my previous response. It is attached below.

/**
 * Ethernet test header (++) file
 * 10-26-23
 * gavund
 */

#ifndef ETHERNET_HPP
#define ETHERNET_HPP

#include "fsl_gpio.h"
#include "fsl_iomuxc.h"
// This gives us defines for a bunch of stuff
#include "pin_mux.h"
#include "peripherals.h"
#include "fsl_debug_console.h"

#include "lwip/opt.h"
#include "lwip/tcpip.h"
#include "lwip/netifapi.h"
#include "lwip/sys.h"
#include "lwip/sockets.h"
#include "lwip/api.h"
#include "lwip/icmp.h"
#include "lwip/errno.h"
#include "ethernetif.h"
#include "fsl_enet.h"
#include "fsl_phyksz8081.h"


#include "ping.h"	// lwip/contrib/apps/ping/ping.h



/**
 * \brief Write to the management interface for the phy.
 *
 * This is a wrapper so that LWIP and the SDK play nicely.
 *
 * \param phyAddr Phy address. Should basically always be 0x01
 * \param regAddr Register address of the phy (see datasheet)
 * \param data 16bit data to write to that register
 * \return Operation status
 */
inline status_t MDIO_Write(uint8_t phyAddr, uint8_t regAddr, uint16_t data)
{
    return ENET_MDIOWrite(ENET, phyAddr, regAddr, data);
}

/**
 * \brief Read to the management interface for the phy.
 *
 * This is a wrapper so that LWIP and the SDK play nicely.
 *
 * \param phyAddr Phy address. Should be 0x01
 * \param regAddr Register address of the phy (see datasheet)
 * \param pData 16bit pointer with read data
 * \return Operation status
 */
inline status_t MDIO_Read(uint8_t phyAddr, uint8_t regAddr, uint16_t *pData)
{
    return ENET_MDIORead(ENET, phyAddr, regAddr, pData);
}


#ifdef DEBUG
/**
 * \brief Task to read phy registers
 *
 * \param args
 */
static void get_phyregs(void* args) {
	uint16_t * phy_regs = new uint16_t[32];
	TickType_t TicksToWait = pdMS_TO_TICKS(1000);
/*	uint32_t cpu_clk = CLOCK_GetCpuClkFreq();
	uint32_t enet_pll = CLOCK_GetFreq(kCLOCK_EnetPllClk);
	uint32_t enet_25m 	= CLOCK_GetFreq(kCLOCK_EnetPll25MClk);
	uint32_t enet_500m	= CLOCK_GetFreq(kCLOCK_EnetPll500MClk);*/
	// also enable the MIBC counters here
	// clear b31
	ENET->MIBC &= 0x7FFF;
	while (true) {
	    for (int i = 0; i <= 31; i++) {
	    	MDIO_Read(1, i, &phy_regs[i]);
	    }


		vTaskDelay(TicksToWait);
	}
}
#endif


void tcpip_init_done(void *){
	PRINTF("TCPIP THREAD INIT DONE\r\n");
}


/* Network interface structure */
static struct netif lwIP_netif0;
/* PHY handle */
static phy_handle_t lwIP_netif0_phy_handle;

static phy_ksz8081_resource_t lwIP_netif0_phy_resource = {
  .write = MDIO_Write,
  .read = MDIO_Read
};


extern const phy_operations_t phyksz8081_ops;
static void lwIP_init(void *arg) {



//	hw->g_phy_resource.write = MDIO_Write;
//	hw->g_phy_resource.read = MDIO_Read;

	// these are just temp i believe
	ip4_addr_t lwIP_netif0_ipaddr, lwIP_netif0_netmask, lwIP_netif0_gw;


	/* ENET peripheral initialization */
	/* ENET clock enable */
    (void)CLOCK_EnableClock(s_enetClock[ENET_GetInstance(ENET)]);
	/* ENET set SMI (serial management interface) */
	ENET_SetSMI(ENET, CLOCK_GetFreq(kCLOCK_IpgClk), false);


	// Enable the 50MHz RMII Clock derived from ENET PLL
    IOMUXC_EnableMode(IOMUXC_GPR, kIOMUXC_GPR_ENET1TxClkOutputDir, true);

	ethernetif_config_t lwIP_netif0_enet_config = {
			.phyHandle = 	&lwIP_netif0_phy_handle,
			.phyAddr = 		1,
			.phyOps = 		&phyksz8081_ops,
			.phyResource =	&lwIP_netif0_phy_resource,
			.srcClockHz =	CLOCK_GetFreq(kCLOCK_IpgClk),
	};
	// gotta memcpy in the MAC address
	// though we could just directly bit bang the registers later


	uint8_t ip_addr[] = {192, 186, 68,42};

	uint8_t ip_netmask[] = {255, 255,255,255};

	uint8_t ip_gateway[] = {192,168,0,1};

	uint8_t mac[] = {0xBA, 0x55,0x33, 0x00, 0x00, 0x06};
	memcpy(&lwIP_netif0_enet_config.macAddress,mac, 6);

	/* lwIP IP address initialization */
	IP4_ADDR(&lwIP_netif0_ipaddr, ip_addr[0], ip_addr[1],
			ip_addr[2], ip_addr[3]);
	/* lwIP netmask initialization */
	IP4_ADDR(&lwIP_netif0_netmask, ip_netmask[0], ip_netmask[1],
			ip_netmask[2], ip_netmask[3]);
	/* lwIP gateway initialization */
	IP4_ADDR(&lwIP_netif0_gw, ip_gateway[0], ip_gateway[1], ip_gateway[2],
			ip_gateway[3]);
	/* lwIP module initialization */
	tcpip_init(NULL, NULL);




	/* lwIP network interface initialization */
	netifapi_netif_add(&lwIP_netif0, &lwIP_netif0_ipaddr, &lwIP_netif0_netmask,
			&lwIP_netif0_gw, &lwIP_netif0_enet_config, ethernetif0_init,
			tcpip_input);


	netifapi_netif_set_default(&lwIP_netif0);
	netifapi_netif_set_up(&lwIP_netif0);


	// Strapping options are f'd up
	// Force RMII mode override
	MDIO_Write(1, 0x16, 2);
	uint16_t phyreg1f = 0;
	MDIO_Read(1, 0x1f, &phyreg1f);
	phyreg1f |= (1 << 7);	// set bit 7
	MDIO_Write(1,0x1f, phyreg1f);

#ifdef DEBUG
	xTaskCreate(get_phyregs, "Phy Debug", 128, NULL,0, NULL);
    // enable the ethenet statistics counters
    ENET->MIBC &= 0x7FFF;	// set b31 0
#endif
	/* lwIP interface auto-negotiation check */
	while (ethernetif_wait_linkup(&lwIP_netif0, 5000UL) != ERR_OK) {
		PRINTF(
				"PHY Auto-negotiation failed. Please check the cable connection and link partner setting.\r\n");
	}
	// link status is now UP
	// print debug stuff
    PRINTF("\r\n************************************************\r\n");
    PRINTF(" BA-5533 Network Configuration\r\n");
    PRINTF("************************************************\r\n");
    PRINTF(" IPv4 Address     : %u.%u.%u.%u\r\n", ((u8_t *)&lwIP_netif0_ipaddr)[0], ((u8_t *)&lwIP_netif0_ipaddr)[1],
           ((u8_t *)&lwIP_netif0_ipaddr)[2], ((u8_t *)&lwIP_netif0_ipaddr)[3]);
    PRINTF(" IPv4 Subnet mask : %u.%u.%u.%u\r\n", ((u8_t *)&lwIP_netif0_netmask)[0], ((u8_t *)&lwIP_netif0_netmask)[1],
           ((u8_t *)&lwIP_netif0_netmask)[2], ((u8_t *)&lwIP_netif0_netmask)[3]);
    PRINTF(" IPv4 Gateway     : %u.%u.%u.%u\r\n", ((u8_t *)&lwIP_netif0_gw)[0], ((u8_t *)&lwIP_netif0_gw)[1],
           ((u8_t *)&lwIP_netif0_gw)[2], ((u8_t *)&lwIP_netif0_gw)[3]);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
    PRINTF(" MAC Address      : %02X:%02X:%02X:%02X:%02X:%02X\r\n",
    		(u8_t *)(lwIP_netif0.hwaddr[0]),
    		(u8_t *)(lwIP_netif0.hwaddr[1]),
    		(u8_t *)(lwIP_netif0.hwaddr[2]),
			(u8_t *)(lwIP_netif0.hwaddr[3]),
			(u8_t *)(lwIP_netif0.hwaddr[4]),
			(u8_t *)(lwIP_netif0.hwaddr[5]));
#pragma GCC diagnostic pop

    PRINTF("************************************************\r\n");

    ping_init(&lwIP_netif0_gw);

    // because tasks must not return, call task delete
	vTaskDelete(NULL);
}


#endif
0 Kudos
Reply
3,064 Views
GUnderdown
Contributor IV

I created a new project, imported the memory map and .mex file from the previous one. I then took the same code (which I will include below again) and tested it with a managed linker script.

 

FreeRTOS task view

GUnderdown_0-1701100906820.png

Managed linker script settings

GUnderdown_1-1701100942546.png

Preprocessor defines

GUnderdown_2-1701101058609.png

 

 

Same issue happens, link goes up, but no data is transmitted

0 Kudos
Reply
3,193 Views
nxf77486
NXP TechSupport
NXP TechSupport

Hello,

Thank you in advance for contacting NXP support.

Regarding your case I appreciate the SDK example testing to confirm that this is not a HW related issue. Can you please help me with the FreeRTOS Heap Stack view. Just to make double check that al task are working properly and non of them are starving causing this trouble. This view can be open on the toolbar in MCUXpresso on RTOS section.

Please help me with this information in order to find a solution to your case.

0 Kudos
Reply
3,178 Views
GUnderdown
Contributor IV

GUnderdown_0-1699368188856.png

GUnderdown_3-1699368243327.pngGUnderdown_4-1699368491446.png

I don't think it has to do with running out of memory, as I have also tried this with insane heap sizes on the external SDRAM (which is identical to the IMXRT1024-EVK in terms of hardware. I placed the heap in the 2nd 4MB from the bottom [Code runs from the first 4MB]).

 

 

0 Kudos
Reply
3,161 Views
nxf77486
NXP TechSupport
NXP TechSupport

 

Hello,

 

I appreciate the information, can you please help me by reviewing if there is any data being transmitted with an oscilloscope signal to see the behavior of this, also if it is possible can you tested this with the default memory map as it is on the SDK example.

0 Kudos
Reply
3,142 Views
GUnderdown
Contributor IV

I have verified that there is no data being transmitted on the RMII TXD[0..1] lines, verified with scope. RMII TXCLK = 50MHz sine wave.

 

 

Unfortunately, I cannot use the default memory maps because our code base is too large to fit code + stack + heap into the 256kB of RAM on the chip.

MEMORY
{
  /* Define each memory region */
  PROGRAM_FLASH (rx)  : ORIGIN = 0x60020400,  LENGTH = 0x3dec00 /* 3963K bytes (alias Flash) */  
  BOARD_INFO_1 (rx)   : ORIGIN = 0x603ff000,  LENGTH = 0x800    /* 2K bytes (alias Flash2) */  
  BOARD_INFO_2 (rx)   : ORIGIN = 0x603ff800,  LENGTH = 0x800    /* 2K bytes (alias Flash3) */  
  SRAM_DTC (rwx)      : ORIGIN = 0x20000000,  LENGTH = 0x40000  /* 256K bytes (alias RAM) */  
  SRAM_ITC (rwx)      : ORIGIN = 0x0,         LENGTH = 0x0      /* 0M bytes (alias RAM2) */  
  SRAM_OC (rwx)       : ORIGIN = 0x20200000,  LENGTH = 0x0      /* 0M bytes (alias RAM3) */  
  SDRAM_B0_CODE (rwx) : ORIGIN = 0x80000000,  LENGTH = 0x400000 /* 4M bytes (alias RAM4) */  
  SDRAM_B0_HEAP (rwx) : ORIGIN = 0x80400000,  LENGTH = 0x400000 /* 4M bytes (alias RAM5) */  
  SDRAM_B1 (rwx)      : ORIGIN = 0x80800000,  LENGTH = 0x800000 /* 8M bytes (alias RAM6) */  
  SDRAM_B2 (rwx)      : ORIGIN = 0x81000000,  LENGTH = 0x800000 /* 8M bytes (alias RAM7) */  
  SDRAM_B3 (rwx)      : ORIGIN = 0x81800000,  LENGTH = 0x800000 /* 8M bytes (alias RAM8) */  
}

Above is the definition of the memory map, note that the flash beings with an offset to hold our boot loader (the uTasker project by @mjbcswitzerland), I've talked with the developer of the bootloader and he is of the opinion that the bootloader is not causing the issue.

0 Kudos
Reply
3,110 Views
nxf77486
NXP TechSupport
NXP TechSupport

Hello,

It seems everything to be fine can you please help me by checking the following information.

I understand that your application is located on the SDRAM can you please help me by checking the link application to RAM box.

Also to enable the SDRAM, it is necessary to add the XIP_BOOT_HEADER_DCD_ENABLE=1 in the following location C/C++ Build > Settings > Preprocessor, then the ROM code will fetch the DCD to initialize the SDRAM during the boot-up process.

nxf77486_0-1700601865912.png

 

0 Kudos
Reply
3,103 Views
GUnderdown
Contributor IV

Code is loaded by the bootloader, which has it's own DCD. The SDRAM appears to function normally, and the linker script is not managed by MCUXpresso. I have attached the linker scripts below, but they should be set to plain load to SDRAM_B0_CODE (first 4MB of SDRAM).

 

xxx_Memory.ld

/*
  This was once auto generated 
  but no longer is 
  feel free to modify but do not break it!
 */

MEMORY
{
  /* Define each memory region */
  PROGRAM_FLASH (rx)  : ORIGIN = 0x60020400,  LENGTH = 0x3dec00 /* 3963K bytes (alias Flash) */  
  BOARD_INFO_1 (rx)   : ORIGIN = 0x603ff000,  LENGTH = 0x800    /* 2K bytes (alias Flash2) */  
  BOARD_INFO_2 (rx)   : ORIGIN = 0x603ff800,  LENGTH = 0x800    /* 2K bytes (alias Flash3) */  
  SRAM_DTC (rwx)      : ORIGIN = 0x20000000,  LENGTH = 0x40000  /* 256K bytes (alias RAM) */  
  SRAM_ITC (rwx)      : ORIGIN = 0x0,         LENGTH = 0x0      /* 0M bytes (alias RAM2) */  
  SRAM_OC (rwx)       : ORIGIN = 0x20200000,  LENGTH = 0x0      /* 0M bytes (alias RAM3) */  
  SDRAM_B0_CODE (rwx) : ORIGIN = 0x80000000,  LENGTH = 0x400000 /* 4M bytes (alias RAM4) */  
  SDRAM_B0_HEAP (rwx) : ORIGIN = 0x80400000,  LENGTH = 0x400000 /* 4M bytes (alias RAM5) */  
  SDRAM_B1 (rwx)      : ORIGIN = 0x80800000,  LENGTH = 0x800000 /* 8M bytes (alias RAM6) */  
  SDRAM_B2 (rwx)      : ORIGIN = 0x81000000,  LENGTH = 0x800000 /* 8M bytes (alias RAM7) */  
  SDRAM_B3 (rwx)      : ORIGIN = 0x81800000,  LENGTH = 0x800000 /* 8M bytes (alias RAM8) */  
}

  /* Define a symbol for the top of each memory region */
  PROVIDE(__base_FLASH_CHIP = 0x60000000);
  PROVIDE(__top_FLASH_CHIP = 0x603ff800 + 0x800); 
  __base_PROGRAM_FLASH = 0x60020400  ; /* PROGRAM_FLASH */  
  __base_Flash = 0x60020400 ; /* Flash */  
  __top_PROGRAM_FLASH = 0x60020400 + 0x3dec00 ; /* 3963K bytes */  
  __top_Flash = 0x60020400 + 0x3dec00 ; /* 3963K bytes */  
  __base_BOARD_INFO_1 = 0x603ff000  ; /* BOARD_INFO_1 */  
  __base_Flash2 = 0x603ff000 ; /* Flash2 */  
  __top_BOARD_INFO_1 = 0x603ff000 + 0x800 ; /* 2K bytes */  
  __top_Flash2 = 0x603ff000 + 0x800 ; /* 2K bytes */  
  __base_BOARD_INFO_2 = 0x603ff800  ; /* BOARD_INFO_2 */  
  __base_Flash3 = 0x603ff800 ; /* Flash3 */  
  __top_BOARD_INFO_2 = 0x603ff800 + 0x800 ; /* 2K bytes */  
  __top_Flash3 = 0x603ff800 + 0x800 ; /* 2K bytes */  
  __base_SRAM_DTC = 0x20000300  ; /* SRAM_DTC */  
  __base_RAM = 0x20000300 ; /* RAM */  
  __top_SRAM_DTC = 0x20000300 + 0x3fd00 ; /* 261376 bytes */  
  __top_RAM = 0x20000300 + 0x3fd00 ; /* 261376 bytes */  
  __base_SRAM_ITC = 0x0  ; /* SRAM_ITC */  
  __base_RAM2 = 0x0 ; /* RAM2 */  
  __top_SRAM_ITC = 0x0 + 0x0 ; /* 0M bytes */  
  __top_RAM2 = 0x0 + 0x0 ; /* 0M bytes */  
  __base_SRAM_OC = 0x20200000  ; /* SRAM_OC */  
  __base_RAM3 = 0x20200000 ; /* RAM3 */  
  __top_SRAM_OC = 0x20200000 + 0x0 ; /* 0M bytes */  
  __top_RAM3 = 0x20200000 + 0x0 ; /* 0M bytes */  
  __base_SDRAM_B0_CODE = 0x80000000  ; /* SDRAM_B0_CODE */  
  __base_RAM4 = 0x80000000 ; /* RAM4 */  
  __top_SDRAM_B0_CODE = 0x80000000 + 0x400000 ; /* 4M bytes */  
  __top_RAM4 = 0x80000000 + 0x400000 ; /* 4M bytes */  
  __base_SDRAM_B0_HEAP = 0x80400000  ; /* SDRAM_B0_HEAP */  
  __base_RAM5 = 0x80400000 ; /* RAM5 */  
  __top_SDRAM_B0_HEAP = 0x80400000 + 0x400000 ; /* 4M bytes */  
  __top_RAM5 = 0x80400000 + 0x400000 ; /* 4M bytes */  
  __base_SDRAM_B1 = 0x80800000  ; /* SDRAM_B1 */  
  __base_RAM6 = 0x80800000 ; /* RAM6 */  
  __top_SDRAM_B1 = 0x80800000 + 0x800000 ; /* 8M bytes */  
  __top_RAM6 = 0x80800000 + 0x800000 ; /* 8M bytes */  
  __base_SDRAM_B2 = 0x81000000  ; /* SDRAM_B2 */  
  __base_RAM7 = 0x81000000 ; /* RAM7 */  
  __top_SDRAM_B2 = 0x81000000 + 0x800000 ; /* 8M bytes */  
  __top_RAM7 = 0x81000000 + 0x800000 ; /* 8M bytes */  
  __base_SDRAM_B3 = 0x81800000  ; /* SDRAM_B3 */  
  __base_RAM8 = 0x81800000 ; /* RAM8 */  
  __top_SDRAM_B3 = 0x81800000 + 0x800000 ; /* 8M bytes */  
  __top_RAM8 = 0x81800000 + 0x800000 ; /* 8M bytes */  

 

 

Library.ld (I haven't modified this from MCUxpresso)

/*
 * GENERATED FILE - DO NOT EDIT
 * Copyright 2008-2013 Code Red Technologies Ltd,
 * Copyright 2013-2023 NXP
 * Generated linker script file for MIMXRT1024xxxxx
 * Created from library.ldt by FMCreateLinkLibraries
 * Using Freemarker v2.3.30
 * MCUXpresso IDE v11.8.0 [Build 1165] [2023-07-26] on Nov 7, 2023, 8:18:38 AM
 */

GROUP (
  "libgcc.a"
  "libc_nano.a"
  "libstdc++_nano.a"
  "libm.a"
  "libcr_newlib_semihost.a"
  "crti.o"
  "crtn.o"
  "crtbegin.o"
  "crtend.o"
)

 

Main Linker script

/*
 * This file was once auto-generated but no longer is 
 * Feel free to modify but do not break it!!!
 *
*/

INCLUDE "BA-5533-Software_Debug_library.ld"
INCLUDE "BA-5533-Software_Debug_memory.ld"

ENTRY(ResetISR)

SECTIONS
{

    .text_Flash2 : ALIGN(4)
    {
       FILL(0xff)
       /* Software Information placement symbol */
       __board_sw_info = ABSOLUTE(.);
       . += 256;
    } > BOARD_INFO_1

    .text_Flash3 : ALIGN(4)
    {
       FILL(0xff)
       /* Board ethernet info placement symbol */
       __board_eth_info = ABSOLUTE(.);
       /* pad 256 */
       . += 256; 
       /* Board hardware info placement symbol */
       __board_hw_info = ABSOLUTE(.);  
       . += 256;     

   } > BOARD_INFO_2

    /* MAIN TEXT SECTION */
    .text : ALIGN(4)
    {
        FILL(0xff)
        __vectors_start__ = ABSOLUTE(.) ;
        KEEP(*(.isr_vector))
        /* Global Section Table */
        . = ALIGN(4) ;
        __section_table_start = .;
        __data_section_table = .;
        LONG((LOADADDR(.data) - LOADADDR(.text)) + __base_SDRAM_B0_CODE);
        LONG(    ADDR(.data));
        LONG(  SIZEOF(.data));
        LONG((LOADADDR(.data_RAM2) - LOADADDR(.text)) + __base_SDRAM_B0_CODE);
        LONG(    ADDR(.data_RAM2));
        LONG(  SIZEOF(.data_RAM2));
        LONG((LOADADDR(.data_RAM3) - LOADADDR(.text)) + __base_SDRAM_B0_CODE);
        LONG(    ADDR(.data_RAM3));
        LONG(  SIZEOF(.data_RAM3));
        LONG((LOADADDR(.data_RAM4) - LOADADDR(.text)) + __base_SDRAM_B0_CODE);
        LONG(    ADDR(.data_RAM4));
        LONG(  SIZEOF(.data_RAM4));
        LONG((LOADADDR(.data_RAM5) - LOADADDR(.text)) + __base_SDRAM_B0_CODE);
        LONG(    ADDR(.data_RAM5));
        LONG(  SIZEOF(.data_RAM5));
        LONG((LOADADDR(.data_RAM6) - LOADADDR(.text)) + __base_SDRAM_B0_CODE);
        LONG(    ADDR(.data_RAM6));
        LONG(  SIZEOF(.data_RAM6));
        LONG((LOADADDR(.data_RAM7) - LOADADDR(.text)) + __base_SDRAM_B0_CODE);
        LONG(    ADDR(.data_RAM7));
        LONG(  SIZEOF(.data_RAM7));
        LONG((LOADADDR(.data_RAM8) - LOADADDR(.text)) + __base_SDRAM_B0_CODE);
        LONG(    ADDR(.data_RAM8));
        LONG(  SIZEOF(.data_RAM8));
        __data_section_table_end = .;
        __bss_section_table = .;
        LONG(    ADDR(.bss));
        LONG(  SIZEOF(.bss));
        LONG(    ADDR(.bss_RAM2));
        LONG(  SIZEOF(.bss_RAM2));
        LONG(    ADDR(.bss_RAM3));
        LONG(  SIZEOF(.bss_RAM3));
        LONG(    ADDR(.bss_RAM4));
        LONG(  SIZEOF(.bss_RAM4));
        LONG(    ADDR(.bss_RAM5));
        LONG(  SIZEOF(.bss_RAM5));
        LONG(    ADDR(.bss_RAM6));
        LONG(  SIZEOF(.bss_RAM6));
        LONG(    ADDR(.bss_RAM7));
        LONG(  SIZEOF(.bss_RAM7));
        LONG(    ADDR(.bss_RAM8));
        LONG(  SIZEOF(.bss_RAM8));
        __bss_section_table_end = .;
        __section_table_end = . ;
        /* End of Global Section Table */

        *(.after_vectors*)

       *(.text*)
       KEEP(*freertos*/tasks.o(.rodata*)) /* FreeRTOS Debug Config */
       *(.rodata .rodata.* .constdata .constdata.*)
       . = ALIGN(4);
            /* C++ constructors etc */
            . = ALIGN(4);
            KEEP(*(.init))
            
            . = ALIGN(4);
            __preinit_array_start = .;
            KEEP (*(.preinit_array))
            __preinit_array_end = .;
            
            . = ALIGN(4);
            __init_array_start = .;
            KEEP (*(SORT(.init_array.*)))
            KEEP (*(.init_array))
            __init_array_end = .;
            
            KEEP(*(.fini));
            
            . = ALIGN(4);
            KEEP (*crtbegin.o(.ctors))
            KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
            KEEP (*(SORT(.ctors.*)))
            KEEP (*crtend.o(.ctors))
            
            . = ALIGN(4);
            KEEP (*crtbegin.o(.dtors))
            KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
            KEEP (*(SORT(.dtors.*)))
            KEEP (*crtend.o(.dtors))
            . = ALIGN(4);
            /* End C++ */
    } > SDRAM_B0_CODE AT> PROGRAM_FLASH
    /*
     * for exception handling/unwind - some Newlib functions (in common
     * with C++ and STDC++) use this.
     */
    .ARM.extab : ALIGN(4)
    {
        *(.ARM.extab* .gnu.linkonce.armextab.*)
    } > SDRAM_B0_CODE AT> PROGRAM_FLASH

    .ARM.exidx : ALIGN(4)
    {
        __exidx_start = .;
        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
        __exidx_end = .;
    } > SDRAM_B0_CODE AT> PROGRAM_FLASH
 
    _etext = .;
        

    /* Reserve and place Heap within memory map */
    _HeapSize = 0x10000;
    .heap (NOLOAD) :  ALIGN(4)
    {
        _pvHeapStart = .;
        . += _HeapSize;
        . = ALIGN(4); 
        _pvHeapLimit = .;
    } > SRAM_DTC
    /* DATA section for SRAM_ITC */

    .data_RAM2 : ALIGN(4)
    {
        FILL(0xff)
        PROVIDE(__start_data_RAM2 = .) ;
        PROVIDE(__start_data_SRAM_ITC = .) ;
        *(.ramfunc.$RAM2)
        *(.ramfunc.$SRAM_ITC)
        *(.data.$RAM2)
        *(.data.$SRAM_ITC)
        *(.data.$RAM2.*)
        *(.data.$SRAM_ITC.*)
        . = ALIGN(4) ;
        PROVIDE(__end_data_RAM2 = .) ;
        PROVIDE(__end_data_SRAM_ITC = .) ;
     } > SRAM_ITC AT>PROGRAM_FLASH

    /* DATA section for SRAM_OC */

    .data_RAM3 : ALIGN(4)
    {
        FILL(0xff)
        PROVIDE(__start_data_RAM3 = .) ;
        PROVIDE(__start_data_SRAM_OC = .) ;
        *(.ramfunc.$RAM3)
        *(.ramfunc.$SRAM_OC)
        *(.data.$RAM3)
        *(.data.$SRAM_OC)
        *(.data.$RAM3.*)
        *(.data.$SRAM_OC.*)
        . = ALIGN(4) ;
        PROVIDE(__end_data_RAM3 = .) ;
        PROVIDE(__end_data_SRAM_OC = .) ;
     } > SRAM_OC AT>PROGRAM_FLASH

    /* DATA section for SDRAM_B0_CODE */

    .data_RAM4 : ALIGN_WITH_INPUT
    {
        FILL(0xff)
        PROVIDE(__start_data_RAM4 = .) ;
        PROVIDE(__start_data_SDRAM_B0_CODE = .) ;
        *(.ramfunc.$RAM4)
        *(.ramfunc.$SDRAM_B0_CODE)
        *(.data.$RAM4)
        *(.data.$SDRAM_B0_CODE)
        *(.data.$RAM4.*)
        *(.data.$SDRAM_B0_CODE.*)
        . = ALIGN(4) ;
        PROVIDE(__end_data_RAM4 = .) ;
        PROVIDE(__end_data_SDRAM_B0_CODE = .) ;
     } > SDRAM_B0_CODE AT>PROGRAM_FLASH

    /* DATA section for SDRAM_B0_HEAP */

    .data_RAM5 : ALIGN(4)
    {
        FILL(0xff)
        PROVIDE(__start_data_RAM5 = .) ;
        PROVIDE(__start_data_SDRAM_B0_HEAP = .) ;
        *(.ramfunc.$RAM5)
        *(.ramfunc.$SDRAM_B0_HEAP)
        *(.data.$RAM5)
        *(.data.$SDRAM_B0_HEAP)
        *(.data.$RAM5.*)
        *(.data.$SDRAM_B0_HEAP.*)
        . = ALIGN(4) ;
        PROVIDE(__end_data_RAM5 = .) ;
        PROVIDE(__end_data_SDRAM_B0_HEAP = .) ;
     } > SDRAM_B0_HEAP AT>PROGRAM_FLASH

    /* DATA section for SDRAM_B1 */

    .data_RAM6 : ALIGN(4)
    {
        FILL(0xff)
        PROVIDE(__start_data_RAM6 = .) ;
        PROVIDE(__start_data_SDRAM_B1 = .) ;
        *(.ramfunc.$RAM6)
        *(.ramfunc.$SDRAM_B1)
        *(.data.$RAM6)
        *(.data.$SDRAM_B1)
        *(.data.$RAM6.*)
        *(.data.$SDRAM_B1.*)
        . = ALIGN(4) ;
        PROVIDE(__end_data_RAM6 = .) ;
        PROVIDE(__end_data_SDRAM_B1 = .) ;
     } > SDRAM_B1 AT>PROGRAM_FLASH

    /* DATA section for SDRAM_B2 */

    .data_RAM7 : ALIGN(4)
    {
        FILL(0xff)
        PROVIDE(__start_data_RAM7 = .) ;
        PROVIDE(__start_data_SDRAM_B2 = .) ;
        *(.ramfunc.$RAM7)
        *(.ramfunc.$SDRAM_B2)
        *(.data.$RAM7)
        *(.data.$SDRAM_B2)
        *(.data.$RAM7.*)
        *(.data.$SDRAM_B2.*)
        . = ALIGN(4) ;
        PROVIDE(__end_data_RAM7 = .) ;
        PROVIDE(__end_data_SDRAM_B2 = .) ;
     } > SDRAM_B2 AT>PROGRAM_FLASH

    /* DATA section for SDRAM_B3 */

    .data_RAM8 : ALIGN(4)
    {
        FILL(0xff)
        PROVIDE(__start_data_RAM8 = .) ;
        PROVIDE(__start_data_SDRAM_B3 = .) ;
        *(.ramfunc.$RAM8)
        *(.ramfunc.$SDRAM_B3)
        *(.data.$RAM8)
        *(.data.$SDRAM_B3)
        *(.data.$RAM8.*)
        *(.data.$SDRAM_B3.*)
        . = ALIGN(4) ;
        PROVIDE(__end_data_RAM8 = .) ;
        PROVIDE(__end_data_SDRAM_B3 = .) ;
     } > SDRAM_B3 AT>PROGRAM_FLASH

    /* MAIN DATA SECTION */
    .uninit_RESERVED (NOLOAD) : ALIGN(4)
    {
        _start_uninit_RESERVED = .;
        KEEP(*(.bss.$RESERVED*))
       . = ALIGN(4) ;
        _end_uninit_RESERVED = .;
    } > SRAM_DTC AT> SRAM_DTC

    /* Main DATA section (SRAM_DTC) */
    .data : ALIGN(4)
    {
       FILL(0xff)
       _data = . ;
       PROVIDE(__start_data_RAM = .) ;
       PROVIDE(__start_data_SRAM_DTC = .) ;
       *(vtable)
       *(.ramfunc*)
       KEEP(*(CodeQuickAccess))
       KEEP(*(DataQuickAccess))
       *(RamFunction)
       *(.data*)
       . = ALIGN(4) ;
       _edata = . ;
       PROVIDE(__end_data_RAM = .) ;
       PROVIDE(__end_data_SRAM_DTC = .) ;
    } > SRAM_DTC AT>PROGRAM_FLASH

    /* BSS section for SRAM_ITC */
    .bss_RAM2 (NOLOAD) : ALIGN(4)
    {
       PROVIDE(__start_bss_RAM2 = .) ;
       PROVIDE(__start_bss_SRAM_ITC = .) ;
       *(.bss.$RAM2)
       *(.bss.$SRAM_ITC)
       *(.bss.$RAM2.*)
       *(.bss.$SRAM_ITC.*)
       . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */
       PROVIDE(__end_bss_RAM2 = .) ;
       PROVIDE(__end_bss_SRAM_ITC = .) ;
    } > SRAM_ITC AT> SRAM_ITC

    /* BSS section for SRAM_OC */
    .bss_RAM3 (NOLOAD) : ALIGN(4)
    {
       PROVIDE(__start_bss_RAM3 = .) ;
       PROVIDE(__start_bss_SRAM_OC = .) ;
       *(.bss.$RAM3)
       *(.bss.$SRAM_OC)
       *(.bss.$RAM3.*)
       *(.bss.$SRAM_OC.*)
       . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */
       PROVIDE(__end_bss_RAM3 = .) ;
       PROVIDE(__end_bss_SRAM_OC = .) ;
    } > SRAM_OC AT> SRAM_OC

    /* BSS section for SDRAM_B0_CODE */
    .bss_RAM4 (NOLOAD) : ALIGN(4)
    {
       PROVIDE(__start_bss_RAM4 = .) ;
       PROVIDE(__start_bss_SDRAM_B0_CODE = .) ;
       *(.bss.$RAM4)
       *(.bss.$SDRAM_B0_CODE)
       *(.bss.$RAM4.*)
       *(.bss.$SDRAM_B0_CODE.*)
       . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */
       PROVIDE(__end_bss_RAM4 = .) ;
       PROVIDE(__end_bss_SDRAM_B0_CODE = .) ;
    } > SDRAM_B0_CODE AT> SDRAM_B0_CODE

    /* BSS section for SDRAM_B0_HEAP */
    .bss_RAM5 (NOLOAD) : ALIGN(4)
    {
       PROVIDE(__start_bss_RAM5 = .) ;
       PROVIDE(__start_bss_SDRAM_B0_HEAP = .) ;
       *(.bss.$RAM5)
       *(.bss.$SDRAM_B0_HEAP)
       *(.bss.$RAM5.*)
       *(.bss.$SDRAM_B0_HEAP.*)
       . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */
       PROVIDE(__end_bss_RAM5 = .) ;
       PROVIDE(__end_bss_SDRAM_B0_HEAP = .) ;
    } > SDRAM_B0_HEAP AT> SDRAM_B0_HEAP

    /* BSS section for SDRAM_B1 */
    .bss_RAM6 (NOLOAD) : ALIGN(4)
    {
       PROVIDE(__start_bss_RAM6 = .) ;
       PROVIDE(__start_bss_SDRAM_B1 = .) ;
       *(.bss.$RAM6)
       *(.bss.$SDRAM_B1)
       *(.bss.$RAM6.*)
       *(.bss.$SDRAM_B1.*)
       . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */
       PROVIDE(__end_bss_RAM6 = .) ;
       PROVIDE(__end_bss_SDRAM_B1 = .) ;
    } > SDRAM_B1 AT> SDRAM_B1

    /* BSS section for SDRAM_B2 */
    .bss_RAM7 (NOLOAD) : ALIGN(4)
    {
       PROVIDE(__start_bss_RAM7 = .) ;
       PROVIDE(__start_bss_SDRAM_B2 = .) ;
       *(.bss.$RAM7)
       *(.bss.$SDRAM_B2)
       *(.bss.$RAM7.*)
       *(.bss.$SDRAM_B2.*)
       . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */
       PROVIDE(__end_bss_RAM7 = .) ;
       PROVIDE(__end_bss_SDRAM_B2 = .) ;
    } > SDRAM_B2 AT> SDRAM_B2

    /* BSS section for SDRAM_B3 */
    .bss_RAM8 (NOLOAD) : ALIGN(4)
    {
       PROVIDE(__start_bss_RAM8 = .) ;
       PROVIDE(__start_bss_SDRAM_B3 = .) ;
       *(.bss.$RAM8)
       *(.bss.$SDRAM_B3)
       *(.bss.$RAM8.*)
       *(.bss.$SDRAM_B3.*)
       . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */
       PROVIDE(__end_bss_RAM8 = .) ;
       PROVIDE(__end_bss_SDRAM_B3 = .) ;
    } > SDRAM_B3 AT> SDRAM_B3

    /* MAIN BSS SECTION */
    .bss (NOLOAD) : ALIGN(4)
    {
        _bss = .;
        PROVIDE(__start_bss_RAM = .) ;
        PROVIDE(__start_bss_SRAM_DTC = .) ;
        *(.bss*)
        *(COMMON)
        . = ALIGN(4) ;
        _ebss = .;
        PROVIDE(__end_bss_RAM = .) ;
        PROVIDE(__end_bss_SRAM_DTC = .) ;
        PROVIDE(end = .);
    } > SRAM_DTC AT> SRAM_DTC

    /* NOINIT section for SRAM_ITC */
    .noinit_RAM2 (NOLOAD) : ALIGN(4)
    {
       PROVIDE(__start_noinit_RAM2 = .) ;
       PROVIDE(__start_noinit_SRAM_ITC = .) ;
       *(.noinit.$RAM2)
       *(.noinit.$SRAM_ITC)
       *(.noinit.$RAM2.*)
       *(.noinit.$SRAM_ITC.*)
       . = ALIGN(4) ;
       PROVIDE(__end_noinit_RAM2 = .) ;
       PROVIDE(__end_noinit_SRAM_ITC = .) ;
    } > SRAM_ITC AT> SRAM_ITC

    /* NOINIT section for SRAM_OC */
    .noinit_RAM3 (NOLOAD) : ALIGN(4)
    {
       PROVIDE(__start_noinit_RAM3 = .) ;
       PROVIDE(__start_noinit_SRAM_OC = .) ;
       *(.noinit.$RAM3)
       *(.noinit.$SRAM_OC)
       *(.noinit.$RAM3.*)
       *(.noinit.$SRAM_OC.*)
       . = ALIGN(4) ;
       PROVIDE(__end_noinit_RAM3 = .) ;
       PROVIDE(__end_noinit_SRAM_OC = .) ;
    } > SRAM_OC AT> SRAM_OC

    /* NOINIT section for SDRAM_B0_CODE */
    .noinit_RAM4 (NOLOAD) : ALIGN(4)
    {
       PROVIDE(__start_noinit_RAM4 = .) ;
       PROVIDE(__start_noinit_SDRAM_B0_CODE = .) ;
       *(.noinit.$RAM4)
       *(.noinit.$SDRAM_B0_CODE)
       *(.noinit.$RAM4.*)
       *(.noinit.$SDRAM_B0_CODE.*)
       . = ALIGN(4) ;
       PROVIDE(__end_noinit_RAM4 = .) ;
       PROVIDE(__end_noinit_SDRAM_B0_CODE = .) ;
    } > SDRAM_B0_CODE AT> SDRAM_B0_CODE

    /* NOINIT section for SDRAM_B0_HEAP */
    .noinit_RAM5 (NOLOAD) : ALIGN(4)
    {
       PROVIDE(__start_noinit_RAM5 = .) ;
       PROVIDE(__start_noinit_SDRAM_B0_HEAP = .) ;
       *(.noinit.$RAM5)
       *(.noinit.$SDRAM_B0_HEAP)
       *(.noinit.$RAM5.*)
       *(.noinit.$SDRAM_B0_HEAP.*)
       . = ALIGN(4) ;
       PROVIDE(__end_noinit_RAM5 = .) ;
       PROVIDE(__end_noinit_SDRAM_B0_HEAP = .) ;
    } > SDRAM_B0_HEAP AT> SDRAM_B0_HEAP

    /* NOINIT section for SDRAM_B1 */
    .noinit_RAM6 (NOLOAD) : ALIGN(4)
    {
       PROVIDE(__start_noinit_RAM6 = .) ;
       PROVIDE(__start_noinit_SDRAM_B1 = .) ;
       *(.noinit.$RAM6)
       *(.noinit.$SDRAM_B1)
       *(.noinit.$RAM6.*)
       *(.noinit.$SDRAM_B1.*)
       . = ALIGN(4) ;
       PROVIDE(__end_noinit_RAM6 = .) ;
       PROVIDE(__end_noinit_SDRAM_B1 = .) ;
    } > SDRAM_B1 AT> SDRAM_B1

    /* NOINIT section for SDRAM_B2 */
    .noinit_RAM7 (NOLOAD) : ALIGN(4)
    {
       PROVIDE(__start_noinit_RAM7 = .) ;
       PROVIDE(__start_noinit_SDRAM_B2 = .) ;
       *(.noinit.$RAM7)
       *(.noinit.$SDRAM_B2)
       *(.noinit.$RAM7.*)
       *(.noinit.$SDRAM_B2.*)
       . = ALIGN(4) ;
       PROVIDE(__end_noinit_RAM7 = .) ;
       PROVIDE(__end_noinit_SDRAM_B2 = .) ;
    } > SDRAM_B2 AT> SDRAM_B2

    /* NOINIT section for SDRAM_B3 */
    .noinit_RAM8 (NOLOAD) : ALIGN(4)
    {
        PROVIDE(__start_noinit_RAM8 = .) ;
        PROVIDE(__start_noinit_SDRAM_B3 = .) ;
        *(.noinit.$RAM8)
        *(.noinit.$SDRAM_B3)
        *(.noinit.$RAM8.*)
        *(.noinit.$SDRAM_B3.*)
        *(.noinit.$SDRAM_B3*)
       . = ALIGN(4) ;
       PROVIDE(__end_noinit_RAM8 = .) ;
       PROVIDE(__end_noinit_SDRAM_B3 = .) ;
    } > SDRAM_B3 AT> SDRAM_B3

    /* DEFAULT NOINIT SECTION */
    .noinit (NOLOAD): ALIGN(4)
    {
        _noinit = .;
        PROVIDE(__start_noinit_RAM = .) ;
        PROVIDE(__start_noinit_SRAM_DTC = .) ;
        *(.noinit*)
         . = ALIGN(4) ;
        _end_noinit = .;
       PROVIDE(__end_noinit_RAM = .) ;
       PROVIDE(__end_noinit_SRAM_DTC = .) ;        
    } > SRAM_DTC AT> SRAM_DTC

     _StackSize = 0x1000;
     /* Reserve space in memory for Stack */
    .heap2stackfill (NOLOAD) :
    {
        . += _StackSize;
    } > SRAM_DTC
    /* Locate actual Stack in memory map */
    .stack ORIGIN(SRAM_DTC) + LENGTH(SRAM_DTC) - _StackSize - 0 (NOLOAD) :  ALIGN(4)
    {
        _vStackBase = .;
        . = ALIGN(4);
        _vStackTop = . + _StackSize;
    } > SRAM_DTC

    /* Provide basic symbols giving location and size of main text
     * block, including initial values of RW data sections. Note that
     * these will need extending to give a complete picture with
     * complex images (e.g multiple Flash banks).
     */
    _image_start = LOADADDR(.text);
    _image_end = LOADADDR(.data) + SIZEOF(.data);
    _image_size = _image_end - _image_start;
}
0 Kudos
Reply
2,955 Views
nxf77486
NXP TechSupport
NXP TechSupport

Hello,

 

Thank you in advance for your information, it is possible to move the Ethernet configuration to RAM and store your application on the SDRAM. We have seen son troubles when the Ethernet try to get some resource form the SDRAM when this is being used so what we can do is move the resources required for Ethernet to the RAM in order for not having resource problems.

0 Kudos
Reply
2,941 Views
GUnderdown
Contributor IV

By configuration, do you mean the TX/RX buffers? Those are currently placed in SRAM_DTC

 

EIR 0x00000000 RW 0x402d8004 Interrupt Event Register
EIMR 0x00000000 RW 0x402d8008 Interrupt Mask Register
RDAR 0x01000000 RW 0x402d8010 Receive Descriptor Active Register - Ring 0
TDAR 0x01000000 RW 0x402d8014 Transmit Descriptor Active Register - Ring 0
ECR 0xf0000102 RW 0x402d8024 Ethernet Control Register
MMFR 0x60fe8180 RW 0x402d8040 MII Management Frame Register
MSCR 0x00000130 RW 0x402d8044 MII Speed Control Register
MIBC 0x40000000 RW 0x402d8064 MIB Control Register
RCR 0x05ee4104 RW 0x402d8084 Receive Control Register
TCR 0x00000004 RW 0x402d80c4 Transmit Control Register
PALR 0xba553300 RW 0x402d80e4 Physical Address Lower Register
PAUR 0x00068808 RW 0x402d80e8 Physical Address Upper Register
OPD 0x00010000 RW 0x402d80ec Opcode/Pause Duration Register
TXIC0 0x00000000 RW 0x402d80f0 Transmit Interrupt Coalescing Register
RXIC0 0x00000000 RW 0x402d8100 Receive Interrupt Coalescing Register
IAUR 0x00000000 RW 0x402d8118 Descriptor Individual Upper Address Register
IALR 0x00000000 RW 0x402d811c Descriptor Individual Lower Address Register
GAUR 0x00000000 RW 0x402d8120 Descriptor Group Upper Address Register
GALR 0x00000000 RW 0x402d8124 Descriptor Group Lower Address Register
TFWR 0x00000100 RW 0x402d8144 Transmit FIFO Watermark Register
RDSR 0x2002e480 RW 0x402d8180 Receive Descriptor Ring 0 Start Register
TDSR 0x2002e4c0 RW 0x402d8184 Transmit Buffer Descriptor Ring 0 Start Register
MRBR 0x00000600 RW 0x402d8188 Maximum Receive Buffer Size Register - Ring 0
RSFL 0x00000000 RW 0x402d8190 Receive FIFO Section Full Threshold
RSEM 0x00000000 RW 0x402d8194 Receive FIFO Section Empty Threshold
RAEM 0x00000004 RW 0x402d8198 Receive FIFO Almost Empty Threshold
RAFL 0x00000004 RW 0x402d819c Receive FIFO Almost Full Threshold
TSEM 0x00000000 RW 0x402d81a0 Transmit FIFO Section Empty Threshold
TAEM 0x00000004 RW 0x402d81a4 Transmit FIFO Almost Empty Threshold
TAFL 0x00000008 RW 0x402d81a8 Transmit FIFO Almost Full Threshold
TIPG 0x0000000c RW 0x402d81ac Transmit Inter-Packet Gap
FTRL 0x000007ff RW 0x402d81b0 Frame Truncation Length
TACC 0x00000000 RW 0x402d81c0 Transmit Accelerator Function Configuration
RACC 0x00000000 RW 0x402d81c4 Receive Accelerator Function Configuration

0 Kudos
Reply
2,894 Views
nxf77486
NXP TechSupport
NXP TechSupport

Hello,

No, for configuration I mean to move the whole Ethernet to the RAM and leave the application on the SDRAM or otherwise the thing is to not share resources form the SDRAM.

0 Kudos
Reply
2,865 Views
GUnderdown
Contributor IV

@nxf77486 

 

I went through this morning and enabled the enhanced buffer descriptors and hopefully they contain information that helps.

 

Referencing section 37.3.14.2 of the reference manual, the transmit buffer descriptors indicate an error. I see the TXE, EE, and OE bits set, as well as several of the fields that are supposed to be cleared/written zero are NOT written zero

 

Below is a copy of the registers for ENET

EIR 0x00000000 RW 0x402d8004 Interrupt Event Register
EIMR 0x00000000 RW 0x402d8008 Interrupt Mask Register
RDAR 0x01000000 RW 0x402d8010 Receive Descriptor Active Register - Ring 0
TDAR 0x00000000 RW 0x402d8014 Transmit Descriptor Active Register - Ring 0
ECR 0xf0000112 RW 0x402d8024 Ethernet Control Register
MMFR 0x60fa0136 RW 0x402d8040 MII Management Frame Register
MSCR 0x0000012e RW 0x402d8044 MII Speed Control Register
MIBC 0xc0000000 RW 0x402d8064 MIB Control Register
RCR 0x05ee4104 RW 0x402d8084 Receive Control Register
TCR 0x00000004 RW 0x402d80c4 Transmit Control Register
PALR 0xba553300 RW 0x402d80e4 Physical Address Lower Register
PAUR 0x00068808 RW 0x402d80e8 Physical Address Upper Register
OPD 0x00010000 RW 0x402d80ec Opcode/Pause Duration Register
TXIC0 0x00000000 RW 0x402d80f0 Transmit Interrupt Coalescing Register
RXIC0 0x00000000 RW 0x402d8100 Receive Interrupt Coalescing Register
IAUR 0x00000000 RW 0x402d8118 Descriptor Individual Upper Address Register
IALR 0x00000000 RW 0x402d811c Descriptor Individual Lower Address Register
GAUR 0x00000000 RW 0x402d8120 Descriptor Group Upper Address Register
GALR 0x00000000 RW 0x402d8124 Descriptor Group Lower Address Register
TFWR 0x00000100 RW 0x402d8144 Transmit FIFO Watermark Register
RDSR 0x2002e7c0 RW 0x402d8180 Receive Descriptor Ring 0 Start Register
TDSR 0x2002e880 RW 0x402d8184 Transmit Buffer Descriptor Ring 0 Start Register
MRBR 0x00000600 RW 0x402d8188 Maximum Receive Buffer Size Register - Ring 0
RSFL 0x00000000 RW 0x402d8190 Receive FIFO Section Full Threshold
RSEM 0x00000000 RW 0x402d8194 Receive FIFO Section Empty Threshold
RAEM 0x00000004 RW 0x402d8198 Receive FIFO Almost Empty Threshold
RAFL 0x00000004 RW 0x402d819c Receive FIFO Almost Full Threshold
TSEM 0x00000000 RW 0x402d81a0 Transmit FIFO Section Empty Threshold
TAEM 0x00000004 RW 0x402d81a4 Transmit FIFO Almost Empty Threshold
TAFL 0x00000008 RW 0x402d81a8 Transmit FIFO Almost Full Threshold
TIPG 0x0000000c RW 0x402d81ac Transmit Inter-Packet Gap
FTRL 0x000007ff RW 0x402d81b0 Frame Truncation Length
TACC 0x00000000 RW 0x402d81c0 Transmit Accelerator Function Configuration
RACC 0x00000000 RW 0x402d81c4 Receive Accelerator Function Configuration

 

Below is a copy of the memory I've seen, this address is buffer descriptor zero

0x2002E880 002A
0x2002E882 8C00
0x2002E884 3F80
0x2002E886 2001
0x2002E888 9212
0x2002E88A C8C5
0x2002E88C FC07
0x2002E88E 09B8
0x2002E890 8250
0x2002E892 33BE
0x2002E894 CB7E
0x2002E896 DC3B
0x2002E898 F9DD
0x2002E89A 85F8
0x2002E89C 4EBE
0x2002E89E 332F

 

If I look at the 0x20013f80 location I see what looks like a valid ARP announcement or ARP request (depending on when I stop the program).

I would expect that the SDK sets the required fields to zero per table 37-34, for example, offset +0xC, the reference manual says thatt the entire 16bits are reserved and must be cleared, but here their value is 0x4EBE. I have not modified the SDK file (I went through and refreshed the SDK components and tested again, had the same result). I believe that would be an SDK problem then (or a reference manual problem).

~~~~~

I believe, in the SDK, the code needs to modify the "controlExtendedn" registers, as well as the "reservedn" registers (in the struct, which lines up to various addresses). I went through and manually cleared the reserved bytes through the debugger, and cleared the controlExtended0 (offset +08h) to hopefully allow the uDMA to set those error fields fields. I cleared and never saw the (offset +12h/controleExtended2) BDU field being set, so I think for some reason, the uDMA transfer is never happening.It would probably be easiest, to when the SDK goes to initialize the descriptor, it just sets everything to zero then only modified the length, pointers, control, timestamp. and controlExtended1 registers. That's just my 2 cents, however.

 

I think the root of my problem is now that the uDMA transfers are not happening or being initiated, based off the BDU field never being set. Would you agree?

0 Kudos
Reply
2,869 Views
GUnderdown
Contributor IV

At the moment, only code is placed on the SDRAM. All the stack and heap is on DTCM. Are you saying you want me to mark all the ethernet functions as ramfunction? (which should put them into DTCM)?

 

0 Kudos
Reply
2,829 Views
nxf77486
NXP TechSupport
NXP TechSupport

Hello,

So please let me clarify this point regarding the DMA, so in the section that should have a value of 0 they are having another value? Is this also happening out of the custom example you are working with? Like a regular ethernet example.

Just to make sure that there is no problem with it, and yes mark the ethernet functions to ram.

0 Kudos
Reply
2,762 Views
GUnderdown
Contributor IV

@nxf77486 

 

I re-tested with the SDK example, linked per the following image:

GUnderdown_0-1703599817381.png

 

 

I observed that this example worked just fine, no errors seemed to happen, I see the packets in wireshark. Same physical connection. I did modify the code to include "ENET_ENHANCEDBUFFERDESCRIPTOR_MODE" as a preprocessor define.

 

Looking at the ENET registers, I see an enhanced descriptor at 0xe7c0 (which makes sense). Inspecting that memory gives me the following:

 

0x0000E7BE ????
0x0000E7C0 004A
0x0000E7C2 0C00
0x0000E7C4 0580
0x0000E7C6 0000
0x0000E7C8 0000
0x0000E7CA 4000
0x0000E7CC 0000
0x0000E7CE 0000
0x0000E7D0 0000
0x0000E7D2 8000
0x0000E7D4 0000
0x0000E7D6 0000
0x0000E7D8 0000
0x0000E7DA 0000
0x0000E7DC 0000
0x0000E7DE 0000

 

The value to note here is that the offset of +12h, the value of 8000. I stepped through the code for a moment, after manually clearing the BDU bit. I observed that the BDU bit was set by the next time the ENET_SendFrame() function was called. This leads me to belive that the reference manual is correct when it comes to how this bit operates.

 

~~~~~

I applied

__attribute__((section("RamFunction")))

to every function in fsl_enet.c, and verified that the functions are actually placed into SRAM_DTC (The relevant linkerscript is somewhere in the previous posts), using the debug view. All functions indicated 0x20xxxxxx instead of 0x80xxxxxx so I belive that I accomplished this. I observed no change in functionality with this change.

~~~~
An observation, I haven't modified the ethernet driver but to add the ram functions, and yet, in the sdk example, the issue I saw of gibberish data being placed in the reserved sections (which should be 0) of the ethernet buffers doesn't happen in the SDK example, but does happen in my code. I think that's incredibly odd, and I will investigate that further.
~~~~~

I was also reading AN12077, regarding the FlexRAM, and noticed that the DTCM interface is not identical to the ITCM interface. Figure 1 in the AN shows that the DTCM bus is actually 2x32 bit interleaved busses (and further reading confirms that), whereas the ITCM bus is a 64 bit bus. Could this possibly be causing issues with the ethernet MAC DMA?

0 Kudos
Reply
2,751 Views
nxf77486
NXP TechSupport
NXP TechSupport

Hello,

The fact that the DTCM is a 2x32 bit could be one of the possible troubles with the ethernet MAC DMA, but it also possible to separate them in order to fit into the DTCM.

0 Kudos
Reply
2,662 Views
GUnderdown
Contributor IV

@nxf77486 

I think I have ruled out the dtcm data bus being the problem.

I imported the sdk example .mex file so that I had a known good clock configuration and pin muxing, and observed no changes.

For giggles, I went and changed the library from NewLibNano to NewLib (both semihosting variants). After making the library change, I observed packets in wireshark from the mac address that I had set.

This means the board is now transmitting data (it's not receiving yet but I haven't dug into that issue yet).

 

It looks like, for some reason, the issue is with newlibnano.

0 Kudos
Reply