sys_arch interface for lwIP Author: Adam Dunkels Simon Goldschmidt The operating system emulation layer provides a common interface between the lwIP code and the underlying operating system kernel. The general idea is that porting lwIP to new architectures requires only small changes to a few header files and a new sys_arch implementation. It is also possible to do a sys_arch implementation that does not rely on any underlying operating system. The sys_arch provides semaphores, mailboxes and mutexes to lwIP. For the full lwIP functionality, multiple threads support can be implemented in the sys_arch, but this is not required for the basic lwIP functionality. Timer scheduling is implemented in lwIP, but can be implemented by the sys_arch port (LWIP_TIMERS_CUSTOM==1). In addition to the source file providing the functionality of sys_arch, the OS emulation layer must provide several header files defining macros used throughout lwip. The files required and the macros they must define are listed below the sys_arch description. Semaphores can be either counting or binary - lwIP works with both kinds. Mailboxes should be implemented as a queue which allows multiple messages to be posted (implementing as a rendez-vous point where only one message can be posted at a time can have a highly negative impact on performance). A message in a mailbox is just a pointer, nothing more. Semaphores are represented by the type "sys_sem_t" which is typedef'd in the sys_arch.h file. Mailboxes are equivalently represented by the type "sys_mbox_t". Mutexes are represented by the type "sys_mutex_t". lwIP does not place any restrictions on how these types are represented internally. Since lwIP 1.4.0, semaphore, mutexes and mailbox functions are prototyped in a way that allows both using pointers or actual OS structures to be used. This way, memory required for such types can be either allocated in place (globally or on the stack) or on the heap (allocated internally in the "*_new()" functions). Note: Be careful with using mem_malloc() in sys_arch. When malloc() refers to mem_malloc() you can run into a circular function call problem. In mem.c mem_init() tries to allcate a semaphore using mem_malloc, which of course can't be performed when sys_arch uses mem_malloc. ------------------------------------------------------------------------------- Additional files required for the "OS support" emulation layer: ------------------------------------------------------------------------------- cc.h - Architecture environment, some compiler specific, some environment specific (probably should move env stuff to sys_arch.h.) Typedefs for the types used by lwip - u8_t, s8_t, u16_t, s16_t, u32_t, s32_t, mem_ptr_t Compiler hints for packing lwip's structures - PACK_STRUCT_FIELD(x) PACK_STRUCT_STRUCT PACK_STRUCT_BEGIN PACK_STRUCT_END Platform specific diagnostic output - LWIP_PLATFORM_DIAG(x) - non-fatal, print a message. LWIP_PLATFORM_ASSERT(x) - fatal, print message and abandon execution. Portability defines for printf formatters: U16_F, S16_F, X16_F, U32_F, S32_F, X32_F, SZT_F "lightweight" synchronization mechanisms - SYS_ARCH_DECL_PROTECT(x) - declare a protection state variable. SYS_ARCH_PROTECT(x) - enter protection mode. SYS_ARCH_UNPROTECT(x) - leave protection mode. If the compiler does not provide memset() this file must include a definition of it, or include a file which defines it. This file must either include a system-local which defines the standard *nix error codes (or define LWIP_ERRNO_INCLUDE to that file name), or it should #define LWIP_PROVIDE_ERRNO to make lwip/arch.h define the codes which are used throughout. perf.h - Architecture specific performance measurement. Measurement calls made throughout lwip, these can be defined to nothing. PERF_START - start measuring something. PERF_STOP(x) - stop measuring something, and record the result. sys_arch.h - Tied to sys_arch.c Arch dependent types for the following objects: sys_sem_t, sys_mbox_t, sys_thread_t, And, optionally: sys_prot_t Defines to set vars of sys_mbox_t and sys_sem_t to NULL. SYS_MBOX_NULL NULL SYS_SEM_NULL NULL