The lwIP socket API provides a BSD socket-style API to programs. This API provides an execution model that is a blocking, open-read-write-close paradigm.
Xilinx Adapter Requirements when using the Socket API
Applications using the Socket API with Xilinx adapters need to spawn a separate thread called xemacif_input_thread. This thread takes care of moving received packets from the interrupt handlers to the tcpip_thread of the lwIP. Application threads that use lwIP must be created using the lwIP sys_thread_new API. Internally, this function makes use of the appropriate thread or task creation routines provided by FreeRTOS.
FreeRTOS scheduling policy when using the Socket API
lwIP in socket mode requires the use of the FreeRTOS, which provides two
policies for thread scheduling: round-robin and priority based.
There are no special requirements when round-robin scheduling policy
is used because all threads or tasks with same priority receive the
same time quanta. This quanta is fixed by the RTOS (FreeRTOS) being
used. With priority scheduling, care must be taken to ensure that
lwIP threads or tasks are not starved. LwIP internally launches all
tasks except the main TCP/IP task at the priority specified in
socket_mode_thread_prio. The TCP/IP task in
FreeRTOS is launched with a higher priority (one more than priority
set in socket_mode_thread_prio). In addition,
application threads must launch
xemacif_input_thread. The priorities of
both xemacif_input_thread, and the lwIP internal
threads (socket_mode_thread_prio) must be high
enough in relation to the other application threads so that they are
not starved.
Socket API Example
main_thread, one more thread (network_thread) is
created to initialize the MAC FreeRTOS (Zynq 7000, Zynq UltraScale+
MPSoC, Versal adaptive SoC, Versal AI Edge Series Gen 2, and Versal
Prime Series Gen 2 device) based applications.- Once the control reaches application main routine, a task (or main_thread) with an entry point function as main_thread() is created before starting the scheduler.
- After the FreeRTOS scheduler starts, the control reaches main_thread(), where the lwIP internal initialization happens.
- The application then creates one more thread (network_thread) to initialize the MAC layer. The following pseudo-code illustrates a typical socket mode program structure.
void network_thread(void *p)
{
struct netif *netif;
ip_addr_t ipaddr, netmask, gw;
unsigned char mac_ethernet_address[] =
{0x00, 0x0a, 0x35, 0x00, 0x01, 0x02};
netif = &server_netif;
IP4_ADDR(&ipaddr,192,168,1,10);
IP4_ADDR(&netmask,255,255,255,0);
IP4_ADDR(&gw,192,168,1,1);
if (!xemac_add(netif, &ipaddr, &netmask,
&gw, mac_ethernet_address,
EMAC_BASEADDR)) {
printf(“Error adding N/W interface\n\r”);
return;
}
netif_set_default(netif);
netif_set_up(netif);
sys_thread_new(“xemacif_input_thread”, xemacif_input_thread,
netif,
THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
sys_thread_new(“httpd” web_application_thread, 0,
THREAD_STACKSIZE DEFAULT_THREAD_PRIO);
}
int main_thread()
{
lwip_init();
sys_thread_new(“network_thread” network_thread, NULL,
THREAD_STACKSIZE DEFAULT_THREAD_PRIO);
return 0;
}