cancel
Showing results for 
Search instead for 
Did you mean: 

[STM32CubeMX] lwIP + FreeRTOS Sample Project

emeydanli
Associate II
Posted on April 23, 2014 at 16:41

Hello Everyone,

I wonder if anyone has been able to get lwIP work properly?

My platform consists of Open407-D baseboard, STM32F4 Discovery and DP83848 Ethernet PHY. SysClk is clocked at 168 MHz.

I have been struggling with generated code by STM32CubeMX for two days. During this time, I have found several issues. 

1) In sys_mutex_lock function, mutex pointer seems incorrectly dereferenced.

2) Priority of the ethernet interrupt is incorrectly configured. It is higher than configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY. That's why firmware hangs in one of FreeRTOS assertions.

3) tcpip_thread is not created due to an incorrect parameter value. (TCPIP_THREAD_STACKSIZE equals to zero)

These are the things I could find but still I cannot get it work. Even though the DHCP option is enabled, the device cannot get an IP address. Giving a static IP address does not work too.

The worst thing is it does not even respond to pings. As an experiment, I created an UDP socket and sent data over it continuously. Green Ethernet LED blinks but of course the packets do not reach to anywhere. (checked with wireshark) 

What can be the problem? Do you have any ideas?

#freertos-lwip #stm32-discovery #cube-lwip-+-stm32f107-+-lan8720a #ethernet
40 REPLIES 40
antonius
Senior
Posted on July 19, 2015 at 03:51

Had a webserver running off that board without much effort using the SPL/ETH examples.

Which example ?

Here's the debug I get from UART....

0690X000006032YQAQ.jpg
Posted on July 19, 2015 at 15:16

And how do you have these systems cabled? Through a cross-over cable, or into a switch/hub?

Have you had any STM32 Ethernet examples working on other boards?

I've had an F207 running via the LwIP/ETH examples.

http://www.st.com/web/en/catalog/tools/PF257896

On the F107 side I've had the STM32C-MICOS board running the web server.

http://www.st.com/web/en/resource/technical/document/user_manual/CD00246066.pdf

F107 LwIP/ETH

http://www.st.com/web/en/catalog/tools/FM147/CL1794/SC961/SS1743/LN1734/PF257862

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
antonius
Senior
Posted on July 20, 2015 at 12:07

And how do you have these systems cabled? Through a cross-over cable, or into a switch/hub?

=========== That's a good question, I'm not using a switch or hub, I connect DP83848 module with ethernet cable directly to my computer, I'm not sure if my cable is cross-overed or not....how do I know that...? From debuging

/* init function */
void MX_LWIP_Init(void)
{
IP_ADDRESS[0] = 10;
IP_ADDRESS[1] = 0;
IP_ADDRESS[2] = 0;
IP_ADDRESS[3] = 12;
NETMASK_ADDRESS[0] = 255;
NETMASK_ADDRESS[1] = 255;
NETMASK_ADDRESS[2] = 255;
NETMASK_ADDRESS[3] = 0;
GATEWAY_ADDRESS[0] = 10;
GATEWAY_ADDRESS[1] = 0;
GATEWAY_ADDRESS[2] = 0;
GATEWAY_ADDRESS[3] = 10;
/* Initilialize the LwIP stack */
lwip_init();
IP4_ADDR(&ipaddr, IP_ADDRESS[0], IP_ADDRESS[1], IP_ADDRESS[2], IP_ADDRESS[3]);
IP4_ADDR(&netmask, NETMASK_ADDRESS[0], NETMASK_ADDRESS[1] , NETMASK_ADDRESS[2], NETMASK_ADDRESS[3]);
IP4_ADDR(&gw, GATEWAY_ADDRESS[0], GATEWAY_ADDRESS[1], GATEWAY_ADDRESS[2], GATEWAY_ADDRESS[3]); 
/* add the network interface */
netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, ðernetif_init, ðernet_input);
/* Registers the default network interface */
netif_set_default(&gnetif);
if (netif_is_link_up(&gnetif))
{
/* When the netif is fully configured this function must be called */
netif_set_up(&gnetif);
HAL_UART_Transmit(&huart1, ''LINK UP! 
'', 40, 1000);
}
else
{
/* When the netif link is down this function must be called */
netif_set_down(&gnetif);
HAL_UART_Transmit(&huart1, ''LINK DOWN! 
'', 40, 1000);
} 
/* USER CODE BEGIN 3 */
HAL_UART_Transmit(&huart1, ''Finished LWIP INIT 
'', 22, 1000);
/* USER CODE END 3 */
}

with UART I get a response from this function above, LINK UP! ..LINK DOWN! Finished LWIP INIT Why it's saying UP then DOWN ??? Is it because of non cross-over cable ? How do I know my cable is cross-overed or not ? I see in my cable : ''verified cat6a patch cable'' but it doesn't say cross-over or not ?... No I don't have any other STM32 boards working with ethernet, this one is my first STM32 experiment with ethernet... thanks
Posted on July 20, 2015 at 18:08

Standard patch cables are wired straight-through, they expect a computer-to-hub/switch connection. For computer-to-computer you need a cross-over cable, where the TX/RX pairs are swapped.

Otherwise the TX of Computer A, is connected to the TX of Computer B, which clearly won't work.

https://en.wikipedia.org/wiki/Ethernet_crossover_cable

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
antonius
Senior
Posted on July 21, 2015 at 11:34

I got some message inside buffer if I connect the cable, does it mean, it's already doing something ?

If I plug the ethernet cable I got this on my USART : [B]Buffer value: .-éð_'H FÆj. ƒFFÖø*1à0hÿÿÿÿÿÿÈ ©qGà...È ©qGà..........©þ[/B] If I unplug it..... it's doing a loop inside this function

static struct pbuf * low_level_input(struct netif *netif)
{
struct pbuf *p = NULL;
struct pbuf *q;
uint16_t len = 0;
uint8_t *buffer;
__IO ETH_DMADescTypeDef *dmarxdesc;
uint32_t bufferoffset = 0;
uint32_t payloadoffset = 0;
uint32_t byteslefttocopy = 0;
uint32_t i=0;
HAL_UART_Transmit(&huart1, ''Inside Low level input ethernetif.c! 
'', 40, 1000);
/* get received frame */
if (HAL_ETH_GetReceivedFrame(&heth) != HAL_OK)
return NULL;
/* Obtain the size of the packet and put it into the ''len'' variable. */
len = heth.RxFrameInfos.length;
buffer = (uint8_t *)heth.RxFrameInfos.buffer;
HAL_UART_Transmit(&huart1, ''Buffer value: 
'', 40, 1000);
HAL_UART_Transmit(&huart1, buffer, 40, 1000);
if (len > 0)
{
/* We allocate a pbuf chain of pbufs from the Lwip buffer pool */
p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
}
if (p != NULL)
{
dmarxdesc = heth.RxFrameInfos.FSRxDesc;
bufferoffset = 0;
for(q = p; q != NULL; q = q->next)
{
byteslefttocopy = q->len;
payloadoffset = 0;
/* Check if the length of bytes to copy in current pbuf is bigger than Rx buffer size*/
while( (byteslefttocopy + bufferoffset) > ETH_RX_BUF_SIZE )
{
/* Copy data to pbuf */
memcpy( (uint8_t*)((uint8_t*)q->payload + payloadoffset), (uint8_t*)((uint8_t*)buffer + bufferoffset), (ETH_RX_BUF_SIZE - bufferoffset));
/* Point to next descriptor */
dmarxdesc = (ETH_DMADescTypeDef *)(dmarxdesc->Buffer2NextDescAddr);
buffer = (uint8_t *)(dmarxdesc->Buffer1Addr);
byteslefttocopy = byteslefttocopy - (ETH_RX_BUF_SIZE - bufferoffset);
payloadoffset = payloadoffset + (ETH_RX_BUF_SIZE - bufferoffset);
bufferoffset = 0;
}
/* Copy remaining data in pbuf */
memcpy( (uint8_t*)((uint8_t*)q->payload + payloadoffset), (uint8_t*)((uint8_t*)buffer + bufferoffset), byteslefttocopy);
bufferoffset = bufferoffset + byteslefttocopy;
}
/* Release descriptors to DMA */
/* Point to first descriptor */
dmarxdesc = heth.RxFrameInfos.FSRxDesc;
/* Set Own bit in Rx descriptors: gives the buffers back to DMA */
for (i=0; i< 
heth.RxFrameInfos.SegCount
; i++)
{ 
dmarxdesc->Status |= ETH_DMARXDESC_OWN;
dmarxdesc = (ETH_DMADescTypeDef *)(dmarxdesc->Buffer2NextDescAddr);
}
/* Clear Segment_Count */
heth.RxFrameInfos.SegCount =0;
} 
/* When Rx Buffer unavailable flag is set: clear it and resume reception */
if ((heth.Instance->DMASR & ETH_DMASR_RBUS) != (uint32_t)RESET) 
{
/* Clear RBUS ETHERNET DMA flag */
heth.Instance->DMASR = ETH_DMASR_RBUS;
/* Resume DMA reception */
heth.Instance->DMARPDR = 0;
}
return p;
}

on UART :[B] .Inside Low level input ethernetif.c! ..Inside Low level input ethernetif.c! ..Inside Low level input ethernetif.c! ..Inside Low level input ethernetif.c! ..Inside Low level input ethernetif.c! [/B] Any clues ? thanks
antonius
Senior
Posted on July 22, 2015 at 12:53

Is it possible if I connect it via a hub ? or must be a cross over cable ?thanks

antonius
Senior
Posted on July 22, 2015 at 15:24

Clive, is MAC address correct ? or I need to change it ?thanks
 static void low_level_init(struct netif *netif)
{ 
uint32_t regvalue = 0;
HAL_StatusTypeDef hal_eth_init_status;
/* Init ETH */
uint8_t MACAddr[6] ;
heth.Instance = ETH;
heth.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;
//heth.Init.Speed = ETH_SPEED_10M;
heth.Init.Speed = ETH_SPEED_100M;
heth.Init.DuplexMode = ETH_MODE_FULLDUPLEX;
heth.Init.PhyAddress = 1;
MACAddr[0] = 0x00;
MACAddr[1] = 0x80;
MACAddr[2] = 0xE1;
MACAddr[3] = 0x00;
MACAddr[4] = 0x00;
MACAddr[5] = 0x00;
heth.Init.MACAddr = &MACAddr[0];
heth.Init.RxMode = ETH_RXPOLLING_MODE;
heth.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE;
heth.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;
hal_eth_init_status = HAL_ETH_Init(&heth);
if (hal_eth_init_status == HAL_OK)
{
/* Set netif link flag */ 
netif->flags |= NETIF_FLAG_LINK_UP;
}
/* Initialize Tx Descriptors list: Chain Mode */
HAL_ETH_DMATxDescListInit(&heth, DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB);
/* Initialize Rx Descriptors list: Chain Mode */
HAL_ETH_DMARxDescListInit(&heth, DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB);
#if LWIP_ARP || LWIP_ETHERNET 
/* set MAC hardware address length */
netif->hwaddr_len = ETHARP_HWADDR_LEN;
/* set MAC hardware address */
netif->hwaddr[0] = heth.Init.MACAddr[0];
netif->hwaddr[1] = heth.Init.MACAddr[1];
netif->hwaddr[2] = heth.Init.MACAddr[2];
netif->hwaddr[3] = heth.Init.MACAddr[3];
netif->hwaddr[4] = heth.Init.MACAddr[4];
netif->hwaddr[5] = heth.Init.MACAddr[5];
/* maximum transfer unit */
netif->mtu = 1500;
/* Accept broadcast address and ARP traffic */
/* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
#if LWIP_ARP
netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
# else 
netif->flags |= NETIF_FLAG_BROADCAST;
#endif /* LWIP_ARP */
/* Enable MAC and DMA transmission and reception */
HAL_ETH_Start(&heth);
/**** Configure PHY to generate an interrupt when Eth Link state changes ****/
/* Read Register Configuration */
HAL_ETH_ReadPHYRegister(&heth, PHY_MICR, ®value);
regvalue |= (PHY_MICR_INT_EN | PHY_MICR_INT_OE);
/* Enable Interrupts */
HAL_ETH_WritePHYRegister(&heth, PHY_MICR, regvalue );
/* Read Register Configuration */
HAL_ETH_ReadPHYRegister(&heth, PHY_MISR, ®value);
regvalue |= PHY_MISR_LINK_INT_EN;
/* Enable Interrupt on change of link status */
HAL_ETH_WritePHYRegister(&heth, PHY_MISR, regvalue); 
#endif /* LWIP_ARP || LWIP_ETHERNET */
HAL_UART_Transmit(&huart1, ''Finished LOW LEVEL INIT! /n'', 36, 1000);
}

Posted on July 22, 2015 at 17:25

Is it possible if I connect it via a hub ? or must be a cross over cable ?

Ok, let's review networking. When you connect systems on a 10/100BT Ethernet branch you typically do so with a straight-through (one-to-one) patch cable between the computing device and a hub/switch. If you wish to connect two computing devices directly, you either need a cross-over type cable, or a connection architecture that can switch things around.

Valid MAC addresses need to be purchased, for a network to actually function properly all nodes need to have a unique MAC address. For testing you can make up your own, but this won't fly for retail products.

It would help you significantly if you got some foundation in the network technology you're building circuits for.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
antonius
Senior
Posted on July 22, 2015 at 23:58

Hi clive1,

I still can't not ping it, I used a switch and straight cable, the LED on the switch are blinking...

Here's the IP address for cubemx

 IP_ADDRESS[0] = 192;

  IP_ADDRESS[1] = 168;

  IP_ADDRESS[2] = 1;

  IP_ADDRESS[3] = 12;

  NETMASK_ADDRESS[0] = 255;

  NETMASK_ADDRESS[1] = 255;

  NETMASK_ADDRESS[2] = 255;

  NETMASK_ADDRESS[3] = 0;

  GATEWAY_ADDRESS[0] = 192;

  GATEWAY_ADDRESS[1] = 168;

  GATEWAY_ADDRESS[2] = 1;

  GATEWAY_ADDRESS[3] = 1;

and the UART output when I tested it :

 

Finished ETH INIT

 

.Finished LOW LEVEL INIT! /n.È.. -éøOLINK UP!

 

..LINK DOWN!

 

....È.. FinishedFinished LWIP INIT

 

..START LISTENING!

 

..&#16;µ

 

F&#1;.

 

�??h&#24;±&#16;FTCP_echoserver_init DONE!

 

.È.. }IHI There...LwIP STM32F107!

 

..Inside Low level input ethernetif.c!

 

..Buffer value:

 

.-éð_'H

 

FÆj. ?F&#4;FÖø&#8; 1à0hÿÿÿÿÿÿÈ

 

©qGà&#8;.E..N.í..€&#17;µXÀ?&#1;

 

À?&#1;ÿ.?.?.:

my IP address on the computer :

0690X00000602zfQAA.jpg

if I plug out the cable it's looping in here :

 

Finished LOW LEVEL INIT! /n.È.. -éøOLINK UP!

 

..LINK DOWN!

 

....È.. FinishedFinished LWIP INIT

 

..START LISTENING!

 

..&#16;µ

 

F&#1;.

 

�??h&#24;±&#16;FTCP_echoserver_init DONE!

 

.È.. }IHI There...LwIP STM32F107!

 

..Inside Low level input ethernetif.c!

 

..Inside Low level input ethernetif.c!

 

..Inside Low level input ethernetif.c!

 

..Inside Low level input ethernetif.c!

 

..Inside Low level input ethernetif.c!

any clues ? ?

Posted on July 23, 2015 at 01:25

I'm not going to dig in and debug Cube/HAL stuff, or try to determine if your issue here is on the software or hardware side. I really don't have the patience or resources to throw at it.

The debugging output would be a lot more effective if it specified the length of the buffer received and output the buffer as hex bytes. At an ETH 802.3 level this would let you see source and destination MAC addresses on the wire, and if you dug deeper the TCP/IP payload beyond them.

Given your level of experience with networking, I would be starting with known good software, and known good hardware, and observe it functioning correctly. A little HTTP web server would be a particularly good demo.

If you have a router that serves DHCP addresses, you could try having the board acquire an address and see if the router's status page shows a lease for your MAC address, and if the board communicates.

If none of this stuff is working, look at the magnetics being used, and make sure they are of the correct ratio, and check if the PHY can negotiate a 10 or 100 connection with your hub/switch if it's of the auto-negotiation type.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..