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.
iggarpe
Posts: 129
Joined: Sun Sep 30, 2012 8:32 pm

Re: STM32 Ethernet Demo

Postby iggarpe » Wed Jan 02, 2013 5:13 pm

You are using the lwip RAW API, which is forbidden when using LwIp with an operating system. You have to use netconn or sockets.


I think it is the other way around. The RAW API is the only one usable without an OS, because it does not require threads and synchronization stuff, but of course can be used with a OS (as I'm doing to keep the memory usage and number of threads low). However, forces you to implement everything as a state machine, which is quite cumbersome in most cases. The netconn and socket APIs are easier to use but require threads, and thus an OS.

iggarpe
Posts: 129
Joined: Sun Sep 30, 2012 8:32 pm

Re: STM32 Ethernet Demo

Postby iggarpe » Wed Jan 02, 2013 5:18 pm

nannou9@gmail.com wrote:In all cases the problem was exacly same: it is working fluently for ex. 10 seconds, then for 5 secs. nothing (pocket loss), again ok for some seconds, then again nothing form some seconds and all over again.
When everything is working ok- no packet loss (20s max), then it is working very fast.

I have tested it using the latest trunk of Chibios/RT and both LWIP 1.4.0 and .1.4.1. Whatever i do i am having very same problem: pocket flood, nothing, pocket flood, nothing......


Is this the problem that was discussed in the support forum? (where the problem was due to bad signal integrity in the connection from the STM32F4DISCOVERY board and the PHY).

viewtopic.php?f=2&t=845

If it is, it would be nice to add a closing comment in this thread stating that the problem is solved and a link to it.

Oh, wait, I just did :-)

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 Jan 02, 2013 5:22 pm

iggarpe wrote:
You are using the lwip RAW API, which is forbidden when using LwIp with an operating system. You have to use netconn or sockets.


I think it is the other way around. The RAW API is the only one usable without an OS, because it does not require threads and synchronization stuff, but of course can be used with a OS (as I'm doing to keep the memory usage and number of threads low). However, forces you to implement everything as a state machine, which is quite cumbersome in most cases. The netconn and socket APIs are easier to use but require threads, and thus an OS.

The lwip code was written with no thread safety in mind. Later this code was encapsulated in a worker thread - aka. the "tcpip-thread". I'm convinced you will get into trouble using the RAW API. You can only use it via messages to the tcpip-thread. I'd be glad to be convinced otherwise, since I also made the error of writing a NTP client in RAW api once.

rubenswerk
Posts: 104
Joined: Wed Feb 22, 2012 11:39 am
Location: Austria

Re: STM32 Ethernet Demo

Postby rubenswerk » Thu Jan 03, 2013 10:34 am

Interesting hint. I'm using the raw API for several month now and exchanged billions of UDP packets.
My architecture is quite simple - at the end of the udp_recv callback function, I'm sending a reply using udp_sendto(). I never do any asynchronous sends. This works fine for my project. However, I experienced problems using FATFS in parallel with Ethernet communication. I don't know if this is caused by using the raw API.

I assume that my udp_recv callback is running in the context of the lwip_thread, because all packet processing is done there:

Code: Select all

  while (TRUE) {
    eventmask_t mask = chEvtWaitAny(ALL_EVENTS);
    if (mask & FRAME_RECEIVED_ID) {
      while ((p = low_level_input(&lumax_thisif)) != NULL) {
        case ETHTYPE_IP:
        case ETHTYPE_ARP:
          /* full packet send to tcpip_thread to process */
          if (lumax_thisif.input(p, &lumax_thisif) == ERR_OK)
            break;
        default:
          pbuf_free(p);
        }
      }
    }
  }

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 Jan 03, 2013 10:51 am

Hello rubenswerk,

rubenswerk wrote:I assume that my udp_recv callback is running in the context of the lwip_thread, because all packet processing is done there[..]

This is not correct.

In ChibiOS, the interface is defined in "os/various/lwip_bindings/lwipthread.c" as

Code: Select all

netif_add(&thisif, &ip, &netmask, &gateway, NULL, ethernetif_init, tcpip_input);


where tcpip_input passes the package as synchronous message to the "tcpip_thread", which is the worker thread I talked about. In this mode (a.k.a. NO_SYS=0 in lwip), calls to the RAW api may only be done from this worker thread. You can tell the worker to call a RAW API fuction via tcpip_callback_with_block, I think.

In you case it probably works quite stable, since you send your UDP answer back in the callback context - which is from the "tcpip_thread".

User avatar
DeusExMachina
Posts: 223
Joined: Tue Apr 03, 2012 5:08 am
Location: South Korea
Has thanked: 3 times
Been thanked: 3 times

Re: STM32 Ethernet Demo

Postby DeusExMachina » Thu Jan 03, 2013 11:28 pm

I have successfully ported ST netconn demo from AN3966 "LwIP TCP/IP stack demonstration for STM32F407/STM32F417 microcontrollers". There is one issue - I don't know how to get running threads list (common to vTaskList in FreeRTOS) to show in dynamic page.

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 » Fri Jan 04, 2013 8:37 am

Hi,

You have to use the "registry", this is an example:

Code: Select all

  chprintf(chp, "    addr    stack prio refs     state time\r\n");
  tp = chRegFirstThread();
  do {
    chprintf(chp, "%.8lx %.8lx %4lu %4lu %9s %lu\r\n",
            (uint32_t)tp, (uint32_t)tp->p_ctx.r13,
            (uint32_t)tp->p_prio, (uint32_t)(tp->p_refs - 1),
            states[tp->p_state], (uint32_t)tp->p_time);
    tp = chRegNextThread(tp);
  } while (tp != NULL);


Giovanni

User avatar
DeusExMachina
Posts: 223
Joined: Tue Apr 03, 2012 5:08 am
Location: South Korea
Has thanked: 3 times
Been thanked: 3 times

Re: STM32 Ethernet Demo

Postby DeusExMachina » Fri Jan 04, 2013 8:45 pm

Thanks, I'll try.

User avatar
DeusExMachina
Posts: 223
Joined: Tue Apr 03, 2012 5:08 am
Location: South Korea
Has thanked: 3 times
Been thanked: 3 times

Re: STM32 Ethernet Demo

Postby DeusExMachina » Sat Jan 05, 2013 12:35 am

Success :) Now there is more complicated web server using F4 discovery & PHY DP83848
Attachments
sht.png
sht.png (73.38 KiB) Viewed 6004 times

rubenswerk
Posts: 104
Joined: Wed Feb 22, 2012 11:39 am
Location: Austria

Re: STM32 Ethernet Demo

Postby rubenswerk » Thu Jan 10, 2013 1:14 pm

Hello,

at the moment, an old problem came up again: one of my boards sometimes crashes when using my UDP communication. In the past, it was always the same board (I have 3 in total), and it took lots of communication cycles until it crashed. Now, another board (which was running with the same software just fine until now) crashes in the moment when I send the first UDP packet to my receive callback function. However, pings are replied just fine.

So I remembered Mabl's hint and I'm thinking of switching to the netconn API. After reading the lwip wiki I'm still not sure if the way I use the raw API is forbidden in an OS environment. However, I think it's worth a try to use the recommended netconn API.

Can you give me some architectural hints about that?

This is how I would try:
1. instead of using the raw API UDP callback function, create a new thread with an endless loop, waiting for UDP packets using netconn_recv(conn,&buf);
2. the lwip_thread from the ehernet demo remains unchanged
3. what should be the netconn thread priority in comparison to the lwip_thread?
4. will there be increased latency compared to a callback function? netconn_recv is a blocking function, which needs to be notified by the lwip kernel. I know it's possible to define a callback also for netconn, but I couldn't find examples for that and I think a thread is the better design choice if the performance/latency is similar.
5. should the netconn setup (netconn_new, netconn_bind) be done in the main function before starting the netconn thread? Functions like netif_add are not thread safe. However, I hope that all netconn_xxx functions ARE thread safe.

Is this the correct approach?

Thanks, RuWe


Return to “Development and Feedback”

Who is online

Users browsing this forum: No registered users and 27 guests