123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417 |
- /**
- * @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.
- */
|