1*10465441SEvalZero /** 2*10465441SEvalZero * @defgroup lwip lwIP 3*10465441SEvalZero * 4*10465441SEvalZero * @defgroup infrastructure Infrastructure 5*10465441SEvalZero * 6*10465441SEvalZero * @defgroup callbackstyle_api Callback-style APIs 7*10465441SEvalZero * Non thread-safe APIs, callback style for maximum performance and minimum 8*10465441SEvalZero * memory footprint. 9*10465441SEvalZero * 10*10465441SEvalZero * @defgroup sequential_api Sequential-style APIs 11*10465441SEvalZero * Sequential-style APIs, blocking functions. More overhead, but can be called 12*10465441SEvalZero * from any thread except TCPIP thread. 13*10465441SEvalZero * 14*10465441SEvalZero * @defgroup addons Addons 15*10465441SEvalZero * 16*10465441SEvalZero * @defgroup apps Applications 17*10465441SEvalZero */ 18*10465441SEvalZero 19*10465441SEvalZero /** 20*10465441SEvalZero * @mainpage Overview 21*10465441SEvalZero * @verbinclude "README" 22*10465441SEvalZero */ 23*10465441SEvalZero 24*10465441SEvalZero /** 25*10465441SEvalZero * @page upgrading Upgrading 26*10465441SEvalZero * @verbinclude "UPGRADING" 27*10465441SEvalZero */ 28*10465441SEvalZero 29*10465441SEvalZero /** 30*10465441SEvalZero * @page changelog Changelog 31*10465441SEvalZero * @verbinclude "CHANGELOG" 32*10465441SEvalZero */ 33*10465441SEvalZero 34*10465441SEvalZero /** 35*10465441SEvalZero * @page contrib How to contribute to lwIP 36*10465441SEvalZero * @verbinclude "contrib.txt" 37*10465441SEvalZero */ 38*10465441SEvalZero 39*10465441SEvalZero /** 40*10465441SEvalZero * @page pitfalls Common pitfalls 41*10465441SEvalZero * 42*10465441SEvalZero * Multiple Execution Contexts in lwIP code 43*10465441SEvalZero * ======================================== 44*10465441SEvalZero * 45*10465441SEvalZero * The most common source of lwIP problems is to have multiple execution contexts 46*10465441SEvalZero * inside the lwIP code. 47*10465441SEvalZero * 48*10465441SEvalZero * lwIP can be used in two basic modes: @ref lwip_nosys (no OS/RTOS 49*10465441SEvalZero * running on target system) or @ref lwip_os (there is an OS running 50*10465441SEvalZero * on the target system). 51*10465441SEvalZero * 52*10465441SEvalZero * Mainloop Mode 53*10465441SEvalZero * ------------- 54*10465441SEvalZero * In mainloop mode, only @ref callbackstyle_api can be used. 55*10465441SEvalZero * The user has two possibilities to ensure there is only one 56*10465441SEvalZero * exection context at a time in lwIP: 57*10465441SEvalZero * 58*10465441SEvalZero * 1) Deliver RX ethernet packets directly in interrupt context to lwIP 59*10465441SEvalZero * by calling netif->input directly in interrupt. This implies all lwIP 60*10465441SEvalZero * callback functions are called in IRQ context, which may cause further 61*10465441SEvalZero * problems in application code: IRQ is blocked for a long time, multiple 62*10465441SEvalZero * execution contexts in application code etc. When the application wants 63*10465441SEvalZero * to call lwIP, it only needs to disable interrupts during the call. 64*10465441SEvalZero * If timers are involved, even more locking code is needed to lock out 65*10465441SEvalZero * timer IRQ and ethernet IRQ from each other, assuming these may be nested. 66*10465441SEvalZero * 67*10465441SEvalZero * 2) Run lwIP in a mainloop. There is example code here: @ref lwip_nosys. 68*10465441SEvalZero * lwIP is _ONLY_ called from mainloop callstacks here. The ethernet IRQ 69*10465441SEvalZero * has to put received telegrams into a queue which is polled in the 70*10465441SEvalZero * mainloop. Ensure lwIP is _NEVER_ called from an interrupt, e.g. 71*10465441SEvalZero * some SPI IRQ wants to forward data to udp_send() or tcp_write()! 72*10465441SEvalZero * 73*10465441SEvalZero * OS Mode 74*10465441SEvalZero * ------- 75*10465441SEvalZero * In OS mode, @ref callbackstyle_api AND @ref sequential_api can be used. 76*10465441SEvalZero * @ref sequential_api are designed to be called from threads other than 77*10465441SEvalZero * the TCPIP thread, so there is nothing to consider here. 78*10465441SEvalZero * But @ref callbackstyle_api functions must _ONLY_ be called from 79*10465441SEvalZero * TCPIP thread. It is a common error to call these from other threads 80*10465441SEvalZero * or from IRQ contexts. Ethernet RX needs to deliver incoming packets 81*10465441SEvalZero * in the correct way by sending a message to TCPIP thread, this is 82*10465441SEvalZero * implemented in tcpip_input(). 83*10465441SEvalZero * Again, ensure lwIP is _NEVER_ called from an interrupt, e.g. 84*10465441SEvalZero * some SPI IRQ wants to forward data to udp_send() or tcp_write()! 85*10465441SEvalZero * 86*10465441SEvalZero * 1) tcpip_callback() can be used get called back from TCPIP thread, 87*10465441SEvalZero * it is safe to call any @ref callbackstyle_api from there. 88*10465441SEvalZero * 89*10465441SEvalZero * 2) Use @ref LWIP_TCPIP_CORE_LOCKING. All @ref callbackstyle_api 90*10465441SEvalZero * functions can be called when lwIP core lock is aquired, see 91*10465441SEvalZero * @ref LOCK_TCPIP_CORE() and @ref UNLOCK_TCPIP_CORE(). 92*10465441SEvalZero * These macros cannot be used in an interrupt context! 93*10465441SEvalZero * Note the OS must correctly handle priority inversion for this. 94*10465441SEvalZero */ 95*10465441SEvalZero 96*10465441SEvalZero /** 97*10465441SEvalZero * @page bugs Reporting bugs 98*10465441SEvalZero * Please report bugs in the lwIP bug tracker at savannah.\n 99*10465441SEvalZero * BEFORE submitting, please check if the bug has already been reported!\n 100*10465441SEvalZero * https://savannah.nongnu.org/bugs/?group=lwip 101*10465441SEvalZero */ 102*10465441SEvalZero 103*10465441SEvalZero /** 104*10465441SEvalZero * @defgroup lwip_nosys Mainloop mode ("NO_SYS") 105*10465441SEvalZero * @ingroup lwip 106*10465441SEvalZero * Use this mode if you do not run an OS on your system. \#define NO_SYS to 1. 107*10465441SEvalZero * Feed incoming packets to netif->input(pbuf, netif) function from mainloop, 108*10465441SEvalZero * *not* *from* *interrupt* *context*. You can allocate a @ref pbuf in interrupt 109*10465441SEvalZero * context and put them into a queue which is processed from mainloop.\n 110*10465441SEvalZero * Call sys_check_timeouts() periodically in the mainloop.\n 111*10465441SEvalZero * Porting: implement all functions in @ref sys_time, @ref sys_prot and 112*10465441SEvalZero * @ref compiler_abstraction.\n 113*10465441SEvalZero * You can only use @ref callbackstyle_api in this mode.\n 114*10465441SEvalZero * Sample code:\n 115*10465441SEvalZero * @include NO_SYS_SampleCode.c 116*10465441SEvalZero */ 117*10465441SEvalZero 118*10465441SEvalZero /** 119*10465441SEvalZero * @defgroup lwip_os OS mode (TCPIP thread) 120*10465441SEvalZero * @ingroup lwip 121*10465441SEvalZero * Use this mode if you run an OS on your system. It is recommended to 122*10465441SEvalZero * use an RTOS that correctly handles priority inversion and 123*10465441SEvalZero * to use @ref LWIP_TCPIP_CORE_LOCKING.\n 124*10465441SEvalZero * Porting: implement all functions in @ref sys_layer.\n 125*10465441SEvalZero * You can use @ref callbackstyle_api together with @ref tcpip_callback, 126*10465441SEvalZero * and all @ref sequential_api. 127*10465441SEvalZero */ 128*10465441SEvalZero 129*10465441SEvalZero /** 130*10465441SEvalZero * @page raw_api lwIP API 131*10465441SEvalZero * @verbinclude "rawapi.txt" 132*10465441SEvalZero */ 133