Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ambrop72/badvpn.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'lwip/doc/rawapi.txt')
-rw-r--r--lwip/doc/rawapi.txt171
1 files changed, 79 insertions, 92 deletions
diff --git a/lwip/doc/rawapi.txt b/lwip/doc/rawapi.txt
index 8c19030..813ddad 100644
--- a/lwip/doc/rawapi.txt
+++ b/lwip/doc/rawapi.txt
@@ -8,6 +8,12 @@ to use for communication with the TCP/IP code:
* higher-level "sequential" API.
* BSD-style socket API.
+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.
+
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
@@ -22,14 +28,17 @@ 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.
-** Threading
+** 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"). The raw API may only be used from
-this thread! Application threads using the sequential- or socket API
-communicate with this main thread through message passing.
+(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
@@ -38,6 +47,7 @@ communicate with this main thread through message passing.
- netbuf.h
- netdb.h
- netifapi.h
+ - pppapi.h
- sockets.h
- sys.h
@@ -46,13 +56,18 @@ communicate with this main thread through message passing.
since they are protected by SYS_LIGHTWEIGHT_PROT and/or
semaphores.
- Only since 1.3.0, if SYS_LIGHTWEIGHT_PROT is set to 1
- and LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT is set to 1,
+ 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 SYS_LIGHTWEIGHT_PROT is set to 1 and
+ 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).
-
+
** The remainder of this document discusses the "raw" API. **
@@ -71,13 +86,28 @@ 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.
-Both APIs can be used simultaneously by different application
+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 later 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.
+
--- Callbacks
-Program execution is driven by callbacks. Each callback is an ordinary
+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,
@@ -141,15 +171,6 @@ incoming connections or be explicitly connected to another host.
in the listen queue to the value specified by the backlog argument.
To use it, your need to set TCP_LISTEN_BACKLOG=1 in your lwipopts.h.
-- void tcp_accepted(struct tcp_pcb *pcb)
-
- Inform lwIP that an incoming connection has been accepted. This would
- usually be called from the accept callback. This allows lwIP to perform
- housekeeping tasks, such as allowing further incoming connections to be
- queued in the listen backlog.
- ATTENTION: the PCB passed in must be the listening pcb, not the pcb passed
- into the accept callback!
-
- void tcp_accept(struct tcp_pcb *pcb,
err_t (* accept)(void *arg, struct tcp_pcb *newpcb,
err_t err))
@@ -196,7 +217,7 @@ callback function.
should be allocated and the data should only be referenced by pointer. This
also means that the memory behind dataptr must not change until the data is
ACKed by the remote host
- - TCP_WRITE_FLAG_MORE: indicates that more data follows. If this is given,
+ - TCP_WRITE_FLAG_MORE: indicates that more data follows. If this is omitted,
the PSH flag is set in the last segment created by this call to tcp_write.
If this flag is given, the PSH flag is not set.
@@ -302,17 +323,6 @@ function to be called is set using the tcp_err() function.
parameter since the pcb may already have been deallocated.
---- Lower layer TCP interface
-
-TCP provides a simple interface to the lower layers of the
-system. During system initialization, the function tcp_init() has
-to be called before any other TCP function is called. When the system
-is running, the two timer functions tcp_fasttmr() and tcp_slowtmr()
-must be called with regular intervals. The tcp_fasttmr() should be
-called every TCP_FAST_INTERVAL milliseconds (defined in tcp.h) and
-tcp_slowtmr() should be called every TCP_SLOW_INTERVAL milliseconds.
-
-
--- UDP interface
The UDP interface is similar to that of TCP, but due to the lower
@@ -363,9 +373,9 @@ level of complexity of UDP, the interface is significantly simpler.
--- System initalization
-A truly complete and generic sequence for initializing the lwip stack
-cannot be given because it depends on the build configuration (lwipopts.h)
-and additional initializations for your runtime environment (e.g. timers).
+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
@@ -373,51 +383,13 @@ UDP and TCP transport layers, IPv4 and the DHCP client.
Call these functions in the order of appearance:
-- stats_init()
-
- Clears the structure where runtime statistics are gathered.
-
-- sys_init()
-
- Not of much use since we set the NO_SYS 1 option in lwipopts.h,
- to be called for easy configuration changes.
-
-- mem_init()
-
- Initializes the dynamic memory heap defined by MEM_SIZE.
+- lwip_init()
-- memp_init()
+ Initialize the lwIP stack and all of its subsystems.
- Initializes the memory pools defined by MEMP_NUM_x.
-
-- pbuf_init()
-
- Initializes the pbuf memory pool defined by PBUF_POOL_SIZE.
-
-- etharp_init()
-
- Initializes the ARP table and queue.
- Note: you must call etharp_tmr at a ARP_TMR_INTERVAL (5 seconds) regular interval
- after this initialization.
-
-- ip_init()
-
- Doesn't do much, it should be called to handle future changes.
-
-- udp_init()
-
- Clears the UDP PCB list.
-
-- tcp_init()
-
- Clears the TCP PCB list and clears some internal TCP timers.
- Note: you must call tcp_fasttmr() and tcp_slowtmr() at the
- predefined regular intervals after this initialization.
-
-- netif_add(struct netif *netif, ip_addr_t *ipaddr,
- ip_addr_t *netmask, ip_addr_t *gw,
- void *state, err_t (* init)(struct netif *netif),
- err_t (* input)(struct pbuf *p, struct netif *netif))
+- netif_add(struct netif *netif, const ip4_addr_t *ipaddr,
+ const ip4_addr_t *netmask, const ip4_addr_t *gw,
+ void *state, netif_init_fn init, netif_input_fn input)
Adds your network interface to the netif_list. Allocate a struct
netif and pass a pointer to this structure as the first argument.
@@ -425,18 +397,20 @@ Call these functions in the order of appearance:
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 it's use.
+ your Ethernet netif interface. The following code illustrates its use.
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];
+ for (i = 0; i < ETHARP_HWADDR_LEN; i++) {
+ netif->hwaddr[i] = some_eth_addr[i];
+ }
init_my_eth_device();
return ERR_OK;
}
- For ethernet drivers, the input function pointer must point to the lwip
+ 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".
@@ -444,20 +418,32 @@ Call these functions in the order of appearance:
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)
- When the netif is fully configured this function must be called.
+ 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.
- Note: you must call dhcp_fine_tmr() and dhcp_coarse_tmr() at
- the predefined regular intervals after starting the client.
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.
+
---- Optimalization hints
+--- 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
@@ -470,9 +456,11 @@ 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_PLATFORM_BYTESWAP 1
-#define LWIP_PLATFORM_HTONS(x) <your_htons>
-#define LWIP_PLATFORM_HTONL(x) <your_htonl>
+#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 hton*/ntoh* compatibility macros.
Check your network interface driver if it reads at
a higher speed than the maximum wire-speed. If the
@@ -498,14 +486,13 @@ remain unchanged until sent. Because the send- (or write-)functions return
when the packets have been enqueued for sending, data must be kept stable
after that, too.
-This implies that PBUF_RAM/PBUF_POOL pbufs passed to raw-API send functions
-must *not* be reused by the application unless their ref-count is 1.
+This implies that *ALL* pbufs passed to send functions must *not* be reused by
+the application unless the send function returns an error indicating the pbuf
+is not sent/queued for sending.
-For no-copy pbufs (PBUF_ROM/PBUF_REF), data must be kept unchanged, too,
-but the stack/driver will/must copy PBUF_REF'ed data when enqueueing, while
-PBUF_ROM-pbufs are just enqueued (as ROM-data is expected to never change).
-Also, data passed to tcp_write without the copy-flag must not be changed!
+Also, data passed to tcp_write without the copy-flag must not be changed until
+sent and ACKed (check the amount of bytes marked as 'sent')!
Therefore, be careful which type of PBUF you use and if you copy TCP data
or not!