xref: /nrf52832-nimble/rt-thread/components/net/lwip-2.1.0/doc/doxygen/main_page.h (revision 104654410c56c573564690304ae786df310c91fc)
1*10465441SEvalZero /**
2*10465441SEvalZero  * @defgroup lwip lwIP
3*10465441SEvalZero  *
4*10465441SEvalZero  * @defgroup infrastructure Infrastructure
5*10465441SEvalZero  *
6*10465441SEvalZero  * @defgroup api APIs
7*10465441SEvalZero  * lwIP provides three Application Program's Interfaces (APIs) for programs
8*10465441SEvalZero  * to use for communication with the TCP/IP code:
9*10465441SEvalZero  * - low-level "core" / "callback" or @ref callbackstyle_api.
10*10465441SEvalZero  * - higher-level @ref sequential_api.
11*10465441SEvalZero  * - BSD-style @ref socket.
12*10465441SEvalZero  *
13*10465441SEvalZero  * The raw TCP/IP interface allows the application program to integrate
14*10465441SEvalZero  * better with the TCP/IP code. Program execution is event based by
15*10465441SEvalZero  * having callback functions being called from within the TCP/IP
16*10465441SEvalZero  * code. The TCP/IP code and the application program both run in the same
17*10465441SEvalZero  * thread. The sequential API has a much higher overhead and is not very
18*10465441SEvalZero  * well suited for small systems since it forces a multithreaded paradigm
19*10465441SEvalZero  * on the application.
20*10465441SEvalZero  *
21*10465441SEvalZero  * The raw TCP/IP interface is not only faster in terms of code execution
22*10465441SEvalZero  * time but is also less memory intensive. The drawback is that program
23*10465441SEvalZero  * development is somewhat harder and application programs written for
24*10465441SEvalZero  * the raw TCP/IP interface are more difficult to understand. Still, this
25*10465441SEvalZero  * is the preferred way of writing applications that should be small in
26*10465441SEvalZero  * code size and memory usage.
27*10465441SEvalZero  *
28*10465441SEvalZero  * All APIs can be used simultaneously by different application
29*10465441SEvalZero  * programs. In fact, the sequential API is implemented as an application
30*10465441SEvalZero  * program using the raw TCP/IP interface.
31*10465441SEvalZero  *
32*10465441SEvalZero  * Do not confuse the lwIP raw API with raw Ethernet or IP sockets.
33*10465441SEvalZero  * The former is a way of interfacing the lwIP network stack (including
34*10465441SEvalZero  * TCP and UDP), the latter refers to processing raw Ethernet or IP data
35*10465441SEvalZero  * instead of TCP connections or UDP packets.
36*10465441SEvalZero  *
37*10465441SEvalZero  * Raw API applications may never block since all packet processing
38*10465441SEvalZero  * (input and output) as well as timer processing (TCP mainly) is done
39*10465441SEvalZero  * in a single execution context.
40*10465441SEvalZero  *
41*10465441SEvalZero  * @defgroup callbackstyle_api "raw" APIs
42*10465441SEvalZero  * @ingroup api
43*10465441SEvalZero  * Non thread-safe APIs, callback style for maximum performance and minimum
44*10465441SEvalZero  * memory footprint.
45*10465441SEvalZero  * Program execution is driven by callbacks functions, which are then
46*10465441SEvalZero  * invoked by the lwIP core when activity related to that application
47*10465441SEvalZero  * occurs. A particular application may register to be notified via a
48*10465441SEvalZero  * callback function for events such as incoming data available, outgoing
49*10465441SEvalZero  * data sent, error notifications, poll timer expiration, connection
50*10465441SEvalZero  * closed, etc. An application can provide a callback function to perform
51*10465441SEvalZero  * processing for any or all of these events. Each callback is an ordinary
52*10465441SEvalZero  * C function that is called from within the TCP/IP code. Every callback
53*10465441SEvalZero  * function is passed the current TCP or UDP connection state as an
54*10465441SEvalZero  * argument. Also, in order to be able to keep program specific state,
55*10465441SEvalZero  * the callback functions are called with a program specified argument
56*10465441SEvalZero  * that is independent of the TCP/IP state.
57*10465441SEvalZero  * The raw API (sometimes called native API) is an event-driven API designed
58*10465441SEvalZero  * to be used without an operating system that implements zero-copy send and
59*10465441SEvalZero  * receive. This API is also used by the core stack for interaction between
60*10465441SEvalZero  * the various protocols. It is the only API available when running lwIP
61*10465441SEvalZero  * without an operating system.
62*10465441SEvalZero  *
63*10465441SEvalZero  * @defgroup sequential_api Sequential-style APIs
64*10465441SEvalZero  * @ingroup api
65*10465441SEvalZero  * Sequential-style APIs, blocking functions. More overhead, but can be called
66*10465441SEvalZero  * from any thread except TCPIP thread.
67*10465441SEvalZero  * The sequential API provides a way for ordinary, sequential, programs
68*10465441SEvalZero  * to use the lwIP stack. It is quite similar to the BSD socket API. The
69*10465441SEvalZero  * model of execution is based on the blocking open-read-write-close
70*10465441SEvalZero  * paradigm. Since the TCP/IP stack is event based by nature, the TCP/IP
71*10465441SEvalZero  * code and the application program must reside in different execution
72*10465441SEvalZero  * contexts (threads).
73*10465441SEvalZero  *
74*10465441SEvalZero  * @defgroup socket Socket API
75*10465441SEvalZero  * @ingroup api
76*10465441SEvalZero  * BSD-style socket API.\n
77*10465441SEvalZero  * Thread-safe, to be called from non-TCPIP threads only.\n
78*10465441SEvalZero  * Can be activated by defining @ref LWIP_SOCKET to 1.\n
79*10465441SEvalZero  * Header is in posix/sys/socket.h\n
80*10465441SEvalZero  * The socket API is a compatibility API for existing applications,
81*10465441SEvalZero  * currently it is built on top of the sequential API. It is meant to
82*10465441SEvalZero  * provide all functions needed to run socket API applications running
83*10465441SEvalZero  * on other platforms (e.g. unix / windows etc.). However, due to limitations
84*10465441SEvalZero  * in the specification of this API, there might be incompatibilities
85*10465441SEvalZero  * that require small modifications of existing programs.
86*10465441SEvalZero  *
87*10465441SEvalZero  * @defgroup netifs NETIFs
88*10465441SEvalZero  *
89*10465441SEvalZero  * @defgroup apps Applications
90*10465441SEvalZero  */
91*10465441SEvalZero 
92*10465441SEvalZero /**
93*10465441SEvalZero  * @mainpage Overview
94*10465441SEvalZero  * @verbinclude "README"
95*10465441SEvalZero  */
96*10465441SEvalZero 
97*10465441SEvalZero /**
98*10465441SEvalZero  * @page upgrading Upgrading
99*10465441SEvalZero  * @verbinclude "UPGRADING"
100*10465441SEvalZero  */
101*10465441SEvalZero 
102*10465441SEvalZero /**
103*10465441SEvalZero  * @page changelog Changelog
104*10465441SEvalZero  *
105*10465441SEvalZero  * 2.1.0
106*10465441SEvalZero  * -----
107*10465441SEvalZero  * * Support TLS via new @ref altcp_api connection API (https, smtps, mqtt over TLS)
108*10465441SEvalZero  * * Switch to cmake as the main build system (Makefile file lists are still
109*10465441SEvalZero  *   maintained for now)
110*10465441SEvalZero  * * Improve IPv6 support: support address scopes, support stateless DHCPv6, bugfixes
111*10465441SEvalZero  * * Add debug helper asserts to ensure threading/locking requirements are met
112*10465441SEvalZero  * * Add sys_mbox_trypost_fromisr() and tcpip_callbackmsg_trycallback_fromisr()
113*10465441SEvalZero  *   (for FreeRTOS, mainly)
114*10465441SEvalZero  * * socket API: support poll(), sendmsg() and recvmsg(); fix problems on close
115*10465441SEvalZero  *
116*10465441SEvalZero  * Detailed Changelog
117*10465441SEvalZero  * ------------------
118*10465441SEvalZero  * @verbinclude "CHANGELOG"
119*10465441SEvalZero  */
120*10465441SEvalZero 
121*10465441SEvalZero /**
122*10465441SEvalZero  * @page contrib How to contribute to lwIP
123*10465441SEvalZero  * @verbinclude "contrib.txt"
124*10465441SEvalZero  */
125*10465441SEvalZero 
126*10465441SEvalZero /**
127*10465441SEvalZero  * @page pitfalls Common pitfalls
128*10465441SEvalZero  *
129*10465441SEvalZero  * Multiple Execution Contexts in lwIP code
130*10465441SEvalZero  * ========================================
131*10465441SEvalZero  *
132*10465441SEvalZero  * The most common source of lwIP problems is to have multiple execution contexts
133*10465441SEvalZero  * inside the lwIP code.
134*10465441SEvalZero  *
135*10465441SEvalZero  * lwIP can be used in two basic modes: @ref lwip_nosys (no OS/RTOS
136*10465441SEvalZero  * running on target system) or @ref lwip_os (there is an OS running
137*10465441SEvalZero  * on the target system).
138*10465441SEvalZero  *
139*10465441SEvalZero  * See also: @ref multithreading (especially the part about @ref LWIP_ASSERT_CORE_LOCKED()!)
140*10465441SEvalZero  *
141*10465441SEvalZero  * Mainloop Mode
142*10465441SEvalZero  * -------------
143*10465441SEvalZero  * In mainloop mode, only @ref callbackstyle_api can be used.
144*10465441SEvalZero  * The user has two possibilities to ensure there is only one
145*10465441SEvalZero  * exection context at a time in lwIP:
146*10465441SEvalZero  *
147*10465441SEvalZero  * 1) Deliver RX ethernet packets directly in interrupt context to lwIP
148*10465441SEvalZero  *    by calling netif->input directly in interrupt. This implies all lwIP
149*10465441SEvalZero  *    callback functions are called in IRQ context, which may cause further
150*10465441SEvalZero  *    problems in application code: IRQ is blocked for a long time, multiple
151*10465441SEvalZero  *    execution contexts in application code etc. When the application wants
152*10465441SEvalZero  *    to call lwIP, it only needs to disable interrupts during the call.
153*10465441SEvalZero  *    If timers are involved, even more locking code is needed to lock out
154*10465441SEvalZero  *    timer IRQ and ethernet IRQ from each other, assuming these may be nested.
155*10465441SEvalZero  *
156*10465441SEvalZero  * 2) Run lwIP in a mainloop. There is example code here: @ref lwip_nosys.
157*10465441SEvalZero  *    lwIP is _ONLY_ called from mainloop callstacks here. The ethernet IRQ
158*10465441SEvalZero  *    has to put received telegrams into a queue which is polled in the
159*10465441SEvalZero  *    mainloop. Ensure lwIP is _NEVER_ called from an interrupt, e.g.
160*10465441SEvalZero  *    some SPI IRQ wants to forward data to udp_send() or tcp_write()!
161*10465441SEvalZero  *
162*10465441SEvalZero  * OS Mode
163*10465441SEvalZero  * -------
164*10465441SEvalZero  * In OS mode, @ref callbackstyle_api AND @ref sequential_api can be used.
165*10465441SEvalZero  * @ref sequential_api are designed to be called from threads other than
166*10465441SEvalZero  * the TCPIP thread, so there is nothing to consider here.
167*10465441SEvalZero  * But @ref callbackstyle_api functions must _ONLY_ be called from
168*10465441SEvalZero  * TCPIP thread. It is a common error to call these from other threads
169*10465441SEvalZero  * or from IRQ contexts. ​Ethernet RX needs to deliver incoming packets
170*10465441SEvalZero  * in the correct way by sending a message to TCPIP thread, this is
171*10465441SEvalZero  * implemented in tcpip_input().​​
172*10465441SEvalZero  * Again, ensure lwIP is _NEVER_ called from an interrupt, e.g.
173*10465441SEvalZero  * some SPI IRQ wants to forward data to udp_send() or tcp_write()!
174*10465441SEvalZero  *
175*10465441SEvalZero  * 1) tcpip_callback() can be used get called back from TCPIP thread,
176*10465441SEvalZero  *    it is safe to call any @ref callbackstyle_api from there.
177*10465441SEvalZero  *
178*10465441SEvalZero  * 2) Use @ref LWIP_TCPIP_CORE_LOCKING. All @ref callbackstyle_api
179*10465441SEvalZero  *    functions can be called when lwIP core lock is aquired, see
180*10465441SEvalZero  *    @ref LOCK_TCPIP_CORE() and @ref UNLOCK_TCPIP_CORE().
181*10465441SEvalZero  *    These macros cannot be used in an interrupt context!
182*10465441SEvalZero  *    Note the OS must correctly handle priority inversion for this.
183*10465441SEvalZero  *
184*10465441SEvalZero  * Cache / DMA issues
185*10465441SEvalZero  * ==================
186*10465441SEvalZero  *
187*10465441SEvalZero  * DMA-capable ethernet hardware and zero-copy RX
188*10465441SEvalZero  * ----------------------------------------------
189*10465441SEvalZero  *
190*10465441SEvalZero  * lwIP changes the content of RECEIVED pbufs in the TCP code path.
191*10465441SEvalZero  * This implies one or more cacheline(s) of the RX pbuf become dirty
192*10465441SEvalZero  * and need to be flushed before the memory is handed over to the
193*10465441SEvalZero  * DMA ethernet hardware for the next telegram to be received.
194*10465441SEvalZero  * See http://lists.nongnu.org/archive/html/lwip-devel/2017-12/msg00070.html
195*10465441SEvalZero  * for a more detailed explanation.
196*10465441SEvalZero  * Also keep in mind the user application may also write into pbufs,
197*10465441SEvalZero  * so it is generally a bug not to flush the data cache before handing
198*10465441SEvalZero  * a buffer to DMA hardware.
199*10465441SEvalZero  *
200*10465441SEvalZero  * DMA-capable ethernet hardware and cacheline alignment
201*10465441SEvalZero  * -----------------------------------------------------
202*10465441SEvalZero  * Nice description about DMA capable hardware and buffer handling:
203*10465441SEvalZero  * http://www.pebblebay.com/a-guide-to-using-direct-memory-access-in-embedded-systems-part-two/
204*10465441SEvalZero  * Read especially sections "Cache coherency" and "Buffer alignment".
205*10465441SEvalZero  */
206*10465441SEvalZero 
207*10465441SEvalZero /**
208*10465441SEvalZero  * @page bugs Reporting bugs
209*10465441SEvalZero  * Please report bugs in the lwIP bug tracker at savannah.\n
210*10465441SEvalZero  * BEFORE submitting, please check if the bug has already been reported!\n
211*10465441SEvalZero  * https://savannah.nongnu.org/bugs/?group=lwip
212*10465441SEvalZero  */
213*10465441SEvalZero 
214*10465441SEvalZero /**
215*10465441SEvalZero  * @page zerocopyrx Zero-copy RX
216*10465441SEvalZero  * The following code is an example for zero-copy RX ethernet driver:
217*10465441SEvalZero  * @include ZeroCopyRx.c
218*10465441SEvalZero  */
219*10465441SEvalZero 
220*10465441SEvalZero /**
221*10465441SEvalZero  * @defgroup lwip_nosys Mainloop mode ("NO_SYS")
222*10465441SEvalZero  * @ingroup lwip
223*10465441SEvalZero  * Use this mode if you do not run an OS on your system. \#define NO_SYS to 1.
224*10465441SEvalZero  * Feed incoming packets to netif->input(pbuf, netif) function from mainloop,
225*10465441SEvalZero  * *not* *from* *interrupt* *context*. You can allocate a @ref pbuf in interrupt
226*10465441SEvalZero  * context and put them into a queue which is processed from mainloop.\n
227*10465441SEvalZero  * Call sys_check_timeouts() periodically in the mainloop.\n
228*10465441SEvalZero  * Porting: implement all functions in @ref sys_time, @ref sys_prot and
229*10465441SEvalZero  * @ref compiler_abstraction.\n
230*10465441SEvalZero  * You can only use @ref callbackstyle_api in this mode.\n
231*10465441SEvalZero  * Sample code:\n
232*10465441SEvalZero  * @include NO_SYS_SampleCode.c
233*10465441SEvalZero  */
234*10465441SEvalZero 
235*10465441SEvalZero /**
236*10465441SEvalZero  * @defgroup lwip_os OS mode (TCPIP thread)
237*10465441SEvalZero  * @ingroup lwip
238*10465441SEvalZero  * Use this mode if you run an OS on your system. It is recommended to
239*10465441SEvalZero  * use an RTOS that correctly handles priority inversion and
240*10465441SEvalZero  * to use @ref LWIP_TCPIP_CORE_LOCKING.\n
241*10465441SEvalZero  * Porting: implement all functions in @ref sys_layer.\n
242*10465441SEvalZero  * You can use @ref callbackstyle_api together with @ref tcpip_callback,
243*10465441SEvalZero  * and all @ref sequential_api.
244*10465441SEvalZero  */
245*10465441SEvalZero 
246*10465441SEvalZero /**
247*10465441SEvalZero  * @page sys_init System initalization
248*10465441SEvalZero A truly complete and generic sequence for initializing the lwIP stack
249*10465441SEvalZero cannot be given because it depends on additional initializations for
250*10465441SEvalZero your runtime environment (e.g. timers).
251*10465441SEvalZero 
252*10465441SEvalZero We can give you some idea on how to proceed when using the raw API.
253*10465441SEvalZero We assume a configuration using a single Ethernet netif and the
254*10465441SEvalZero UDP and TCP transport layers, IPv4 and the DHCP client.
255*10465441SEvalZero 
256*10465441SEvalZero Call these functions in the order of appearance:
257*10465441SEvalZero 
258*10465441SEvalZero - lwip_init(): Initialize the lwIP stack and all of its subsystems.
259*10465441SEvalZero 
260*10465441SEvalZero - netif_add(struct netif *netif, ...):
261*10465441SEvalZero   Adds your network interface to the netif_list. Allocate a struct
262*10465441SEvalZero   netif and pass a pointer to this structure as the first argument.
263*10465441SEvalZero   Give pointers to cleared ip_addr structures when using DHCP,
264*10465441SEvalZero   or fill them with sane numbers otherwise. The state pointer may be NULL.
265*10465441SEvalZero 
266*10465441SEvalZero   The init function pointer must point to a initialization function for
267*10465441SEvalZero   your Ethernet netif interface. The following code illustrates its use.
268*10465441SEvalZero 
269*10465441SEvalZero @code{.c}
270*10465441SEvalZero   err_t netif_if_init(struct netif *netif)
271*10465441SEvalZero   {
272*10465441SEvalZero     u8_t i;
273*10465441SEvalZero 
274*10465441SEvalZero     for (i = 0; i < ETHARP_HWADDR_LEN; i++) {
275*10465441SEvalZero       netif->hwaddr[i] = some_eth_addr[i];
276*10465441SEvalZero     }
277*10465441SEvalZero     init_my_eth_device();
278*10465441SEvalZero     return ERR_OK;
279*10465441SEvalZero   }
280*10465441SEvalZero @endcode
281*10465441SEvalZero 
282*10465441SEvalZero   For Ethernet drivers, the input function pointer must point to the lwIP
283*10465441SEvalZero   function ethernet_input() declared in "netif/etharp.h". Other drivers
284*10465441SEvalZero   must use ip_input() declared in "lwip/ip.h".
285*10465441SEvalZero 
286*10465441SEvalZero - netif_set_default(struct netif *netif)
287*10465441SEvalZero   Registers the default network interface.
288*10465441SEvalZero 
289*10465441SEvalZero - netif_set_link_up(struct netif *netif)
290*10465441SEvalZero   This is the hardware link state; e.g. whether cable is plugged for wired
291*10465441SEvalZero   Ethernet interface. This function must be called even if you don't know
292*10465441SEvalZero   the current state. Having link up and link down events is optional but
293*10465441SEvalZero   DHCP and IPv6 discover benefit well from those events.
294*10465441SEvalZero 
295*10465441SEvalZero - netif_set_up(struct netif *netif)
296*10465441SEvalZero   This is the administrative (= software) state of the netif, when the
297*10465441SEvalZero   netif is fully configured this function must be called.
298*10465441SEvalZero 
299*10465441SEvalZero - dhcp_start(struct netif *netif)
300*10465441SEvalZero   Creates a new DHCP client for this interface on the first call.
301*10465441SEvalZero   You can peek in the netif->dhcp struct for the actual DHCP status.
302*10465441SEvalZero 
303*10465441SEvalZero - sys_check_timeouts()
304*10465441SEvalZero   When the system is running, you have to periodically call
305*10465441SEvalZero   sys_check_timeouts() which will handle all timers for all protocols in
306*10465441SEvalZero   the stack; add this to your main loop or equivalent.
307*10465441SEvalZero  */
308*10465441SEvalZero 
309*10465441SEvalZero /**
310*10465441SEvalZero  * @page multithreading Multithreading
311*10465441SEvalZero  * lwIP started targeting single-threaded environments. When adding multi-
312*10465441SEvalZero  * threading support, instead of making the core thread-safe, another
313*10465441SEvalZero  * approach was chosen: there is one main thread running the lwIP core
314*10465441SEvalZero  * (also known as the "tcpip_thread"). When running in a multithreaded
315*10465441SEvalZero  * environment, raw API functions MUST only be called from the core thread
316*10465441SEvalZero  * since raw API functions are not protected from concurrent access (aside
317*10465441SEvalZero  * from pbuf- and memory management functions). Application threads using
318*10465441SEvalZero  * the sequential- or socket API communicate with this main thread through
319*10465441SEvalZero  * message passing.
320*10465441SEvalZero  *
321*10465441SEvalZero  * As such, the list of functions that may be called from
322*10465441SEvalZero  * other threads or an ISR is very limited! Only functions
323*10465441SEvalZero  * from these API header files are thread-safe:
324*10465441SEvalZero  * - api.h
325*10465441SEvalZero  * - netbuf.h
326*10465441SEvalZero  * - netdb.h
327*10465441SEvalZero  * - netifapi.h
328*10465441SEvalZero  * - pppapi.h
329*10465441SEvalZero  * - sockets.h
330*10465441SEvalZero  * - sys.h
331*10465441SEvalZero  *
332*10465441SEvalZero  * Additionaly, memory (de-)allocation functions may be
333*10465441SEvalZero  * called from multiple threads (not ISR!) with NO_SYS=0
334*10465441SEvalZero  * since they are protected by @ref SYS_LIGHTWEIGHT_PROT and/or
335*10465441SEvalZero  * semaphores.
336*10465441SEvalZero  *
337*10465441SEvalZero  * Netconn or Socket API functions are thread safe against the
338*10465441SEvalZero  * core thread but they are not reentrant at the control block
339*10465441SEvalZero  * granularity level. That is, a UDP or TCP control block must
340*10465441SEvalZero  * not be shared among multiple threads without proper locking.
341*10465441SEvalZero  *
342*10465441SEvalZero  * If @ref SYS_LIGHTWEIGHT_PROT is set to 1 and
343*10465441SEvalZero  * @ref LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT is set to 1,
344*10465441SEvalZero  * pbuf_free() may also be called from another thread or
345*10465441SEvalZero  * an ISR (since only then, mem_free - for PBUF_RAM - may
346*10465441SEvalZero  * be called from an ISR: otherwise, the HEAP is only
347*10465441SEvalZero  * protected by semaphores).
348*10465441SEvalZero  *
349*10465441SEvalZero  * How to get threading done right
350*10465441SEvalZero  * -------------------------------
351*10465441SEvalZero  *
352*10465441SEvalZero  * It is strongly recommended to implement the LWIP_ASSERT_CORE_LOCKED()
353*10465441SEvalZero  * macro in an application that uses multithreading. lwIP code has
354*10465441SEvalZero  * several places where a check for a correct thread context is
355*10465441SEvalZero  * implemented which greatly helps the user to get threading done right.
356*10465441SEvalZero  * See the example sys_arch.c files in unix and Win32 port
357*10465441SEvalZero  * in the contrib repository.
358*10465441SEvalZero  *
359*10465441SEvalZero  * In short: Copy the functions sys_mark_tcpip_thread() and
360*10465441SEvalZero  * sys_check_core_locking() to your port and modify them to work with your OS.
361*10465441SEvalZero  * Then let @ref LWIP_ASSERT_CORE_LOCKED() and @ref LWIP_MARK_TCPIP_THREAD()
362*10465441SEvalZero  * point to these functions.
363*10465441SEvalZero  *
364*10465441SEvalZero  * If you use @ref LWIP_TCPIP_CORE_LOCKING, you also need to copy and adapt
365*10465441SEvalZero  * the functions sys_lock_tcpip_core() and sys_unlock_tcpip_core().
366*10465441SEvalZero  * Let @ref LOCK_TCPIP_CORE() and @ref UNLOCK_TCPIP_CORE() point
367*10465441SEvalZero  * to these functions.
368*10465441SEvalZero  */
369*10465441SEvalZero 
370*10465441SEvalZero /**
371*10465441SEvalZero  * @page optimization Optimization hints
372*10465441SEvalZero The first thing you want to optimize is the lwip_standard_checksum()
373*10465441SEvalZero routine from src/core/inet.c. You can override this standard
374*10465441SEvalZero function with the \#define LWIP_CHKSUM your_checksum_routine().
375*10465441SEvalZero 
376*10465441SEvalZero There are C examples given in inet.c or you might want to
377*10465441SEvalZero craft an assembly function for this. RFC1071 is a good
378*10465441SEvalZero introduction to this subject.
379*10465441SEvalZero 
380*10465441SEvalZero Other significant improvements can be made by supplying
381*10465441SEvalZero assembly or inline replacements for htons() and htonl()
382*10465441SEvalZero if you're using a little-endian architecture.
383*10465441SEvalZero \#define lwip_htons(x) your_htons()
384*10465441SEvalZero \#define lwip_htonl(x) your_htonl()
385*10465441SEvalZero If you \#define them to htons() and htonl(), you should
386*10465441SEvalZero \#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS to prevent lwIP from
387*10465441SEvalZero defining htonx / ntohx compatibility macros.
388*10465441SEvalZero 
389*10465441SEvalZero Check your network interface driver if it reads at
390*10465441SEvalZero a higher speed than the maximum wire-speed. If the
391*10465441SEvalZero hardware isn't serviced frequently and fast enough
392*10465441SEvalZero buffer overflows are likely to occur.
393*10465441SEvalZero 
394*10465441SEvalZero E.g. when using the cs8900 driver, call cs8900if_service(ethif)
395*10465441SEvalZero as frequently as possible. When using an RTOS let the cs8900 interrupt
396*10465441SEvalZero wake a high priority task that services your driver using a binary
397*10465441SEvalZero semaphore or event flag. Some drivers might allow additional tuning
398*10465441SEvalZero to match your application and network.
399*10465441SEvalZero 
400*10465441SEvalZero For a production release it is recommended to set LWIP_STATS to 0.
401*10465441SEvalZero Note that speed performance isn't influenced much by simply setting
402*10465441SEvalZero high values to the memory options.
403*10465441SEvalZero  */
404