RAFW Flexible Software Package Documentation  Release v2.0.1

 
lwIP (rm_lwip_w)

Detailed Description

Middleware lwIP on RAFW MCUs.

Overview

lwIP (Lightweight IP) is a widely used open-source TCP/IP stack designed for embedded systems with limited resources. Developed by Adam Dunkels at the Swedish Institute of Computer Science, lwIP is particularly suited for systems that need networking capabilities but have constraints on memory, processing power, and storage

Features

The lwIP module has the following key features:

Configuration

Build Time Configurations for rm_lwip_w

The following build time configurations are defined in fsp_cfg/rm_lwip_w_cfg.h:

ConfigurationOptionsDefaultDescription
Watchdog Service Support
  • Enabled
  • Disabled
Enabled Enable when using the Watchdog Service.
GARP ps-mode timeValue must be greater than 160 Time in seconds between Gratuitous ARP announcements sent when in power sleep mode

Clock Configuration

This module has no required clock configurations.

Pin Configuration

This module does not use I/O pins.

Usage Notes

The lwIP module use the next submodules:

Examples

Basic Example

This is a basic example of minimal use of lwIP which attaches an interface and send packets to interface and recieve in the egress handler.

#if defined(__SUPPORT_IPV4__) && !defined(__SUPPORT_IPV6__)
#include "lwip/udp.h"
#include "lwip/etharp.h"
#include "lwip/inet.h"
#include "netif/ethernet.h"
#include "lwip/stats.h"
#include "lwip/prot/iana.h"
#include "lwip/tcpip.h"
#include "lwip/ip4_addr.h"
#include "lwip/apps/ping.h"
#include "portmacro.h"
#define DUMMY_MAC_ADDRESS {0x00, 0x11, 0x22, 0x33, 0x44, 0x55}
/*
******************************************************************************
* GLOBAL VARIABLES
******************************************************************************
*/
struct netif test_netif; /* Test interface */
struct eth_addr test_ethaddr2 = {{1,1,1,1,1,2}};
static ip4_addr_t test_ipaddr, test_ipaddr1, test_netmask, test_gw;
const uint8_t mac_addr[6] = DUMMY_MAC_ADDRESS;
static int linkoutput_ctr;
const u8_t arp_reply[] = {
0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x00, 0x11, 0x22, 0x33,
0x44, 0x55, 0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04,
0x00, 0x02, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0xc0, 0xa8,
0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0xc0, 0xa8,
0x00, 0x0a
};
static err_t
default_netif_linkoutput(struct netif *netif, struct pbuf *p)
{
size_t i = 0;
struct eth_hdr *ethhdr;
struct etharp_hdr *arphdr;
ip4_addr_t sipaddr, dipaddr;
TEST_ASSERT_EQUAL_PTR(&test_netif, netif);
TEST_ASSERT_NOT_NULL_MESSAGE(p, "PBUF is NULL");
linkoutput_ctr++;
if (p->len >= (sizeof(struct eth_hdr) + sizeof(struct etharp_hdr))) {
ethhdr = (struct eth_hdr *)p->payload;
/* Check whether ARP packet */
if (htons(ethhdr->type) == ETHTYPE_ARP) {
arphdr = (struct etharp_hdr *)(p->payload + sizeof(struct eth_hdr));
uint16_t opcode = htons(arphdr->opcode);
IPADDR_WORDALIGNED_COPY_TO_IP4_ADDR_T(&sipaddr, &arphdr->sipaddr);
IPADDR_WORDALIGNED_COPY_TO_IP4_ADDR_T(&dipaddr, &arphdr->dipaddr);
if (opcode == ARP_REPLY) {
if (ip4_addr_cmp(&sipaddr, &dipaddr))
LWIP_DEBUG_PRINTF("\nDiscard gratuitous ARP announcement pkts opcode : %d\n", opcode);
else {
LWIP_DEBUG_PRINTF("\n===pbuf payload (ARP REPLY) recieved from lwIP===");
for (i = 0; i < p->len; i++) {
if(i % 16 == 0)
LWIP_DEBUG_PRINTF("\n");
LWIP_DEBUG_PRINTF("%02X ", ((unsigned char *)p->payload)[i]);
}
LWIP_DEBUG_PRINTF("\n");
if (memcmp(p->payload, &arp_reply, sizeof(arp_reply)) == 0) {
LWIP_DEBUG_PRINTF("\nVerification passed , ARP REPLY matches expected o/p\n");
return 1;
}
}
} else {
if (ip4_addr_cmp(&sipaddr, &dipaddr))
LWIP_DEBUG_PRINTF("\nDiscard gratuitous ARP announcement pkts opcode :%d\n", opcode);
}
} else {
LWIP_DEBUG_PRINTF("\nNot and ARP frame failed");
TEST_ASSERT(false);
}
} else {
LWIP_DEBUG_PRINTF("\nNot and Ethernet frame failed");
TEST_ASSERT(false);
}
return ERR_OK;
}
static err_t
default_netif_init(struct netif *netif)
{
netif->linkoutput = default_netif_linkoutput;
netif->output = etharp_output;
netif->mtu = 1500;
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
netif->hwaddr_len = ETHARP_HWADDR_LEN;
return ERR_OK;
}
static void setup_interface(void)
{
static bool initialized = false;
if (!initialized)
{
initialized = true;
ip_addr_set_zero(&test_gw);
ip_addr_set_zero(&test_ipaddr);
ip_addr_set_zero(&test_netmask);
mem_init();
memp_init();
tcpip_init(NULL, NULL);
IP4_ADDR(&test_gw, 192,168,0,1);
IP4_ADDR(&test_ipaddr, 192,168,0,1);
IP4_ADDR(&test_netmask, 255,255,0,0);
memcpy(&test_netif.hwaddr, mac_addr, ETH_HWADDR_LEN);
if (netif_add(&test_netif,
&test_ipaddr, &test_netmask, &test_gw,
NULL,
default_netif_init,
ethernet_input) == NULL) {
TEST_ASSERT(false);
}
}
netif_set_default(&test_netif);
netif_set_up(&test_netif);
}
static void close_interface(void)
{
netif_remove(&test_netif);
}
static void create_send_ingress_pkt(void)
{
int k;
size_t i = 0;
struct eth_hdr *ethhdr;
struct etharp_hdr *etharphdr;
struct pbuf *p = pbuf_alloc(PBUF_RAW, sizeof(struct eth_hdr) + sizeof(struct etharp_hdr), PBUF_RAM);
if(p == NULL) {
TEST_ASSERT(false);
}
ethhdr = (struct eth_hdr*)p->payload;
etharphdr = (struct etharp_hdr*)(ethhdr + 1);
ethhdr->dest.addr[0] = 0xFF;
ethhdr->dest.addr[1] = 0xFF;
ethhdr->dest.addr[2] = 0xFF;
ethhdr->dest.addr[3] = 0xFF;
ethhdr->dest.addr[4] = 0xFF;
ethhdr->dest.addr[5] = 0xFF;
ethhdr->src = test_ethaddr2;
ethhdr->type = htons(ETHTYPE_ARP);
etharphdr->hwtype = htons(LWIP_IANA_HWTYPE_ETHERNET);
etharphdr->proto = htons(ETHTYPE_IP);
etharphdr->hwlen = ETHARP_HWADDR_LEN;
etharphdr->protolen = sizeof(ip4_addr_t);
etharphdr->opcode = htons(ARP_REQUEST);
IP4_ADDR(&test_ipaddr1, 192,168,0,10);
SMEMCPY(&etharphdr->sipaddr, &test_ipaddr1, sizeof(ip4_addr_t));
SMEMCPY(&etharphdr->dipaddr, &test_ipaddr, sizeof(ip4_addr_t));
k = 6;
while(k > 0) {
k--;
/* Write the ARP MAC-Addresses */
etharphdr->shwaddr.addr[k] = test_ethaddr2.addr[k];
etharphdr->dhwaddr.addr[k] = 0x00;
/* Write the Ethernet MAC-Addresses */
ethhdr->dest.addr[k] = 0xFF;
ethhdr->src.addr[k] = test_ethaddr2.addr[k];
}
LWIP_DEBUG_PRINTF("\n=====payload sent to lwIP(ARP REQ)==== ");
for (i = 0; i < p->len; i++) {
if(i % 16 == 0)
LWIP_DEBUG_PRINTF("\n");
LWIP_DEBUG_PRINTF("%02X ", ((unsigned char *)p->payload)[i]);
}
LWIP_DEBUG_PRINTF("\n");
if(test_netif.input(p, &test_netif) != ERR_OK)
{
pbuf_free(p);
}
}
void lwip_main(void)
{
setup_interface();
create_send_ingress_pkt();
close_interface();
}
#endif

Data Structures

struct  lwip_w_cfg_t
 

Data Structure Documentation

◆ lwip_w_cfg_t

struct lwip_w_cfg_t

User configuration structure, used in open function

Data Fields
void const * p_extend Pointer to extended configuration by instance of interface.