FreeRTOS on SAME70 with FreeRTOS-Plus-TCP - DHCP Fails

I am running FreeRTOS on a SAME70, compile via Atmet Studio. There are multiple tasks running fine to handle UART communication etc.
I am currently trying to add ethernet support by using FreeRTOS-Plus-TCP. The PHY I’m using is a KSZ8081RNACA.

I am able to read from and write to the standard IEEE registers on the PHY. I can use polling of the interrupt flag to detect when an ethernet cable is plugged in and removing. This was just to confirm the communication over MDIO

I have DHCP enabled. When I plug in an ethernet cable connected to my router, I get a call to “vApplicationIPNetworkEventHook_Multi” after 30 seconds, to indicate that ethernet is up. However, DHCP fails each time. If I disable DHCP, the call to “vApplicationIPNetworkEventHook_Multi” occurs almost immediately. DHCP’s default timeout is 30 seconds, so it’s failing each time.

If I unplug the ethernet cable after being notified the ethernet is up, I will get 1 more call to “vApplicationIPNetworkEventHook_Multi”. However, future ethenet cable plug-in occurences are ignored. I get no furhter calls to “vApplicationIPNetworkEventHook_Multi”.

I started by just making calls to FreeRTOS_FillEndPoint() and FreeRTOS_IPInit_Multi();, but nothing worked. Then I added a call to enable the clock. Still things didn’t work. Then I tried to parse an example and came up with the code below. However, I don’t know if the MAC configuration that I’m doing is actually messing up things more than they’re helping. I can’t determine if the PLUS-TCP package does configuration of the MAC on the SAME70, or what the configuration needs to be.

During initialization, I perform the following:

/* Enable GMAC clock. */
pmc_enable_periph_clk(ID_GMAC);

/* Disable TX & RX and more. */
gmac_network_control(GMAC, 0);
gmac_disable_interrupt(GMAC, ~0u);

gmac_clear_statistics(GMAC);

/* Clear all status bits in the receive status register. */
gmac_clear_rx_status(GMAC, GMAC_RSR_BNA | GMAC_RSR_REC | GMAC_RSR_RXOVR	| GMAC_RSR_HNO);

/* Clear all status bits in the transmit status register. */
gmac_clear_tx_status(GMAC, GMAC_TSR_UBR | GMAC_TSR_COL | GMAC_TSR_RLE
		| GMAC_TSR_TXGO | GMAC_TSR_TFC | GMAC_TSR_TXCOMP
		| GMAC_TSR_HRESP);

/* Clear interrupts. */
gmac_get_interrupt_status(GMAC);

/* Enable the copy of data into the buffers
   ignore broadcasts, and not copy FCS. */
gmac_enable_copy_all(GMAC, false);
gmac_disable_broadcast(GMAC, false);

/* Set RX buffer size to 1536. */
gmac_set_rx_bufsize(GMAC, 0x18);

/* Clear interrupts */
for(uint8_t i = 1; i < GMAC_QUE_N; i++)
{
	gmac_get_priority_interrupt_status(GMAC, (gmac_quelist_t)(GMAC_QUE_0+i));
}

/* Enable GMAC clock. */
pmc_enable_periph_clk(ID_GMAC);

//Get the system clock speed	
mck = sysclk_get_cpu_hz();

//Initialize the MAC
initResult = ethernet_phy_init(GMAC, BOARD_GMAC_PHY_ADDR, mck);

/* Initialise the interface descriptor for WinPCap for example. */
pxSAM_FillInterfaceDescriptor( 0, &( xInterfaces[ 0 ] ) );
	
	
FreeRTOS_FillEndPoint( &( xInterfaces[ 0 ] ), &( xEndPoints[ 0 ] ), ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress );
	
	#if ( ipconfigUSE_DHCP != 0 )
	{
		/* End-point 0 wants to use DHCPv4. */
		xEndPoints[ 0 ].bits.bWantDHCP = pdTRUE;
	}
	#endif /* ( ipconfigUSE_DHCP != 0 ) */
	
FreeRTOS_IPInit_Multi();

Can anyone tell me how much configuration of the MAC I need to do?
Even better: Does anyone have an example of working code that uses DHCP and makes a socket connection as a CLIENT to a server on a SAME70 or similar device?

I think the example by @mtut GitHub - Peter-Herrmann/SAME70-FreeRTOS-Plus-TCP: A minimal example of a FreeRTOS-Plus-TCP port for the SAME70 might help you. Try it out!

FYI old post on SAMEE70: FreeRTOS-Plus-TCP on SAME70 and latest code - #12 by mtut

When you use a static IP address, are you able to ping your DUT?

Hi Nikhil,

Thank you for that link. I tried running that project on my SAME70 Xplained board and it seems to be able to get an IP via DHCP, which is great. I will try to port the code to my project, for my custom PCB and see if I can get that to work.

Hi RAc,

No, I don’t get any response, only timeouts, when I try to PING the DUT. I’m going to try to port the code Nikhil shared above and see if a ping will work then.

@NikhilKamath Thank you very much for your suggestion. I got my system to get an IP address by using the code from Peter Hermann. However, one seemingly important details was that I was missing the following from my flash.ld file (i.e. linker script :

.first_data (NOLOAD) :
{
	. = ALIGN(4);
	_first_data = . ;
	*(._first_data ._first_data.*)
	. = ALIGN(4);
	_e_first_data = . ;
} > ram

This was in Peter’s script, but not mine. I think this is to ensure that 32bit data (4 bytes) are aligned with memory, but I’m not sure. Do you know what part of the FreeRTOS TCP/IP stack is dependent on this? It’s not stopping me. I would just like to understand the linker syntax better. I’ve always found it cryptic.

@RAc I get responses to ping requests now. Thanks for taking a look at my question.

1 Like

I am not an expert on linker scripts. The first_data section creates a dedicated section at the beginning of RAM for all initialized data, guaranteeing 4-byte alignment. This is useful if large contiguous block of uncached memory is required at the start of RAM for DMA. In the context of FreeRTOS-Plus-TCP, the 4-byte alignment enforced by linker scripts is primarily intended for efficient DMA access to network buffers.. From this post - FreeRTOS +TCP on SAME70 - #13 by PBot, I think this is also done to deal with the D-cache (if enabled) and maintain cache coherency. I will let the experts from the community and my colleagues/TCP developers confirm here. @htibosch @Shub @moninom1 @ActoryOu @tony-josi-aws

This section of the linker script ensures that the data placed in the first_data section goes into the RAM first and is 4 byte aligned. As @NikhilKamath said, the alignment or placement requirements are likely for DMA or cache.

1 Like

Just to add to what @NikhilKamath and @aggarg pointed out: This is NOT a requirement of the FreeRTOS stack but the underlying hardware, thus must be implemented in the driver (which acts as a glue between the hardware and the software, in this case the netweork stack). It is very common for hardware to impose restrictions on how the chip ressources can be accessed, so for device driver writers, the chip docs are mandatory literature.

1 Like