Page 24 of 26
Re: STM32 Ethernet Demo
Posted: Wed Jan 02, 2013 5:13 pm
by iggarpe
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.
Re: STM32 Ethernet Demo
Posted: Wed Jan 02, 2013 5:18 pm
by iggarpe
[email protected] 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=845If 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

Re: STM32 Ethernet Demo
Posted: Wed Jan 02, 2013 5:22 pm
by mabl
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.
Re: STM32 Ethernet Demo
Posted: Thu Jan 03, 2013 10:34 am
by rubenswerk
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);
}
}
}
}
Re: STM32 Ethernet Demo
Posted: Thu Jan 03, 2013 10:51 am
by mabl
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".
Re: STM32 Ethernet Demo
Posted: Thu Jan 03, 2013 11:28 pm
by DeusExMachina
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.
Re: STM32 Ethernet Demo
Posted: Fri Jan 04, 2013 8:37 am
by Giovanni
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
Re: STM32 Ethernet Demo
Posted: Fri Jan 04, 2013 8:45 pm
by DeusExMachina
Thanks, I'll try.
Re: STM32 Ethernet Demo
Posted: Sat Jan 05, 2013 12:35 am
by DeusExMachina
Success

Now there is more complicated web server using F4 discovery & PHY DP83848
Re: STM32 Ethernet Demo
Posted: Thu Jan 10, 2013 1:14 pm
by rubenswerk
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