Skip to content

Commit 0e20c71

Browse files
fredrikdanielmollerhefloryd
authored andcommitted
rt-kernel: Use lwip hook function
This removes the xmc4-specific hook function serving the same purpose, replacing it with a platform-agnostic hook function. A drawback with this solution is that the frame receive handler now checks if frame is a Profinet frame only after it has checked for IP/ARP (see ethernet_input() in lwip source tree). This will increase latency somewhat. The patch file was updated with changes in lwip to support this: - LWIP_HOOK_UNKNOWN_ETH_PROTOCOL was enabled. - An API function for setting hook function was added. If no such hook function is set, received frames of unknown type will be dropped. - To avoid an extra context switch when handling received frame, LWIP_TCPIP_CORE_LOCKING_INPUT was activated.
1 parent 5e257e7 commit 0e20c71

File tree

4 files changed

+220
-86
lines changed

4 files changed

+220
-86
lines changed

src/ports/rt-kernel/0001-rtkernel-for-Profinet.patch

Lines changed: 113 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
From 337d268fa4701e10cec14bedb9732d049ff3e387 Mon Sep 17 00:00:00 2001
1+
From 3dd5f871c118cdbc98c6068165a7eeef4ac5d245 Mon Sep 17 00:00:00 2001
22
From: =?UTF-8?q?Fredrik=20M=C3=B6ller?= <[email protected]>
33
Date: Tue, 15 Sep 2020 18:22:53 +0200
44
Subject: [PATCH] rtkernel for Profinet
@@ -12,6 +12,12 @@ stack:
1212
- Fix SNMP ifDescr in ifTable.
1313
- Discard invalid UDP packets.
1414
- VLAN tag support.
15+
- Lock mutex while handling received frame
16+
instead of passing message to lwip thread
17+
(LWIP_TCPIP_CORE_LOCKING_INPUT).
18+
- Add hook function to be called when frame of
19+
unknown EtherType is received, such as LLDP
20+
and Profinet (LWIP_HOOK_UNKNOWN_ETH_PROTOCOL).
1521
- bsp/xmc48relax:
1622
- Static IP addressing.
1723
- Increase stack size for main task.
@@ -26,12 +32,16 @@ stack:
2632
lwip/src/apps/snmp/Makefile | 16 ++
2733
lwip/src/apps/snmp/snmp_mib2_interfaces.c | 6 +-
2834
lwip/src/apps/snmp/snmp_mib2_system.c | 309 ++--------------------
35+
lwip/src/core/lwip_hooks.c | 23 ++
2936
lwip/src/core/udp.c | 12 +
3037
lwip/src/include/lwip/apps/snmp_mib2.h | 24 +-
31-
lwip/src/include/lwip/lwipopts.h | 23 +-
32-
11 files changed, 133 insertions(+), 309 deletions(-)
38+
lwip/src/include/lwip/lwip_hooks.h | 41 +++
39+
lwip/src/include/lwip/lwipopts.h | 39 ++-
40+
13 files changed, 213 insertions(+), 309 deletions(-)
3341
create mode 100644 lwip/src/apps/Makefile
3442
create mode 100644 lwip/src/apps/snmp/Makefile
43+
create mode 100644 lwip/src/core/lwip_hooks.c
44+
create mode 100644 lwip/src/include/lwip/lwip_hooks.h
3545

3646
diff --git a/bsp/xmc48relax/include/config.h b/bsp/xmc48relax/include/config.h
3747
index 850ce674..07d80b1e 100644
@@ -567,6 +577,35 @@ index 90e57805..0242ce5c 100644
567577
}
568578

569579
static const struct snmp_scalar_array_node_def system_nodes[] = {
580+
diff --git a/lwip/src/core/lwip_hooks.c b/lwip/src/core/lwip_hooks.c
581+
new file mode 100644
582+
index 00000000..ad6229f8
583+
--- /dev/null
584+
+++ b/lwip/src/core/lwip_hooks.c
585+
@@ -0,0 +1,23 @@
586+
+#include "lwip/lwip_hooks.h"
587+
+
588+
+#ifdef LWIP_HOOK_UNKNOWN_ETH_PROTOCOL
589+
+static netif_input_fn lwip_hook_for_unknown_eth_protocol;
590+
+
591+
+err_enum_t lwip_hook_unknown_eth_protocol(struct pbuf *pbuf, struct netif *netif)
592+
+{
593+
+ if(lwip_hook_for_unknown_eth_protocol == NULL)
594+
+ {
595+
+ /* Not handled. User needs to free pbuf */
596+
+ return ERR_IF;
597+
+ }
598+
+ else
599+
+ {
600+
+ return lwip_hook_for_unknown_eth_protocol(pbuf, netif);
601+
+ }
602+
+}
603+
+
604+
+void lwip_set_hook_for_unknown_eth_protocol(struct netif *netif, netif_input_fn hook)
605+
+{
606+
+ lwip_hook_for_unknown_eth_protocol = hook;
607+
+}
608+
+#endif /* LWIP_HOOK_UNKNOWN_ETH_PROTOCOL */
570609
diff --git a/lwip/src/core/udp.c b/lwip/src/core/udp.c
571610
index ce2e3d29..7946cb05 100644
572611
--- a/lwip/src/core/udp.c
@@ -625,11 +664,62 @@ index 2f4a6893..1df6bb0d 100644
625664

626665
#endif /* SNMP_LWIP_MIB2 */
627666
#endif /* LWIP_SNMP */
667+
diff --git a/lwip/src/include/lwip/lwip_hooks.h b/lwip/src/include/lwip/lwip_hooks.h
668+
new file mode 100644
669+
index 00000000..c48f1c57
670+
--- /dev/null
671+
+++ b/lwip/src/include/lwip/lwip_hooks.h
672+
@@ -0,0 +1,41 @@
673+
+/**
674+
+ * Hook functions
675+
+ *
676+
+ * Declares hook functions called by lwip.
677+
+ * Also declared API for configuring hook functions.
678+
+ *
679+
+ * The name of this file is specified as LWIP_HOOK_FILENAME in lwipopts.h.
680+
+ */
681+
+
682+
+#ifndef LWIP_HOOKS_H
683+
+#define LWIP_HOOKS_H
684+
+
685+
+#include "lwip/netif.h"
686+
+
687+
+/**
688+
+ * LWIP_HOOK_UNKNOWN_ETH_PROTOCOL
689+
+ *
690+
+ * Called from ethernet_input() when an unknown eth type is encountered.
691+
+ *
692+
+ * By default, this will do nothing and return ERR_IF.
693+
+ * If a hook function has been set in lwip_set_hook_for_unknown_eth_protocol(),
694+
+ * then that function will be called.
695+
+ *
696+
+ * \param pbuf Payload points to ethernet header!
697+
+ * \param netif Network interface.
698+
+ * \return ERR_OK if packet is accepted and freed,
699+
+ * ERR_IF otherwise.
700+
+ */
701+
+err_enum_t lwip_hook_unknown_eth_protocol(struct pbuf *pbuf, struct netif *netif);
702+
+
703+
+/**
704+
+ * Configure function to be called by lwip_hook_unknown_eth_protocol()
705+
+ *
706+
+ *\param netif Network interface.
707+
+ *\param hook Hook function to be called when frame with unknown eth type
708+
+ * is encountered. Should return ERR_OK for accepted and freed
709+
+ * frames, ERR_IF otherwise.
710+
+ */
711+
+void lwip_set_hook_for_unknown_eth_protocol(struct netif *netif, netif_input_fn hook);
712+
+
713+
+#endif /* LWIP_HOOKS_H */
628714
diff --git a/lwip/src/include/lwip/lwipopts.h b/lwip/src/include/lwip/lwipopts.h
629-
index c48a69b7..941e6f9c 100644
715+
index c48a69b7..c3fdf058 100644
630716
--- a/lwip/src/include/lwip/lwipopts.h
631717
+++ b/lwip/src/include/lwip/lwipopts.h
632-
@@ -49,7 +49,12 @@
718+
@@ -46,10 +46,31 @@
719+
#define LWIP_NETIF_LINK_CALLBACK 1
720+
#define LWIP_NETIF_STATUS_CALLBACK 1
721+
#define LWIP_NETIF_LOOPBACK 1
722+
+#define LWIP_TCPIP_CORE_LOCKING_INPUT 1
633723
#define LWIP_SOCKET 1
634724
#define LWIP_IGMP 1
635725
#define LWIP_TCP_KEEPALIVE 1
@@ -639,10 +729,25 @@ index c48a69b7..941e6f9c 100644
639729
+#define MIB2_STATS 1
640730
#define SO_REUSE 1
641731
+#define ETHARP_SUPPORT_VLAN 1
732+
+
733+
+/**
734+
+ * LWIP_HOOK_FILENAME: Custom filename to #include in files that provide hooks.
735+
+ * Declare your hook function prototypes in there, you may also #include all headers
736+
+ * providing data types that are need in this file.
737+
+ */
738+
+#define LWIP_HOOK_FILENAME "lwip/lwip_hooks.h"
739+
+
740+
+/**
741+
+ * LWIP_HOOK_UNKNOWN_ETH_PROTOCOL(pbuf, netif):
742+
+ * Called from ethernet_input() when an unknown eth type is encountered.
743+
+ * Return ERR_OK if packet is accepted, any error code otherwise.
744+
+ * Payload points to ethernet header!
745+
+ */
746+
+#define LWIP_HOOK_UNKNOWN_ETH_PROTOCOL lwip_hook_unknown_eth_protocol
642747

643748
/**
644749
* LWIP_DHCP_AUTOIP_COOP_TRIES: Set to the number of DHCP DISCOVER probes
645-
@@ -60,20 +65,33 @@
750+
@@ -60,20 +81,33 @@
646751
*/
647752
#define LWIP_DHCP_AUTOIP_COOP_TRIES 2
648753

@@ -677,15 +782,15 @@ index c48a69b7..941e6f9c 100644
677782
/* Mailbox sizes */
678783
#define TCPIP_MBOX_SIZE 128
679784
#define DEFAULT_RAW_RECVMBOX_SIZE 5
680-
@@ -106,6 +124,7 @@
785+
@@ -106,6 +140,7 @@
681786
* LWIP_DBG_OFF
682787
* LWIP_DBG_ON
683788
*/
684789
+#define PBUF_DEBUG LWIP_DBG_OFF
685790
#define IP_DEBUG LWIP_DBG_OFF
686791
#define IGMP_DEBUG LWIP_DBG_OFF
687792
#define TCPIP_DEBUG LWIP_DBG_OFF
688-
@@ -120,5 +139,7 @@
793+
@@ -120,5 +155,7 @@
689794
#define TCP_FR_DEBUG LWIP_DBG_OFF
690795
#define TCP_QLEN_DEBUG LWIP_DBG_OFF
691796
#define TCP_RST_DEBUG LWIP_DBG_OFF

src/ports/rt-kernel/dwmac1000.c

Lines changed: 5 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -254,9 +254,6 @@ typedef struct dwmac1000
254254
uint16_t anar;
255255
} dwmac1000_t;
256256

257-
static pnal_eth_sys_recv_callback_t * input_rx_hook = NULL;
258-
static void * input_rx_arg = NULL;
259-
260257
#ifdef DEBUG_DATA
261258
#include <ctype.h>
262259
static void dwmac1000_pbuf_dump (struct pbuf * p)
@@ -636,10 +633,8 @@ static struct pbuf * dwmac1000_hw_get_received_frame (struct netif * netif)
636633
* called.
637634
*
638635
*/
639-
static void dwmac1000_input (dwmac1000_t * dwmac1000, struct netif * netif)
636+
static void dwmac1000_input (struct netif * netif)
640637
{
641-
int handled = 0;
642-
struct eth_hdr * ethhdr;
643638
struct pbuf * p;
644639

645640
/* Move received packet into a new pbuf */
@@ -650,35 +645,11 @@ static void dwmac1000_input (dwmac1000_t * dwmac1000, struct netif * netif)
650645
return;
651646
}
652647

653-
/* points to packet payload, which starts with an Ethernet header */
654-
ethhdr = p->payload;
655-
656-
/* Pass pbuf to rx hook if set */
657-
if (input_rx_hook != NULL)
648+
/* pass all packets to netif input, which decides what packets it supports */
649+
if (netif->input (p, netif) != (err_t)ERR_OK)
658650
{
659-
handled = input_rx_hook (netif, input_rx_arg, p);
660-
if (handled != 0)
661-
{
662-
return;
663-
}
664-
/* Else pass it to lwIP */
665-
}
666-
667-
switch (htons (ethhdr->type))
668-
{
669-
case ETHTYPE_VLAN:
670-
case ETHTYPE_IP:
671-
/* Fall-through */
672-
case ETHTYPE_ARP:
673-
if (netif->input (p, netif) != (err_t)ERR_OK)
674-
{
675-
LWIP_DEBUGF (NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
676-
pbuf_free (p);
677-
}
678-
break;
679-
default:
651+
LWIP_DEBUGF (NETIF_DEBUG, ("dwmac1000: IP input error\n"));
680652
pbuf_free (p);
681-
break;
682653
}
683654
}
684655

@@ -704,7 +675,7 @@ static void dwmac1000_receiver (void * arg)
704675
while ((dwmac1000->pRx->des0 & xDES0_OWN) == 0)
705676
{
706677
/* Get one packet */
707-
dwmac1000_input (dwmac1000, netif);
678+
dwmac1000_input (netif);
708679

709680
/* Move to next descriptor */
710681
dwmac1000->pRx = dwmac1000->pRx->next;
@@ -788,10 +759,6 @@ int eth_ioctl (drv_t * drv, void * arg, int req, void * param)
788759

789760
switch (req)
790761
{
791-
case IOCTL_NET_SET_RX_HOOK:
792-
input_rx_hook = (pnal_eth_sys_recv_callback_t *)param;
793-
input_rx_arg = arg;
794-
return 0;
795762
case IOCTL_NET_GET_STATUS:
796763
dwmac1000_get_status (dwmac1000, arg, param);
797764
return 0;

0 commit comments

Comments
 (0)