Chapter 162. Port
Table of Contents
- 162.1. Port status
- 162.2. Implementation
- 162.3. Extensions
- 162.4. eCos API reference
- cyg_lwip_init — Initialise lwIP network stack
- cyg_lwip_netif_print_info — Output network interface address information
- cyg_net_eth_phy_ctx_acquire — Allocate PHY event context
- cyg_net_eth_phy_dsr — Notify lwIP stack of PHY event
- cyg_lwip_tick_to_msec — Convert eCos kernel clock ticks to millisecond count
- cyg_lwip_msec_to_tick — Convert millisecond count to eCos kernel clock ticks
- cyg_lwip_statistics — Statistics output
162.1. Port status
The eCos port of lwIP in eCosPro is based on the main lwIP Savannah git code base, with modifications consisting of both bug fixes and feature enhancements being made to the lwIP core code by eCosCentric.
The port requires the eCos kernel (CYGPKG_KERNEL
) for now.
The main reasons for this are because the ethernet driver and serial driver
implementations have dependencies on interrupts and non-kernel interrupt
support is tricky; and that it is only really feasible in the lwIP core
code to avoid a multi-thread OS if solely using the raw API. And when using
the raw API, the application would have to be responsible for polling the
underlying device driver (e.g. Ethernet) in any case.
Some eCos Ethernet drivers may have alignment constraints on packet data. This is usually not a problem, however it can affect PBUF_ROM packets, whose alignment is dictated by the application. Therefore the application must ensure only appropriately aligned PBUF_ROM packets are passed to lwIP, as appropriate for the hardware-specific Ethernet device driver.
lwIP's BSD sockets compatibility API is completely separate from the
socket and file descriptor interface provided by the eCos File I/O
(CYGPKG_IO_FILEIO
) package. As such, network
packages which rely on semantics such as being able to read and write
both files and sockets with that API, cannot work with lwIP at the
present time. This includes the httpd, DNS, SNTP and FTP client packages.
The NET-SNMP package uses BSD stack-specific APIs and so also cannot
work with lwIP, though lwIP can be configured with its own internal
SNMP agent providing MIB-2 support. Note that an example httpd server
written using the lwIP raw API is included in the tests/
subdirectory of the lwIP eCos
package.
For convenience when using the BSD sockets compatibility API,
including the network.h
header
file:
#include <network.h>
This allows access to the API. This also has the benefit of potentially allowing interchangeable application code if switching between the lwIP BSD socket compatibility API and the real BSD stack port in eCos.
lwIP does not attempt to provide a cleanly delineated namespace for lwIP functions. This could make it difficult to port legacy code where there is a chance of conflicting names and symbols, both functions and data. Care is required here.
Note | |
---|---|
The serial-based SLIP and PPP protocols should be functional, however they have not been well tested, and so are not supported under the terms of incident support in eCosPro. There is only convenient configuration for a single SLIP and/or PPP interface. Multiple interface support is planned for some future point. |
162.2. Implementation
The following sections provide an overview of how the port is structured regarding the interface between eCos and the core lwIP implementation.
162.2.1. System Configuration
The normal lwIP approach of the user supplying
a lwipopts.h
header file that provides
manifests to override the standard
lwIP opt.h
header file is used to
configure the main stack features. For eCos
the lwipopts.h
is provided as part of
the CYGPKG_NET_LWIP
package along with the lwIP generic
sources. Note: For eCos the lwipopts.h
also contains definitions for some lwIP features that do not yet have defaults
defined within opt.h
.
The eCos lwipopts.h
implementation itself
sets the majority of the lwIP feature control options based on the standard eCos
CDL (.ecc
) configuration world.
162.2.2. System Source
The CYGPKG_NET_LWIP
package provides some eCos specific
functionality in the src/ecos/
directory.
lwip_ecos_init.cxx
This source file provides two functions that are normally called by the application. The function cyg_lwip_init is needed to initialize the lwIP network stack, and cyg_lwip_netif_print_info can optionally be called to output network interface address information.
If
CYGINT_IO_ETH_DRIVERS_PHY_EVENTS
is configured to provide PHY event notification support then the functions cyg_net_eth_phy_ctx_acquireand cyg_net_eth_phy_dsr are available for network device drivers to manage per-interface event notification between the driver and lwIP TCP/IP stack layers.sys_arch.cxx
This source file implements the majority of the run-time support needed by lwIP to execute under eCos, which mainly covers:
- Mailbox support, mapping lwIP sys_mbox_t to eCos Cyg_Mbox objects.
- Semaphore support, mapping lwIP sys_sem_t to eCos Cyg_Counting_Semaphore objects.
- Thread support, mapping lwIP sys_thread_t to eCos Cyg_Thread objects.
- Mutex support, mapping lwIP sys_mutex_t to eCos Cyg_Mutex objects.
- Timer conversion support for converting between real-time-clock and millisecond ticks. The cyg_lwip_tick_to_msecand cyg_lwip_msec_to_tick functions may be useful to applications.
sio.c
Some serial I/O utility routines for SLIP and PPPoS support.
Only a single serial interface is support and is accessed via a named serial I/O device (either
CYGDAT_LWIP_PPP_DEV
for PPPoS, orCYGDAT_LWIP_SLIP_DEV
for SLIP). The I/O device is configured with non-blocking RX, and blocking TX as per the requirements of the lwIP APIs. The lwIP package CDL does not enforce any specific serial configuration (due to the varied differences between architectures and driver feature sets), so the developer is responsible for ensuring a suitable serial I/O driver configuration.
162.2.3. Threads
The lwIP network stack is mostly thread-safe for sockets and the sequential API, but not for the raw API. The most important caveat is that even for the sequential API it is NOT thread-safe to access the same BSD-style socket, or netconn, from multiple threads.
The default for eCos is for the run-time support to provide the TCP/IP
helper thread, which is enabled via the
lwIP NO_SYS=0
manifest definition. The lwIP API
thread will be created even if
the CYGFUN_LWIP_SEQUENTIAL_API
option is not
enabled, unless over-ridden by
the CYGFUN_LWIP_NO_SYS
option.
Note | |
---|---|
Disabling the sequential API option does not disable the
TCP/IP helper thread for backwards compatibility with previous eCos
configurations where the helper thread is expected even if the
option |
When the TCP/IP helper thread is required, the eCos lwIP run-time
support will call the lwIP tcpip_init()
function
as part of the initialization sequence. The created eCos thread is
named with the
configured CYGDAT_LWIP_TCPIP_THREAD_NAME
value,
and with the priority as configured
by CYGNUM_LWIP_NETWORK_THREAD_PRIORITY
.
Providing this thread allows simple raw API applications to interact with the eCos ethernet device drivers.
Note | |
---|---|
The, mutually exclusive, SLIP and PPPoS features require
the |
Caution | |
---|---|
If the option |
If SLIP support is configured then a handler thread is also created during the system initialization. As with the main lwIP thread the name and the priority of the thread can be set in the eCos configuration.
The current PPPoS implementation does not use a seperate helper thread, with the required RX work being done as part of the normal TCP/IP helper thread.
Note: At some points within the lwIP network stack the eCos scheduler is locked. Whilst this is only for short sections of code, this could disrupt real-time behaviour.
Thread-safety considerations regarding lwIP:
the network stack is thread-safe in general
However, individual sockets should not be shared between different eCos threads simultaneously (e.g. two threads doing overlapping
recv()
s).uses semaphores
So priority inversion is possible.
coarse locking granularity
The whole lwIP network stack can remain locked for a long time whilst an operation is processed. This could exacerbate any priority inversion issues.
- core lwIP code (and hence the raw API) is not thread-safe
mailboxes are used extensively
Mailboxes are used to funnel all threads' API requests into the lwIP context to avoid synchronisation problems, but this can cause priority inversion.
Also the effects of
CYGNUM_KERNEL_SYNCH_MBOX_QUEUE_SIZE
should be considered, since a very shallow mailbox depth could lead to client threads blocking waiting to post requests.
For eCos the timer support has been extended to provide absolute
timeout functionality to provide consistent timeout behaviour. The
manifset setting SYS_TIMEOUT_ENDTIME=1
is
enforced for eCos builds. If the previous lwIP functionality is
required then SYS_TIMEOUT_ENDTIME=0
and SYS_TIMEOUT_DELTA=1
should be manually
configured in the lwipopts.h
header file.
Caution | |
---|---|
If the older |
162.3. Extensions
When creating a deeply-embedded network application some features of lwIP can be used by the general application code to save on the code footprint of duplicating similar support. One major area that can easily be made use of in such a way is the lwIP memory allocation support.
If the CDL option CYGFUN_LWIP_MEMP_USE_CUSTOM_POOLS
is
enabled then the user can supply
the lwippools.h
header file accessible to
the lwIP build. This header file is included by lwIP when defining the memory
pool structures, and can include application
specific custom pools. The following example implementation
provides a new application specific 16 entry memory pool containing 64-byte
buffers:
/*> lwippools.h <*/ /* NOTE: We do NOT have the standard header file one-time inclusion conditional checks since this source file is referenced multiple-times, with different macro definitions, depending on the part of the memory pool support being instantiated. */ LWIP_MEMPOOL(APP_BUFFER, 16, 64, "APP_BUFFER") /*> EOF lwippools.h <*/
The custom memory pool space is located within the configured lwIP memory pool
space. The pool can then be accessed via the memp_malloc()
and memp_free()
as normal:
pointer = (someptr *)memp_malloc(MEMP_APP_BUFFER); /* Do some work with the buffer … */ memp_free(MEMP_APP_BUFFER, pointer);
For eCos the memory pool allocation support is protected using
the SYS_ARCH_PROTECT
(DSR) serialization support code,
allowing the calls to be made from any thread.
Similarly if lwIP is configured
with CYGFUN_LWIP_MEM_USE_POOLS
then it will use fixed size
memory pools instead of a heap for the mem_malloc()
calls. The lwippools.h
header file can
then be used to define the specific fixed size memory pools to be used by
including suitable LWIP_MALLOC_MEMPOOL()
macro calls. For
example the following fragment will define a set of fixed size pools:
/* Define three pools with buffer sizes of 256, 512, and 1512 bytes respectively. */ LWIP_MALLOC_MEMPOOL_START LWIP_MALLOC_MEMPOOL(20, 256) LWIP_MALLOC_MEMPOOL(10, 512) LWIP_MALLOC_MEMPOOL( 5, 1512) /* More pools can be added as required. */ LWIP_MALLOC_MEMPOOL_END
162.4. eCos API reference
- cyg_lwip_init — Initialise lwIP network stack
- cyg_lwip_netif_print_info — Output network interface address information
- cyg_net_eth_phy_ctx_acquire — Allocate PHY event context
- cyg_net_eth_phy_dsr — Notify lwIP stack of PHY event
- cyg_lwip_tick_to_msec — Convert eCos kernel clock ticks to millisecond count
- cyg_lwip_msec_to_tick — Convert millisecond count to eCos kernel clock ticks
- cyg_lwip_statistics — Statistics output
2024-03-18 | LWIP Documentation Notices |