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