lwIP Wiki
Register
m (grammatical correction)
(add timer info)
Line 8: Line 8:
   
 
* <code>ip_input(pbuf, netif)</code><nowiki>: Takes an IP packet and the incoming network interface as arguments and does the TCP/IP processing for the packet. </nowiki>
 
* <code>ip_input(pbuf, netif)</code><nowiki>: Takes an IP packet and the incoming network interface as arguments and does the TCP/IP processing for the packet. </nowiki>
* <code>tcp_tmr()</code><nowiki>: Should be called every 250 ms. Does all TCP timer processing such as doing retransmissions. </nowiki>
+
* <code>tcp_tmr()</code><nowiki>: Should be called every 250 ms (=TCP_TMR_INTERVAL). Does all TCP timer processing such as doing retransmissions. </nowiki>
   
 
Because none of the core functions ever needs to block when run in a single-threaded environment, a sys_arch (operating system abstraction layer) implementation is not needed (and semaphore and mailbox functions are stub definitions only).
 
Because none of the core functions ever needs to block when run in a single-threaded environment, a sys_arch (operating system abstraction layer) implementation is not needed (and semaphore and mailbox functions are stub definitions only).
Line 24: Line 24:
 
last_arp_time = clock();
 
last_arp_time = clock();
 
}
 
}
if(clock() - last_time >= 250 * CLOCK_MS) {
+
if(clock() - last_time >= TCP_TMR_INTERVAL * CLOCK_MS) {
 
tcp_tmr();
 
tcp_tmr();
 
last_time = clock();
 
last_time = clock();
 
}
 
}
 
}
 
}
  +
  +
In case you use more than just TCP/IP and ARP, you might need to add more calls to timers. In a multi-threaded system all these timers are called from <code>api/tcpip.c</code>, so this source file is a good place to check if you need to call any more timers (like IP_REASSEMBLY, DHCP, etc.). Hint: Both in <code>api/tcpip.c</code> and the examples above, the timers do not "catch up". That means if one timer tick is delayed (for whatever reason), all following timer ticks will be delayed, too.
   
 
==lwIP in a multi-threaded system ==
 
==lwIP in a multi-threaded system ==
Line 38: Line 40:
 
When run in a multi-threaded environment, incoming packets are handled by the function <code>tcpip_input()</code> (or alternatively <code>tcpip_ethinput()</code>), which takes the same arguments as the <code>ip_input()</code> function. The difference between the two functions is that the <code>tcpip_input()</code> function does not process the incoming packet immediately. It merely puts the packet on a queue which later is drained by the TCP/IP thread.
 
When run in a multi-threaded environment, incoming packets are handled by the function <code>tcpip_input()</code> (or alternatively <code>tcpip_ethinput()</code>), which takes the same arguments as the <code>ip_input()</code> function. The difference between the two functions is that the <code>tcpip_input()</code> function does not process the incoming packet immediately. It merely puts the packet on a queue which later is drained by the TCP/IP thread.
   
When being run in a multi-threaded system, timer events are taken care of internally in <tt>tcpip.c</tt>.
+
When being run in a multi-threaded system, timer events are taken care of internally in <tt>tcpip.c</tt>.[[category:LwIP Application Developers Manual]]
[[category:LwIP Application Developers Manual]]
 

Revision as of 10:53, 17 April 2009

There has been a few questions about how lwIP can be used in a standalone environment (i.e., an environment without a multi-threaded operating system) lately. The purpose of this document is to describe how lwIP is designed to be used with and without a multi-threaded operating system.

The lwIP single-threaded core

The core of lwIP consists of the actual implementations of the IP, ICMP, UDP, and TCP protocols, as well as support functions such as buffer and memory management. The core components are the only ones that are needed when lwIP is to be run in a single-threaded (non-OS) environment.

The core components can be viewed as a software library which has the following interface:

  • ip_input(pbuf, netif): Takes an IP packet and the incoming network interface as arguments and does the TCP/IP processing for the packet.
  • tcp_tmr(): Should be called every 250 ms (=TCP_TMR_INTERVAL). Does all TCP timer processing such as doing retransmissions.

Because none of the core functions ever needs to block when run in a single-threaded environment, a sys_arch (operating system abstraction layer) implementation is not needed (and semaphore and mailbox functions are stub definitions only).

A simple main loop for a single-threaded system might look like this:

 while(1) {
   if(poll_driver(netif) == PACKET_READY) {
     pbuf = get_packet(netif);
     ip_input(pbuf, netif);
   }
   if (clock() - last_arp_time >= ARP_TMR_INTERVAL * CLOCK_MS)
   {
       etharp_tmr();
       last_arp_time = clock();
   }
   if(clock() - last_time >= TCP_TMR_INTERVAL * CLOCK_MS) {
     tcp_tmr();
     last_time = clock();
   }    
 }

In case you use more than just TCP/IP and ARP, you might need to add more calls to timers. In a multi-threaded system all these timers are called from api/tcpip.c, so this source file is a good place to check if you need to call any more timers (like IP_REASSEMBLY, DHCP, etc.). Hint: Both in api/tcpip.c and the examples above, the timers do not "catch up". That means if one timer tick is delayed (for whatever reason), all following timer ticks will be delayed, too.

lwIP in a multi-threaded system

lwIP is designed to be able to be run in a multi-threaded system with applications running in concurrent threads. The model used in this case is that all TCP/IP processing is done in a single thread. The application thread communicates with the TCP/IP thread using the sequential API.

The inter-thread communication is implemented in the two files api_lib.c and api_msg.c. The former contains the functions used by the application programs and the latter implements the TCP/IP stack interface. A third file, tcpip.c, handles incoming packets and timer events as described in the previous section.

When run in a multi-threaded environment, incoming packets are handled by the function tcpip_input() (or alternatively tcpip_ethinput()), which takes the same arguments as the ip_input() function. The difference between the two functions is that the tcpip_input() function does not process the incoming packet immediately. It merely puts the packet on a queue which later is drained by the TCP/IP thread.

When being run in a multi-threaded system, timer events are taken care of internally in tcpip.c.