diff --git a/cmake/iMX8MM.cmake b/cmake/iMX8MM.cmake
new file mode 100644
index 00000000..d7922144
--- /dev/null
+++ b/cmake/iMX8MM.cmake
@@ -0,0 +1,62 @@
+#********************************************************************
+#        _       _         _
+#  _ __ | |_  _ | |  __ _ | |__   ___
+# | '__|| __|(_)| | / _` || '_ \ / __|
+# | |   | |_  _ | || (_| || |_) |\__ \
+# |_|    \__|(_)|_| \__,_||_.__/ |___/
+#
+# www.rt-labs.com
+# Copyright 2021 rt-labs AB, Sweden.
+# Copyright 2023 NXP
+#
+# This software is dual-licensed under GPLv3 and a commercial
+# license. See the file LICENSE.md distributed with this software for
+# full license information.
+#*******************************************************************/
+
+target_include_directories(profinet
+  PRIVATE
+  src/ports/iMX8M
+  )
+
+target_sources(profinet
+  PRIVATE
+  src/ports/iMX8M/pnal.c
+  src/ports/iMX8M/pnal_eth.c
+  src/ports/iMX8M/pnal_udp.c
+  )
+
+target_include_directories(pn_dev
+  PRIVATE
+  samples/pn_dev
+  src/ports/iMX8M
+  )
+
+target_sources(pn_dev
+  PRIVATE
+  samples/pn_dev/sampleapp_common.c
+  samples/pn_dev/app_utils.c
+  samples/pn_dev/app_log.c
+  samples/pn_dev/app_gsdml.c
+  samples/pn_dev/app_data.c
+  src/ports/iMX8M/sampleapp_main.c
+  src/ports/iMX8M/sampleapp_imx8mmevk.c
+  )
+
+target_link_libraries(pn_dev PRIVATE mcuxsdk-bsp)
+
+install (FILES
+  src/ports/iMX8M/pnal_config.h
+  DESTINATION include
+  )
+
+generate_bin(pn_dev)
+
+if (BUILD_TESTING)
+  target_include_directories(pf_test
+    PRIVATE
+    src/ports/iMX8M
+    )
+  target_link_libraries(pf_test PRIVATE mcuxsdk-bsp)
+  generate_bin(pf_test)
+endif()
diff --git a/src/ports/iMX8M/pnal.c b/src/ports/iMX8M/pnal.c
new file mode 100644
index 00000000..cf1efaad
--- /dev/null
+++ b/src/ports/iMX8M/pnal.c
@@ -0,0 +1,185 @@
+/*********************************************************************
+ *        _       _         _
+ *  _ __ | |_  _ | |  __ _ | |__   ___
+ * | '__|| __|(_)| | / _` || '_ \ / __|
+ * | |   | |_  _ | || (_| || |_) |\__ \
+ * |_|    \__|(_)|_| \__,_||_.__/ |___/
+ *
+ * www.rt-labs.com
+ * Copyright 2021 rt-labs AB, Sweden.
+ * Copyright 2023 NXP
+ *
+ * This software is dual-licensed under GPLv3 and a commercial
+ * license. See the file LICENSE.md distributed with this software for
+ * full license information.
+ ********************************************************************/
+
+#include "pnal.h"
+
+#include "options.h"
+#include "osal.h"
+#include "osal_log.h"
+
+#include <lwip/apps/snmp.h>
+#include <lwip/netif.h>
+#include <lwip/snmp.h>
+#include <lwip/sys.h>
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int pnal_set_ip_suite (
+   const char * interface_name,
+   const pnal_ipaddr_t * p_ipaddr,
+   const pnal_ipaddr_t * p_netmask,
+   const pnal_ipaddr_t * p_gw,
+   const char * hostname,
+   bool permanent)
+{
+   ip_addr_t ip_addr;
+   ip_addr_t ip_mask;
+   ip_addr_t ip_gw;
+
+   ip_addr.addr = htonl (*p_ipaddr);
+   ip_mask.addr = htonl (*p_netmask);
+   ip_gw.addr = htonl (*p_gw);
+   
+   LOCK_TCPIP_CORE();
+   netif_set_addr (netif_default, &ip_addr, &ip_mask, &ip_gw);
+   UNLOCK_TCPIP_CORE();
+
+   return 0;
+}
+
+int pnal_get_macaddress (const char * interface_name, pnal_ethaddr_t * mac_addr)
+{
+   memcpy (mac_addr, netif_default->hwaddr, sizeof (pnal_ethaddr_t));
+   return 0;
+}
+
+pnal_ipaddr_t pnal_get_ip_address (const char * interface_name)
+{
+   return htonl (netif_default->ip_addr.addr);
+}
+
+pnal_ipaddr_t pnal_get_netmask (const char * interface_name)
+{
+   return htonl (netif_default->netmask.addr);
+}
+
+pnal_ipaddr_t pnal_get_gateway (const char * interface_name)
+{
+   /* TODO Read the actual default gateway */
+
+   pnal_ipaddr_t ip;
+   pnal_ipaddr_t gateway;
+
+   ip = pnal_get_ip_address (interface_name);
+   gateway = (ip & 0xFFFFFF00) | 0x00000001;
+
+   return gateway;
+}
+
+int pnal_get_hostname (char * hostname)
+{
+   strcpy (hostname, netif_default->hostname);
+   return 0;
+}
+
+int pnal_get_ip_suite (
+   const char * interface_name,
+   pnal_ipaddr_t * p_ipaddr,
+   pnal_ipaddr_t * p_netmask,
+   pnal_ipaddr_t * p_gw,
+   char * hostname)
+{
+   int ret = -1;
+
+   *p_ipaddr = pnal_get_ip_address (interface_name);
+   *p_netmask = pnal_get_netmask (interface_name);
+   *p_gw = pnal_get_gateway (interface_name);
+   ret = pnal_get_hostname (hostname);
+
+   return ret;
+}
+
+int pnal_get_port_statistics (
+   const char * interface_name,
+   pnal_port_stats_t * port_stats)
+{
+   port_stats->if_in_octets = netif_default->mib2_counters.ifinoctets;
+   port_stats->if_in_errors = netif_default->mib2_counters.ifinerrors;
+   port_stats->if_in_discards = netif_default->mib2_counters.ifindiscards;
+   port_stats->if_out_octets = netif_default->mib2_counters.ifoutoctets;
+   port_stats->if_out_errors = netif_default->mib2_counters.ifouterrors;
+   port_stats->if_out_discards = netif_default->mib2_counters.ifoutdiscards;
+
+   return 0;
+}
+
+int pnal_get_interface_index (const char * interface_name)
+{
+   return 0;
+}
+
+int pnal_eth_get_status (const char * interface_name, pnal_eth_status_t * status)
+{
+   status->is_autonegotiation_supported = false;
+   status->is_autonegotiation_enabled = false;
+   status->autonegotiation_advertised_capabilities = 0;
+
+   status->operational_mau_type = PNAL_ETH_MAU_COPPER_100BaseTX_FULL_DUPLEX;
+   status->running = true;
+
+   return 0;
+}
+
+int pnal_save_file (
+   const char * fullpath,
+   const void * object_1,
+   size_t size_1,
+   const void * object_2,
+   size_t size_2)
+{
+   return -1;
+}
+
+void pnal_clear_file (const char * fullpath)
+{
+
+}
+
+int pnal_load_file (
+   const char * fullpath,
+   void * object_1,
+   size_t size_1,
+   void * object_2,
+   size_t size_2)
+{
+   return -1;
+}
+
+uint32_t pnal_get_system_uptime_10ms (void)
+{
+   uint32_t uptime = 0;
+
+   MIB2_COPY_SYSUPTIME_TO (&uptime);
+   return uptime;
+}
+
+pnal_buf_t * pnal_buf_alloc (uint16_t length)
+{
+   return pbuf_alloc (PBUF_RAW, length, PBUF_POOL);
+}
+
+void pnal_buf_free (pnal_buf_t * p)
+{
+   CC_ASSERT (pbuf_free (p) == 1);
+}
+
+uint8_t pnal_buf_header (pnal_buf_t * p, int16_t header_size_increment)
+{
+   return pbuf_header (p, header_size_increment);
+}
\ No newline at end of file
diff --git a/src/ports/iMX8M/pnal_config.h b/src/ports/iMX8M/pnal_config.h
new file mode 100644
index 00000000..3eed49ef
--- /dev/null
+++ b/src/ports/iMX8M/pnal_config.h
@@ -0,0 +1,49 @@
+/*********************************************************************
+ *        _       _         _
+ *  _ __ | |_  _ | |  __ _ | |__   ___
+ * | '__|| __|(_)| | / _` || '_ \ / __|
+ * | |   | |_  _ | || (_| || |_) |\__ \
+ * |_|    \__|(_)|_| \__,_||_.__/ |___/
+ *
+ * www.rt-labs.com
+ * Copyright 2021 rt-labs AB, Sweden.
+ *
+ * This software is dual-licensed under GPLv3 and a commercial
+ * license. See the file LICENSE.md distributed with this software for
+ * full license information.
+ ********************************************************************/
+
+/**
+ * @file
+ * @brief PNAL-specific configuration
+ *
+ * This file contains definitions of configuration settings for the
+ * PNAL layer.
+ */
+
+#ifndef PNAL_CONFIG_H
+#define PNAL_CONFIG_H
+
+#include <stdint.h>
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct pnal_thread_cfg
+{
+   uint32_t prio;
+   size_t stack_size;
+} pnal_thread_cfg_t;
+
+typedef struct pnal_cfg
+{
+   pnal_thread_cfg_t bg_worker_thread;
+} pnal_cfg_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PNAL_CONFIG_H */
diff --git a/src/ports/iMX8M/pnal_eth.c b/src/ports/iMX8M/pnal_eth.c
new file mode 100644
index 00000000..7feaf44c
--- /dev/null
+++ b/src/ports/iMX8M/pnal_eth.c
@@ -0,0 +1,191 @@
+/*********************************************************************
+ *        _       _         _
+ *  _ __ | |_  _ | |  __ _ | |__   ___
+ * | '__|| __|(_)| | / _` || '_ \ / __|
+ * | |   | |_  _ | || (_| || |_) |\__ \
+ * |_|    \__|(_)|_| \__,_||_.__/ |___/
+ *
+ * www.rt-labs.com
+ * Copyright 2021 rt-labs AB, Sweden.
+ * Copyright 2023 NXP
+ *
+ * This software is dual-licensed under GPLv3 and a commercial
+ * license. See the file LICENSE.md distributed with this software for
+ * full license information.
+ ********************************************************************/
+
+/**
+ * @file
+ * @brief i.MX8M Ethernet related functions that use \a pnal_eth_handle_t
+ */
+
+#include "pnal.h"
+#include "osal_log.h"
+
+#include <lwip/netif.h>
+#include <lwip/apps/snmp_core.h>
+
+#define MAX_NUMBER_OF_IF 1
+
+struct pnal_eth_handle
+{
+   struct netif * netif;
+   pnal_eth_callback_t * eth_rx_callback;
+   void * arg;
+};
+
+static pnal_eth_handle_t interface[MAX_NUMBER_OF_IF];
+static int nic_index = 0;
+
+/**
+ * Find PNAL network interface handle
+ *
+ * @param netif            In:    lwip network interface.
+ * @return PNAL network interface handle corresponding to \a netif,
+ *         NULL otherwise.
+ */
+static pnal_eth_handle_t * pnal_eth_find_handle (struct netif * netif)
+{
+   pnal_eth_handle_t * handle;
+   int i;
+
+   for (i = 0; i < MAX_NUMBER_OF_IF; i++)
+   {
+      handle = &interface[i];
+      if (handle->netif == netif)
+      {
+         return handle;
+      }
+   }
+
+   return NULL;
+}
+
+/**
+ * Allocate PNAL network interface handle
+ *
+ * Handles are allocated from a static array and need never be freed.
+ *
+ * @return PNAL network interface handle if available,
+ *         NULL if too many handles were allocated.
+ */
+static pnal_eth_handle_t * pnal_eth_allocate_handle (void)
+{
+   pnal_eth_handle_t * handle;
+
+   if (nic_index < MAX_NUMBER_OF_IF)
+   {
+      handle = &interface[nic_index];
+      nic_index++;
+      return handle;
+   }
+   else
+   {
+      return NULL;
+   }
+}
+
+/**
+ * Process received Ethernet frame
+ *
+ * Called from lwip when an Ethernet frame is received with an EtherType
+ * lwip is not aware of (e.g. Profinet and LLDP).
+ *
+ * @param p_buf            InOut: Packet buffer containing Ethernet frame.
+ * @param netif            InOut: Network interface receiving the frame.
+ * @return ERR_OK if frame was processed and freed,
+ *         ERR_IF if it was ignored.
+ */
+static err_t pnal_eth_sys_recv (struct pbuf * p_buf, struct netif * netif)
+{
+   int processed;
+   pnal_eth_handle_t * handle;
+
+   handle = pnal_eth_find_handle (netif);
+   if (handle == NULL)
+   {
+      /* p-net not started yet, let lwIP handle frame */
+      return ERR_IF;
+   }
+
+   processed = handle->eth_rx_callback (handle, handle->arg, p_buf);
+   //uint8_t *data = (uint8_t*)p_buf->payload;
+   
+   /*printf("hook: ");
+   for(int i = 0; i < 50; i++)
+      printf("%02x ", data[i]);
+   printf("\n");*/
+
+   if (processed)
+   {
+      //printf("Frame processed\n");
+      /* Frame handled and freed */
+      return ERR_OK;
+   }
+   else
+   {
+      //printf("Frame not processed\n");
+      /* Frame not handled */
+      return ERR_IF;
+   }
+}
+
+err_enum_t lwip_hook_unknown_eth_protocol (
+   struct pbuf * pbuf,
+   struct netif * netif)
+{
+   return pnal_eth_sys_recv (pbuf, netif);
+}
+
+pnal_eth_handle_t * pnal_eth_init (
+   const char * if_name,
+   pnal_ethertype_t receive_type,
+   const pnal_cfg_t * pnal_cfg,
+   pnal_eth_callback_t * callback,
+   void * arg)
+{
+   pnal_eth_handle_t * handle;
+   struct netif * netif;
+
+   (void)receive_type; /* Ignore, for now all frames will be received. */
+   
+   LOCK_TCPIP_CORE();
+
+   netif = netif_find (if_name);
+   if (netif == NULL)
+   {
+      os_log (LOG_LEVEL_ERROR, "Network interface \"%s\" not found!\n", if_name);
+      return NULL;
+   }
+
+   UNLOCK_TCPIP_CORE();
+
+   handle = pnal_eth_allocate_handle();
+   if (handle == NULL)
+   {
+      os_log (LOG_LEVEL_ERROR, "Too many network interfaces\n");
+      return NULL;
+   }
+
+   handle->arg = arg;
+   handle->eth_rx_callback = callback;
+   handle->netif = netif;
+
+   return handle;
+}
+
+int pnal_eth_send (pnal_eth_handle_t * handle, pnal_buf_t * buf)
+{
+   int ret = -1;
+
+   CC_ASSERT (handle->netif->linkoutput != NULL);
+
+   if (buf != NULL)
+   {
+      buf->tot_len = buf->len;
+
+      handle->netif->linkoutput (handle->netif, buf);
+      ret = buf->len;
+   }
+   return ret;
+}
diff --git a/src/ports/iMX8M/pnal_sys.h b/src/ports/iMX8M/pnal_sys.h
new file mode 100644
index 00000000..ad9bfc4f
--- /dev/null
+++ b/src/ports/iMX8M/pnal_sys.h
@@ -0,0 +1,35 @@
+/*********************************************************************
+ *        _       _         _
+ *  _ __ | |_  _ | |  __ _ | |__   ___
+ * | '__|| __|(_)| | / _` || '_ \ / __|
+ * | |   | |_  _ | || (_| || |_) |\__ \
+ * |_|    \__|(_)|_| \__,_||_.__/ |___/
+ *
+ * www.rt-labs.com
+ * Copyright 2021 rt-labs AB, Sweden.
+ *
+ * This software is dual-licensed under GPLv3 and a commercial
+ * license. See the file LICENSE.md distributed with this software for
+ * full license information.
+ ********************************************************************/
+
+#ifndef PNAL_SYS_H
+#define PNAL_SYS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <lwip/def.h> /* For htonl etc */
+#include <lwip/pbuf.h>
+
+#define PNAL_BUF_MAX_SIZE PBUF_POOL_BUFSIZE
+
+/* Re-use lwIP pbuf for rt-kernel */
+typedef struct pbuf pnal_buf_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PNAL_SYS_H */
diff --git a/src/ports/iMX8M/pnal_udp.c b/src/ports/iMX8M/pnal_udp.c
new file mode 100644
index 00000000..0d0cd6ce
--- /dev/null
+++ b/src/ports/iMX8M/pnal_udp.c
@@ -0,0 +1,110 @@
+/*********************************************************************
+ *        _       _         _
+ *  _ __ | |_  _ | |  __ _ | |__   ___
+ * | '__|| __|(_)| | / _` || '_ \ / __|
+ * | |   | |_  _ | || (_| || |_) |\__ \
+ * |_|    \__|(_)|_| \__,_||_.__/ |___/
+ *
+ * www.rt-labs.com
+ * Copyright 2021 rt-labs AB, Sweden.
+ *
+ * This software is dual-licensed under GPLv3 and a commercial
+ * license. See the file LICENSE.md distributed with this software for
+ * full license information.
+ ********************************************************************/
+
+#include "pnal.h"
+#include "osal_log.h"
+
+#include <lwip/sockets.h>
+#include <string.h>
+
+int pnal_udp_open (pnal_ipaddr_t addr, pnal_ipport_t port)
+{
+   struct sockaddr_in local;
+   int id;
+   const int enable = 1;
+
+   id = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+   if (id == -1)
+   {
+      return -1;
+   }
+
+   if (setsockopt (id, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof (enable)) != 0)
+   {
+      goto error;
+   }
+
+   /* set IP and port number */
+   local = (struct sockaddr_in){
+      .sin_family = AF_INET,
+      .sin_addr.s_addr = htonl (addr),
+      .sin_port = htons (port),
+   };
+
+   if (bind (id, (struct sockaddr *)&local, sizeof (local)) != 0)
+   {
+      goto error;
+   }
+
+   return id;
+
+error:
+   close (id);
+   return -1;
+}
+
+int pnal_udp_sendto (
+   uint32_t id,
+   pnal_ipaddr_t dst_addr,
+   pnal_ipport_t dst_port,
+   const uint8_t * data,
+   int size)
+{
+   struct sockaddr_in remote;
+   int len;
+
+   remote = (struct sockaddr_in){
+      .sin_family = AF_INET,
+      .sin_addr.s_addr = htonl (dst_addr),
+      .sin_port = htons (dst_port),
+   };
+   len =
+      sendto (id, data, size, 0, (struct sockaddr *)&remote, sizeof (remote));
+
+   return len;
+}
+
+int pnal_udp_recvfrom (
+   uint32_t id,
+   pnal_ipaddr_t * src_addr,
+   pnal_ipport_t * src_port,
+   uint8_t * data,
+   int size)
+{
+   struct sockaddr_in remote;
+   socklen_t addr_len = sizeof (remote);
+   int len;
+
+   memset (&remote, 0, sizeof (remote));
+   len = recvfrom (
+      id,
+      data,
+      size,
+      MSG_DONTWAIT,
+      (struct sockaddr *)&remote,
+      &addr_len);
+   if (len > 0)
+   {
+      *src_addr = ntohl (remote.sin_addr.s_addr);
+      *src_port = ntohs (remote.sin_port);
+   }
+
+   return len;
+}
+
+void pnal_udp_close (uint32_t id)
+{
+   close (id);
+}
diff --git a/src/ports/iMX8M/sampleapp_imx8mmevk.c b/src/ports/iMX8M/sampleapp_imx8mmevk.c
new file mode 100644
index 00000000..04003214
--- /dev/null
+++ b/src/ports/iMX8M/sampleapp_imx8mmevk.c
@@ -0,0 +1,42 @@
+/*********************************************************************
+ *        _       _         _
+ *  _ __ | |_  _ | |  __ _ | |__   ___
+ * | '__|| __|(_)| | / _` || '_ \ / __|
+ * | |   | |_  _ | || (_| || |_) |\__ \
+ * |_|    \__|(_)|_| \__,_||_.__/ |___/
+ *
+ * www.rt-labs.com
+ * Copyright 2021 rt-labs AB, Sweden.
+ * Copyright 2023 NXP
+ *
+ * This software is dual-licensed under GPLv3 and a commercial
+ * license. See the file LICENSE.md distributed with this software for
+ * full license information.
+ ********************************************************************/
+
+#include "sampleapp_common.h"
+#include "fsl_gpio.h"
+
+/************************* Utilities ******************************************/
+
+void app_set_led (uint16_t pin, bool led_state)
+{
+   if (pin == APP_DATA_LED_ID)
+      GPIO_WritePinOutput(GPIO5, 13, led_state ? true : false);
+   else if (pin == APP_PROFINET_SIGNAL_LED_ID) 
+      GPIO_WritePinOutput(GPIO5, 10, led_state ? true : false);
+}
+
+bool app_get_button (uint16_t id)
+{
+   if (id == 0)
+   {
+      return (bool)GPIO_ReadPinInput(GPIO5, 12);
+   }
+   else if (id == 1)
+   {
+      // No more buttons on i.MX 8M Mini 
+   }
+   return false;
+}
+
diff --git a/src/ports/iMX8M/sampleapp_main.c b/src/ports/iMX8M/sampleapp_main.c
new file mode 100644
index 00000000..ace9c60e
--- /dev/null
+++ b/src/ports/iMX8M/sampleapp_main.c
@@ -0,0 +1,108 @@
+/*********************************************************************
+ *        _       _         _
+ *  _ __ | |_  _ | |  __ _ | |__   ___
+ * | '__|| __|(_)| | / _` || '_ \ / __|
+ * | |   | |_  _ | || (_| || |_) |\__ \
+ * |_|    \__|(_)|_| \__,_||_.__/ |___/
+ *
+ * www.rt-labs.com
+ * Copyright 2021 rt-labs AB, Sweden.
+ * Copyright 2023 NXP
+ *
+ * This software is dual-licensed under GPLv3 and a commercial
+ * license. See the file LICENSE.md distributed with this software for
+ * full license information.
+ ********************************************************************/
+
+#include "sampleapp_common.h"
+#include "app_utils.h"
+#include "app_log.h"
+#include "app_gsdml.h"
+
+#include "osal_log.h"
+#include "osal.h"
+#include <pnet_api.h>
+
+#define APP_DEFAULT_ETHERNET_INTERFACE "en0"
+#define APP_DEFAULT_FILE_DIRECTORY     ""
+#define APP_LOG_LEVEL                  APP_LOG_LEVEL_INFO
+
+#define APP_BG_WORKER_THREAD_PRIORITY  2
+#define APP_BG_WORKER_THREAD_STACKSIZE 4096 /* bytes */
+
+/********************************** Globals ***********************************/
+
+static app_data_t * sample_app = NULL;
+static pnet_cfg_t pnet_cfg = {0};
+app_args_t app_args = {0};
+
+/****************************** Main ******************************************/
+
+int _main (void)
+{
+   int ret;
+   app_utils_netif_namelist_t netif_name_list;
+   pnet_if_cfg_t netif_cfg = {0};
+   uint16_t number_of_ports;
+
+   strcpy (app_args.eth_interfaces, APP_DEFAULT_ETHERNET_INTERFACE);
+   strcpy (app_args.station_name, APP_GSDML_DEFAULT_STATION_NAME);
+   app_log_set_log_level (APP_LOG_LEVEL);
+
+   APP_LOG_INFO ("\n** Starting P-Net sample application " PNET_VERSION
+                 " **\n");
+   APP_LOG_INFO (
+      "Number of slots:      %u (incl slot for DAP module)\n",
+      PNET_MAX_SLOTS);
+   APP_LOG_INFO ("P-net log level:      %u (DEBUG=0, FATAL=4)\n", LOG_LEVEL);
+   APP_LOG_INFO ("App log level:        %u (DEBUG=0, FATAL=4)\n", APP_LOG_LEVEL);
+   APP_LOG_INFO ("Max number of ports:  %u\n", PNET_MAX_PHYSICAL_PORTS);
+   APP_LOG_INFO ("Network interfaces:   %s\n", app_args.eth_interfaces);
+   APP_LOG_INFO ("Default station name: %s\n", app_args.station_name);
+
+   app_pnet_cfg_init_default (&pnet_cfg);
+
+   /* Note: station name is defined by app_gsdml.h */
+
+   strcpy (pnet_cfg.file_directory, APP_DEFAULT_FILE_DIRECTORY);
+
+   ret = app_utils_pnet_cfg_init_netifs (
+      app_args.eth_interfaces,
+      &netif_name_list,
+      &number_of_ports,
+      &netif_cfg);
+   if (ret != 0)
+   {
+      return -1;
+   }
+
+   pnet_cfg.if_cfg = netif_cfg;
+   pnet_cfg.num_physical_ports = number_of_ports;
+
+   app_utils_print_network_config (&netif_cfg, number_of_ports);
+
+   pnet_cfg.pnal_cfg.bg_worker_thread.prio = APP_BG_WORKER_THREAD_PRIORITY;
+   pnet_cfg.pnal_cfg.bg_worker_thread.stack_size =
+      APP_BG_WORKER_THREAD_STACKSIZE;
+
+   /* Initialize profinet stack */
+   sample_app = app_init (&pnet_cfg, &app_args);
+   if (sample_app == NULL)
+   {
+      printf ("Failed to initialize P-Net.\n");
+      printf ("Aborting application\n");
+      return -1;
+   }
+
+   /* Start main loop */
+   if (app_start (sample_app, RUN_IN_MAIN_THREAD) != 0)
+   {
+      printf ("Failed to start\n");
+      printf ("Aborting application\n");
+      return -1;
+   }
+
+   app_loop_forever (sample_app);
+
+   return 0;
+}