diff options
author | Tom Rini <trini@konsulko.com> | 2024-10-16 08:10:14 -0600 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2024-10-16 08:10:14 -0600 |
commit | f3f86fd1fe0fb288356bff78f8a6fa2edf89e3fc (patch) | |
tree | f0a99ea87d92f63895a6d053e3185838ebecf2d0 /doc/doxygen/main_page.h |
Squashed 'lib/lwip/lwip/' content from commit 0a0452b2c39b
git-subtree-dir: lib/lwip/lwip
git-subtree-split: 0a0452b2c39bdd91e252aef045c115f88f6ca773
Diffstat (limited to 'doc/doxygen/main_page.h')
-rw-r--r-- | doc/doxygen/main_page.h | 417 |
1 files changed, 417 insertions, 0 deletions
diff --git a/doc/doxygen/main_page.h b/doc/doxygen/main_page.h new file mode 100644 index 00000000000..4766c3a1856 --- /dev/null +++ b/doc/doxygen/main_page.h @@ -0,0 +1,417 @@ +/** + * @defgroup lwip lwIP + * + * @defgroup infrastructure Infrastructure + * + * @defgroup api APIs + * lwIP provides three Application Program's Interfaces (APIs) for programs + * to use for communication with the TCP/IP code: + * - low-level "core" / "callback" or @ref callbackstyle_api. + * - higher-level @ref sequential_api. + * - BSD-style @ref socket. + * + * The raw TCP/IP interface allows the application program to integrate + * better with the TCP/IP code. Program execution is event based by + * having callback functions being called from within the TCP/IP + * code. The TCP/IP code and the application program both run in the same + * thread. The sequential API has a much higher overhead and is not very + * well suited for small systems since it forces a multithreaded paradigm + * on the application. + * + * The raw TCP/IP interface is not only faster in terms of code execution + * time but is also less memory intensive. The drawback is that program + * development is somewhat harder and application programs written for + * the raw TCP/IP interface are more difficult to understand. Still, this + * is the preferred way of writing applications that should be small in + * code size and memory usage. + * + * All APIs can be used simultaneously by different application + * programs. In fact, the sequential API is implemented as an application + * program using the raw TCP/IP interface. + * + * Do not confuse the lwIP raw API with raw Ethernet or IP sockets. + * The former is a way of interfacing the lwIP network stack (including + * TCP and UDP), the latter refers to processing raw Ethernet or IP data + * instead of TCP connections or UDP packets. + * + * Raw API applications may never block since all packet processing + * (input and output) as well as timer processing (TCP mainly) is done + * in a single execution context. + * + * @defgroup callbackstyle_api "raw" APIs + * @ingroup api + * Non thread-safe APIs, callback style for maximum performance and minimum + * memory footprint. + * Program execution is driven by callbacks functions, which are then + * invoked by the lwIP core when activity related to that application + * occurs. A particular application may register to be notified via a + * callback function for events such as incoming data available, outgoing + * data sent, error notifications, poll timer expiration, connection + * closed, etc. An application can provide a callback function to perform + * processing for any or all of these events. Each callback is an ordinary + * C function that is called from within the TCP/IP code. Every callback + * function is passed the current TCP or UDP connection state as an + * argument. Also, in order to be able to keep program specific state, + * the callback functions are called with a program specified argument + * that is independent of the TCP/IP state. + * The raw API (sometimes called native API) is an event-driven API designed + * to be used without an operating system that implements zero-copy send and + * receive. This API is also used by the core stack for interaction between + * the various protocols. It is the only API available when running lwIP + * without an operating system. + * + * @defgroup sequential_api Sequential-style APIs + * @ingroup api + * Sequential-style APIs, blocking functions. More overhead, but can be called + * from any thread except TCPIP thread. + * The sequential API provides a way for ordinary, sequential, programs + * to use the lwIP stack. It is quite similar to the BSD socket API. The + * model of execution is based on the blocking open-read-write-close + * paradigm. Since the TCP/IP stack is event based by nature, the TCP/IP + * code and the application program must reside in different execution + * contexts (threads). + * + * @defgroup socket Socket API + * @ingroup api + * BSD-style socket API.<br> + * Thread-safe, to be called from non-TCPIP threads only.<br> + * Can be activated by defining @ref LWIP_SOCKET to 1.<br> + * Header is in posix/sys/socket.h<br> + * The socket API is a compatibility API for existing applications, + * currently it is built on top of the sequential API. It is meant to + * provide all functions needed to run socket API applications running + * on other platforms (e.g. unix / windows etc.). However, due to limitations + * in the specification of this API, there might be incompatibilities + * that require small modifications of existing programs. + * + * @defgroup netifs NETIFs + * + * @defgroup apps Applications + */ + +/** + * @mainpage Overview + * @verbinclude "README" + */ + +/** + * @page upgrading Upgrading + * @verbinclude "UPGRADING" + */ + +/** + * @page changelog Changelog + * + * 2.1.0 + * ----- + * * Support TLS via new @ref altcp_api connection API (https, smtps, mqtt over TLS) + * * Switch to cmake as the main build system (Makefile file lists are still + * maintained for now) + * * Improve IPv6 support: support address scopes, support stateless DHCPv6, bugfixes + * * Add debug helper asserts to ensure threading/locking requirements are met + * * Add sys_mbox_trypost_fromisr() and tcpip_callbackmsg_trycallback_fromisr() + * (for FreeRTOS, mainly) + * * socket API: support poll(), sendmsg() and recvmsg(); fix problems on close + * + * Detailed Changelog + * ------------------ + * @verbinclude "CHANGELOG" + */ + +/** + * @page contrib How to contribute to lwIP + * @verbinclude "contrib.txt" + */ + +/** + * @page cmake CMake build system + * @verbinclude "BUILDING" + */ + +/** + * @page pitfalls Common pitfalls + * + * Multiple Execution Contexts in lwIP code + * ======================================== + * + * The most common source of lwIP problems is to have multiple execution contexts + * inside the lwIP code. + * + * lwIP can be used in two basic modes: @ref lwip_nosys (no OS/RTOS + * running on target system) or @ref lwip_os (there is an OS running + * on the target system). + * + * See also: @ref multithreading (especially the part about @ref LWIP_ASSERT_CORE_LOCKED()!) + * + * Mainloop Mode + * ------------- + * In mainloop mode, only @ref callbackstyle_api can be used. + * The user has two possibilities to ensure there is only one + * execution context at a time in lwIP: + * + * 1) Deliver RX ethernet packets directly in interrupt context to lwIP + * by calling netif->input directly in interrupt. This implies all lwIP + * callback functions are called in IRQ context, which may cause further + * problems in application code: IRQ is blocked for a long time, multiple + * execution contexts in application code etc. When the application wants + * to call lwIP, it only needs to disable interrupts during the call. + * If timers are involved, even more locking code is needed to lock out + * timer IRQ and ethernet IRQ from each other, assuming these may be nested. + * + * 2) Run lwIP in a mainloop. There is example code here: @ref lwip_nosys. + * lwIP is _ONLY_ called from mainloop callstacks here. The ethernet IRQ + * has to put received telegrams into a queue which is polled in the + * mainloop. Ensure lwIP is _NEVER_ called from an interrupt, e.g. + * some SPI IRQ wants to forward data to udp_send() or tcp_write()! + * + * OS Mode + * ------- + * In OS mode, @ref callbackstyle_api AND @ref sequential_api can be used. + * @ref sequential_api are designed to be called from threads other than + * the TCPIP thread, so there is nothing to consider here. + * But @ref callbackstyle_api functions must _ONLY_ be called from + * TCPIP thread. It is a common error to call these from other threads + * or from IRQ contexts. Ethernet RX needs to deliver incoming packets + * in the correct way by sending a message to TCPIP thread, this is + * implemented in tcpip_input(). + * Again, ensure lwIP is _NEVER_ called from an interrupt, e.g. + * some SPI IRQ wants to forward data to udp_send() or tcp_write()! + * + * 1) tcpip_callback() can be used get called back from TCPIP thread, + * it is safe to call any @ref callbackstyle_api from there. + * + * 2) Use @ref LWIP_TCPIP_CORE_LOCKING. All @ref callbackstyle_api + * functions can be called when lwIP core lock is acquired, see + * @ref LOCK_TCPIP_CORE() and @ref UNLOCK_TCPIP_CORE(). + * These macros cannot be used in an interrupt context! + * Note the OS must correctly handle priority inversion for this. + * + * Cache / DMA issues + * ================== + * + * DMA-capable ethernet hardware and zero-copy RX + * ---------------------------------------------- + * + * lwIP changes the content of RECEIVED pbufs in the TCP code path. + * This implies one or more cacheline(s) of the RX pbuf become dirty + * and need to be flushed before the memory is handed over to the + * DMA ethernet hardware for the next telegram to be received. + * See http://lists.nongnu.org/archive/html/lwip-devel/2017-12/msg00070.html + * for a more detailed explanation. + * Also keep in mind the user application may also write into pbufs, + * so it is generally a bug not to flush the data cache before handing + * a buffer to DMA hardware. + * + * DMA-capable ethernet hardware and cacheline alignment + * ----------------------------------------------------- + * Nice description about DMA capable hardware and buffer handling: + * http://www.pebblebay.com/a-guide-to-using-direct-memory-access-in-embedded-systems-part-two/ + * Read especially sections "Cache coherency" and "Buffer alignment". + */ + +/** + * @page mem_err Debugging memory pool sizes + * If you have issues with lwIP and you are using memory pools, check that your pools + * are correctly sized.<br> + * To debug pool sizes, \#define LWIP_STATS and MEMP_STATS to 1. Check the global variable + * lwip_stats.memp[] using a debugger. If the "err" member of a pool is > 0, the pool + * may be too small for your application and you need to increase its size. + */ + +/** + * @page bugs Reporting bugs + * Please report bugs in the lwIP bug tracker at savannah.<br> + * BEFORE submitting, please check if the bug has already been reported!<br> + * https://savannah.nongnu.org/bugs/?group=lwip + */ + +/** + * @page zerocopyrx Zero-copy RX + * The following code is an example for zero-copy RX ethernet driver: + * @include ZeroCopyRx.c + */ + +/** + * @defgroup lwip_nosys Mainloop mode ("NO_SYS") + * @ingroup lwip + * Use this mode if you do not run an OS on your system. \#define NO_SYS to 1. + * Feed incoming packets to netif->input(pbuf, netif) function from mainloop, + * *not* *from* *interrupt* *context*. You can allocate a @ref pbuf in interrupt + * context and put them into a queue which is processed from mainloop.<br> + * Call sys_check_timeouts() periodically in the mainloop.<br> + * Porting: implement all functions in @ref sys_time, @ref sys_prot and + * @ref compiler_abstraction.<br> + * You can only use @ref callbackstyle_api in this mode.<br> + * Sample code: + * @include NO_SYS_SampleCode.c + */ + +/** + * @defgroup lwip_os OS mode (TCPIP thread) + * @ingroup lwip + * Use this mode if you run an OS on your system. It is recommended to + * use an RTOS that correctly handles priority inversion and + * to use @ref LWIP_TCPIP_CORE_LOCKING.<br> + * Porting: implement all functions in @ref sys_layer.<br> + * You can use @ref callbackstyle_api together with @ref tcpip_callback, + * and all @ref sequential_api. + */ + +/** + * @page sys_init System initialization +A truly complete and generic sequence for initializing the lwIP stack +cannot be given because it depends on additional initializations for +your runtime environment (e.g. timers). + +We can give you some idea on how to proceed when using the raw API. +We assume a configuration using a single Ethernet netif and the +UDP and TCP transport layers, IPv4 and the DHCP client. + +Call these functions in the order of appearance: + +- lwip_init(): Initialize the lwIP stack and all of its subsystems. + +- netif_add(struct netif *netif, ...): + Adds your network interface to the netif_list. Allocate a struct + netif and pass a pointer to this structure as the first argument. + Give pointers to cleared ip_addr structures when using DHCP, + or fill them with sane numbers otherwise. The state pointer may be NULL. + + The init function pointer must point to a initialization function for + your Ethernet netif interface. The following code illustrates its use. + +@code{.c} + err_t netif_if_init(struct netif *netif) + { + u8_t i; + + for (i = 0; i < ETHARP_HWADDR_LEN; i++) { + netif->hwaddr[i] = some_eth_addr[i]; + } + init_my_eth_device(); + return ERR_OK; + } +@endcode + + For Ethernet drivers, the input function pointer must point to the lwIP + function ethernet_input() declared in "netif/etharp.h". Other drivers + must use ip_input() declared in "lwip/ip.h". + +- netif_set_default(struct netif *netif) + Registers the default network interface. + +- netif_set_link_up(struct netif *netif) + This is the hardware link state; e.g. whether cable is plugged for wired + Ethernet interface. This function must be called even if you don't know + the current state. Having link up and link down events is optional but + DHCP and IPv6 discover benefit well from those events. + +- netif_set_up(struct netif *netif) + This is the administrative (= software) state of the netif, when the + netif is fully configured this function must be called. + +- dhcp_start(struct netif *netif) + Creates a new DHCP client for this interface on the first call. + You can peek in the netif->dhcp struct for the actual DHCP status. + +- sys_check_timeouts() + When the system is running, you have to periodically call + sys_check_timeouts() which will handle all timers for all protocols in + the stack; add this to your main loop or equivalent. + */ + +/** + * @page multithreading Multithreading + * lwIP started targeting single-threaded environments. When adding multi- + * threading support, instead of making the core thread-safe, another + * approach was chosen: there is one main thread running the lwIP core + * (also known as the "tcpip_thread"). When running in a multithreaded + * environment, raw API functions MUST only be called from the core thread + * since raw API functions are not protected from concurrent access (aside + * from pbuf- and memory management functions). Application threads using + * the sequential- or socket API communicate with this main thread through + * message passing. + * + * As such, the list of functions that may be called from + * other threads or an ISR is very limited! Only functions + * from these API header files are thread-safe: + * - api.h + * - netbuf.h + * - netdb.h + * - netifapi.h + * - pppapi.h + * - sockets.h + * - sys.h + * + * Additionally, memory (de-)allocation functions may be + * called from multiple threads (not ISR!) with NO_SYS=0 + * since they are protected by @ref SYS_LIGHTWEIGHT_PROT and/or + * semaphores. + * + * Netconn or Socket API functions are thread safe against the + * core thread but they are not reentrant at the control block + * granularity level. That is, a UDP or TCP control block must + * not be shared among multiple threads without proper locking. + * + * If @ref SYS_LIGHTWEIGHT_PROT is set to 1 and + * @ref LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT is set to 1, + * pbuf_free() may also be called from another thread or + * an ISR (since only then, mem_free - for PBUF_RAM - may + * be called from an ISR: otherwise, the HEAP is only + * protected by semaphores). + * + * How to get threading done right + * ------------------------------- + * + * It is strongly recommended to implement the LWIP_ASSERT_CORE_LOCKED() + * macro in an application that uses multithreading. lwIP code has + * several places where a check for a correct thread context is + * implemented which greatly helps the user to get threading done right. + * See the example sys_arch.c files in unix and Win32 port + * in the lwIP/contrib subdirectory. + * + * In short: Copy the functions sys_mark_tcpip_thread() and + * sys_check_core_locking() to your port and modify them to work with your OS. + * Then let @ref LWIP_ASSERT_CORE_LOCKED() and @ref LWIP_MARK_TCPIP_THREAD() + * point to these functions. + * + * If you use @ref LWIP_TCPIP_CORE_LOCKING, you also need to copy and adapt + * the functions sys_lock_tcpip_core() and sys_unlock_tcpip_core(). + * Let @ref LOCK_TCPIP_CORE() and @ref UNLOCK_TCPIP_CORE() point + * to these functions. + */ + +/** + * @page optimization Optimization hints +The first thing you want to optimize is the lwip_standard_checksum() +routine from src/core/inet.c. You can override this standard +function with the \#define LWIP_CHKSUM your_checksum_routine(). + +There are C examples given in inet.c or you might want to +craft an assembly function for this. RFC1071 is a good +introduction to this subject. + +Other significant improvements can be made by supplying +assembly or inline replacements for htons() and htonl() +if you're using a little-endian architecture. +\#define lwip_htons(x) your_htons() +\#define lwip_htonl(x) your_htonl() +If you \#define them to htons() and htonl(), you should +\#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS to prevent lwIP from +defining htonx / ntohx compatibility macros. + +Check your network interface driver if it reads at +a higher speed than the maximum wire-speed. If the +hardware isn't serviced frequently and fast enough +buffer overflows are likely to occur. + +E.g. when using the cs8900 driver, call cs8900if_service(ethif) +as frequently as possible. When using an RTOS let the cs8900 interrupt +wake a high priority task that services your driver using a binary +semaphore or event flag. Some drivers might allow additional tuning +to match your application and network. + +For a production release it is recommended to set LWIP_STATS to 0. +Note that speed performance isn't influenced much by simply setting +high values to the memory options. + */ |