STM32 Ethernet Demo

This forum is dedicated to feedback, discussions about ongoing or future developments, ideas and suggestions regarding the ChibiOS projects are welcome. This forum is NOT for support.
mabl
Posts: 417
Joined: Tue Dec 21, 2010 10:19 am
Location: Karlsruhe, Germany
Been thanked: 1 time
Contact:

Re: STM32 Ethernet Demo

Postby mabl » Thu Oct 06, 2011 10:05 pm

Hey santatanta,

I was curious how ST does it and basically they do the same thing:

Code: Select all

diff -C 3 -b -w -B -E -d -t -r -N -- lwip-1.3.1/src/core/ipv4/icmp.c lwip-1.3.1-st/src/core/ipv4/icmp.c
*** lwip-1.3.1/src/core/ipv4/icmp.c   Tue Aug 18 14:54:17 2009
--- lwip-1.3.1-st/src/core/ipv4/icmp.c   Fri Nov 20 17:07:14 2009
***************
*** 189,200 ****
--- 189,209 ----
      iphdr->src.addr = iphdr->dest.addr;
      iphdr->dest.addr = tmpaddr.addr;
      ICMPH_TYPE_SET(iecho, ICMP_ER);
+     
+
+ /* This part of code has been modified by ST's MCD Application Team */
+ /* To use the Checksum Offload Engine for the putgoing ICMP packets,
+    the ICMP checksum field should be set to 0, this is required only for Tx ICMP*/
+ #ifdef CHECKSUM_BY_HARDWARE
+     iecho->chksum = 0;
+ #else   
          /* adjust the checksum */
      if (iecho->chksum >= htons(0xffff - (ICMP_ECHO << 8))) {
        iecho->chksum += htons(ICMP_ECHO << 8) + 1;
      } else {
        iecho->chksum += htons(ICMP_ECHO << 8);
      }   
+ #endif
 
      /* Set the correct TTL and recalculate the header checksum. */
      IPH_TTL_SET(iphdr, ICMP_TTL);


Some further googling I found this PDF: http://www.st.com/internet/com/TECHNICA ... 255062.pdf

With lwIP, you can disable software generation and checksum verification for the IP, UDP
and TCP protocols. In the current port, this is done in the lwipopts.h file. For the ICMP,
however, it is necessary to modify the icmp.c file to disable checksum calculation.

mabl
Posts: 417
Joined: Tue Dec 21, 2010 10:19 am
Location: Karlsruhe, Germany
Been thanked: 1 time
Contact:

Re: STM32 Ethernet Demo

Postby mabl » Fri Oct 07, 2011 9:06 am

I updated the ethernet wrapper to check for link state. It's an ugly hack and somewhen it should really be replaced by a proper ChibiOS driver. (I saw that there is some work in the repository already). This driver should work with the most recent ChibiOS trunk and was tested with revision 3425.
Attachments
stm32_eth.zip
(38.7 KiB) Downloaded 356 times

User avatar
Giovanni
Site Admin
Posts: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

Re: STM32 Ethernet Demo

Postby Giovanni » Sat Oct 08, 2011 10:18 am

Thanks for the update.

The Ethernet code for STM32 is not yet ready and I don't know yet if it will be included in 2.4.x, there are still I2C and USB to finalize first.

Giovanni

mabl
Posts: 417
Joined: Tue Dec 21, 2010 10:19 am
Location: Karlsruhe, Germany
Been thanked: 1 time
Contact:

Re: STM32 Ethernet Demo

Postby mabl » Mon Oct 10, 2011 3:34 pm

I wished you'd have your proper code ready yet...

I ran into a strange problem and wonder if anybody has experienced similar problems:
I have a SNTP server running which queries the time from my laptop every 5 seconds or so. Everything seems to work fine but sometimes the MAC does not send the outgoing UDP packages anymore. The lwip trace is

Code: Select all

sntp_send_request: Sending request to server
udp_send
pbuf_header: old p new p (536910916)
udp_send: added header in given pbuf p
udp_send: sending datagram of length 56
udp_send: UDP packet length 56
udp_send: UDP checksum 0x   0
udp_send: ip_output_if (,,,,IP_PROTO_UDP,)
pbuf_header: old p new p (536910908)
ip_output_if: ms0
IP header:
+-------------------------------+
| 4 | 5 |  0x 0 |        76     | (v, hl, tos, len)
+-------------------------------+
|       68      |000|       0   | (id, flags, offset)
+-------------------------------+
|  255  |   17  |    0x   0     | (ttl, proto, chksum)
+-------------------------------+
|  172  |   16  |    0  |   21  | (src)
+-------------------------------+
|  172  |   16  |    0  |  168  | (dest)
+-------------------------------+
netif->output()pbuf_header: old p new p (536910888)
etharp_send_ip: sending packet p
pbuf_free(p)
pbuf_free: deallocating p


And looks the same as when the packages are still sent, also low_level_output in lwipthread.c is still called and executed successfully. Now, it continues to not work until I ping the board - at which point things magically start to work again!

I guess I'll have to dig through the MAC registers and all the ugly ST source code :(

EDIT:
When the execution is stalled the ETH_DMASR has the TS, TBUS, ETS set. So it might be some kind of DMA problem.

EDIT2:
Basically what happens is that the current Tx buffer doesnt get cleared and therefore always does a
if ((mdp->Status & ETH_DMATxDesc_OWN) != (uint32_t)RESET) return RDY_TIMEOUT; in max_lld_get_transmit_descriptor.

I am a real newbie to this ethernet mac stuff, so I don't understand the whole code. First, where does DMATxDescToSet get updated to the next current descriptor? I tried the following code in mac_lld_release_transmit_descriptor

Code: Select all

    /* Selects the next DMA Tx descriptor list for next buffer read */
    DMATxDescToSet = (ETH_DMADESCTypeDef*) (DMAPTPTxDescToSet->Buffer2NextDescAddr);
    if(DMAPTPTxDescToSet->Status != 0){
      DMAPTPTxDescToSet = (ETH_DMADESCTypeDef*) (DMAPTPTxDescToSet->Status);
    }
    else{
      DMAPTPTxDescToSet++;
    }

but this makes to driver fail completely.

Also there is the following code in mac_lld_release_transmit_descriptor

Code: Select all

  /* Clear unavailable flag & resume transmission */
  //TODO: the following check for DMASR_TBUS doesn't work
//if ((ETH->DMASR & ETH_DMASR_TBUS) != (uint32_t)RESET) {
    ETH->DMASR = ETH_DMASR_TBUS;
    ETH->DMATPDR = 0;
//}

The todo says it all - but from reading the parts of the documentation it should work with the if. I cannot figure out why the driver stops working with the enabled if branch. I do not understand why I need to do a ETH->DMASR = ETH_DMASR_TBUS; though.

Hmm probably time to go to bed...

brian360
Posts: 27
Joined: Wed Dec 08, 2010 5:47 pm
Location: Seattle, WA, USA

Re: STM32 Ethernet Demo

Postby brian360 » Tue Oct 18, 2011 10:52 pm

mabl wrote:I updated the ethernet wrapper to check for link state. It's an ugly hack and somewhen it should really be replaced by a proper ChibiOS driver. (I saw that there is some work in the repository already). This driver should work with the most recent ChibiOS trunk and was tested with revision 3425.


Thanks for your work on this. I've just based my link polling code on this, but have a question with how you inform the lwip stack of link up/down events. My understanding is that netif_set_link_up(struct netif *) and netif_set_link_down(struct netif *) must be called when a link change event occurs. Furthermore, those two functions must be called from the tcpip thread context; it would be dangerous to call them from the 'lwipthread' loop.

Are you also doing this by chance?

mabl
Posts: 417
Joined: Tue Dec 21, 2010 10:19 am
Location: Karlsruhe, Germany
Been thanked: 1 time
Contact:

Re: STM32 Ethernet Demo

Postby mabl » Wed Oct 19, 2011 7:34 am

Hello Brian,

Interesting, I did not notice that, as I assumed that this would be done by an upper layer, specifically the lwipthread.c adapter code. And indeed there is the following code in it:

Code: Select all

  while (TRUE) {
    eventmask_t mask = chEvtWaitAny(ALL_EVENTS);
    if (mask & PERIODIC_TIMER_ID)
      (void) macPollLinkStatus(&ETH1);


But this does only check the interface and might bring it up again. We should probably check for a changed state and notify lwip from there. Now, you are right that this has to be done from the tcp_tread context so we will have to use tcpip_callback_with_block.

Maybe Giovanni knows of a reason why this is missing in the current implementation?

EDIT:
I propose to replace the code above with

Code: Select all

    eventmask_t mask = chEvtWaitAny(ALL_EVENTS);
    if (mask & PERIODIC_TIMER_ID) {
      bool_t current_link_status;
      current_link_status = macPollLinkStatus(&ETH1);

      if (current_link_status != netif_is_link_up(&thisif)){
        if (current_link_status)
          tcpip_callback_with_block( (tcpip_callback_fn) netif_set_link_up, &thisif, 0);
        else
          tcpip_callback_with_block( (tcpip_callback_fn) netif_set_link_down, &thisif, 0);
      }

User avatar
Giovanni
Site Admin
Posts: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

Re: STM32 Ethernet Demo

Postby Giovanni » Wed Oct 19, 2011 8:15 am

Hi,

The lwip thread started as demo code, that's why. I wasn't aware that lwIP needed to be notified of a state change. Probably the change should be integrated in the trunk.

The idea is to make lwipthread a supported component (located in ./os/various), so please collect all the requirements.

Giovanni

mabl
Posts: 417
Joined: Tue Dec 21, 2010 10:19 am
Location: Karlsruhe, Germany
Been thanked: 1 time
Contact:

Re: STM32 Ethernet Demo

Postby mabl » Wed Oct 19, 2011 8:29 am

Hi Giovanni,

i think it's a great idea to move it into os/various.

I also found something which might be of interest to you: http://lwip.wikia.com/wiki/Writing_a_device_driver
There is also a chapter about zero copy implementations.

What's about the STM32 MAC driver? Do you have any timetable on that? I thought about trying to extend it a bit but I don't want to do duplicate work. Also, my semester just started again, so there is only spare time in the evenings...

User avatar
Giovanni
Site Admin
Posts: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

Re: STM32 Ethernet Demo

Postby Giovanni » Wed Oct 19, 2011 8:51 am

Thanks for the link, it looks interesting.

About the STM32 Ethernet driver, it is frozen right now, I need to complete several other tasks first:
- USB driver revision.
- I2C driver model finalization.
- STM32 F2/F4 official support (with STM32F4-Discovery demo, those are proving very popular).
- Yet another documentation improvement/revision cycle.

I don't know if it will make it into 2.4.0 so it is a good idea to optimize and stabilize the wrapper driver, if it is reasonably reliable it could be included in ./ext.

Giovanni

santatanta
Posts: 8
Joined: Fri Jul 22, 2011 11:13 am

Re: STM32 Ethernet Demo

Postby santatanta » Fri Oct 21, 2011 11:52 am

Hello mabl,

I don't know if this is linked to your problem, but in my simple UDP echo application (using the raw API), the second transfer after reset is lost:

I get the echo response for the first packet after reset
I do NOT get the echo response for the second packet after reset
I get the echo response for all further packets

It's not a big problem because the application should always be aware that UDP packets might get lost, but it's a little bit strange.


Return to “Development and Feedback”

Who is online

Users browsing this forum: No registered users and 34 guests