1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

pkg/lwip: use sys/event for handling ISR and bhp

This is directly useful for the two driver using the bhp API, but also
other drivers profit from not loosing IRQs.

The main selling point is that this paves the way for implementing
netdev_driver_t::confirm_send().

Co-authored-by: benpicco <benpicco@googlemail.com>
Co-authored-by: Erik Ekman <eekman@google.com>
This commit is contained in:
Marian Buschsieweke 2022-07-22 14:11:19 +02:00 committed by Marian Buschsieweke
parent 925644e4ce
commit 7277d1d351
No known key found for this signature in database
GPG Key ID: 77AA882EC78084E6
6 changed files with 86 additions and 104 deletions

View File

@ -3,6 +3,7 @@
FEATURES_REQUIRED_ANY += arch_32bit|arch_64bit FEATURES_REQUIRED_ANY += arch_32bit|arch_64bit
DEFAULT_MODULE += auto_init_lwip DEFAULT_MODULE += auto_init_lwip
USEMODULE += event
ifneq (,$(filter sock_async,$(USEMODULE))) ifneq (,$(filter sock_async,$(USEMODULE)))
USEMODULE += lwip_sock_async USEMODULE += lwip_sock_async
@ -90,7 +91,7 @@ ifneq (,$(filter lwip_contrib,$(USEMODULE)))
USEMODULE += sema USEMODULE += sema
USEMODULE += ztimer_msec USEMODULE += ztimer_msec
ifneq (,$(filter bhp,$(USEMODULE))) ifneq (,$(filter bhp,$(USEMODULE)))
USEMODULE += bhp_msg USEMODULE += bhp_event
endif endif
endif endif

View File

@ -14,26 +14,27 @@
*/ */
#include <assert.h> #include <assert.h>
#include <sys/uio.h>
#include <inttypes.h> #include <inttypes.h>
#include <sys/uio.h>
#include "architecture.h"
#include "event.h"
#include "lwip.h"
#include "lwip/err.h" #include "lwip/err.h"
#include "lwip/ethip6.h" #include "lwip/ethip6.h"
#include "lwip/netif.h" #include "lwip/netif.h"
#include "lwip/netifapi.h"
#include "lwip/netif/compat.h" #include "lwip/netif/compat.h"
#include "lwip/netif/netdev.h" #include "lwip/netif/netdev.h"
#include "lwip/netifapi.h"
#include "lwip/opt.h" #include "lwip/opt.h"
#include "lwip/pbuf.h" #include "lwip/pbuf.h"
#include "netif/etharp.h"
#include "netif/lowpan6.h"
#include "net/eui64.h" #include "net/eui64.h"
#include "net/ieee802154.h" #include "net/ieee802154.h"
#include "net/ipv6/addr.h" #include "net/ipv6/addr.h"
#include "net/netdev.h" #include "net/netdev.h"
#include "net/netopt.h" #include "net/netopt.h"
#include "utlist.h" #include "netif/etharp.h"
#include "netif/lowpan6.h"
#include "thread.h" #include "thread.h"
#define ENABLE_DEBUG 0 #define ENABLE_DEBUG 0
@ -42,7 +43,6 @@
#define LWIP_NETDEV_NAME "lwip_netdev_mux" #define LWIP_NETDEV_NAME "lwip_netdev_mux"
#define LWIP_NETDEV_PRIO (THREAD_PRIORITY_MAIN - 4) #define LWIP_NETDEV_PRIO (THREAD_PRIORITY_MAIN - 4)
#define LWIP_NETDEV_STACKSIZE (THREAD_STACKSIZE_DEFAULT) #define LWIP_NETDEV_STACKSIZE (THREAD_STACKSIZE_DEFAULT)
#define LWIP_NETDEV_QUEUE_LEN (8)
#define LWIP_NETDEV_MSG_TYPE_EVENT 0x1235 #define LWIP_NETDEV_MSG_TYPE_EVENT 0x1235
#define ETHERNET_IFNAME1 'E' #define ETHERNET_IFNAME1 'E'
@ -51,9 +51,10 @@
#define WPAN_IFNAME1 'W' #define WPAN_IFNAME1 'W'
#define WPAN_IFNAME2 'P' #define WPAN_IFNAME2 'P'
event_queue_t lwip_event_queue = { 0 };
static kernel_pid_t _pid = KERNEL_PID_UNDEF; static kernel_pid_t _pid = KERNEL_PID_UNDEF;
static char _stack[LWIP_NETDEV_STACKSIZE]; static WORD_ALIGNED char _stack[LWIP_NETDEV_STACKSIZE];
static msg_t _queue[LWIP_NETDEV_QUEUE_LEN];
static char _tmp_buf[LWIP_NETDEV_BUFLEN]; static char _tmp_buf[LWIP_NETDEV_BUFLEN];
#ifdef MODULE_NETDEV_ETH #ifdef MODULE_NETDEV_ETH
@ -73,11 +74,14 @@ static err_t slip_output6(struct netif *netif, struct pbuf *q, const ip6_addr_t
#endif #endif
static void _event_cb(netdev_t *dev, netdev_event_t event); static void _event_cb(netdev_t *dev, netdev_event_t event);
static void *_event_loop(void *arg); static void *_event_loop(void *arg);
static void _isr(event_t *ev);
err_t lwip_netdev_init(struct netif *netif) err_t lwip_netdev_init(struct netif *netif)
{ {
LWIP_ASSERT("netif != NULL", (netif != NULL)); LWIP_ASSERT("netif != NULL", (netif != NULL));
LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
lwip_netif_t *compat_netif = container_of(netif, lwip_netif_t, lwip_netif);
compat_netif->ev_isr.handler = _isr;
netdev_t *netdev; netdev_t *netdev;
netopt_enable_t enabled = 0; netopt_enable_t enabled = 0;
uint16_t dev_type; uint16_t dev_type;
@ -96,11 +100,6 @@ err_t lwip_netdev_init(struct netif *netif)
} }
} }
/* initialize Bottom Half Processor, netdev and netif */
if (IS_USED(MODULE_BHP_MSG)) {
bhp_msg_claim_thread(lwip_netif_get_bhp(netif), _pid);
}
netdev = netif->state; netdev = netif->state;
lwip_netif_dev_acquire(netif); lwip_netif_dev_acquire(netif);
netdev->event_callback = _event_cb; netdev->event_callback = _event_cb;
@ -364,22 +363,16 @@ static struct pbuf *_get_recv_pkt(netdev_t *dev)
static void _event_cb(netdev_t *dev, netdev_event_t event) static void _event_cb(netdev_t *dev, netdev_event_t event)
{ {
if (event == NETDEV_EVENT_ISR) { lwip_netif_t *compat_netif = dev->context;
assert(_pid != KERNEL_PID_UNDEF); assert(compat_netif != NULL);
msg_t msg; struct netif *netif = &compat_netif->lwip_netif;
msg.type = LWIP_NETDEV_MSG_TYPE_EVENT; switch (event) {
msg.content.ptr = dev; case NETDEV_EVENT_ISR:
event_post(&lwip_event_queue, &compat_netif->ev_isr);
if (msg_send(&msg, _pid) <= 0) { break;
DEBUG("lwip_netdev: possibly lost interrupt.\n"); case NETDEV_EVENT_RX_COMPLETE:
} {
}
else {
lwip_netif_t *compat_netif = dev->context;
struct netif *netif = &compat_netif->lwip_netif;
switch (event) {
case NETDEV_EVENT_RX_COMPLETE: {
struct pbuf *p = _get_recv_pkt(dev); struct pbuf *p = _get_recv_pkt(dev);
if (p == NULL) { if (p == NULL) {
DEBUG("lwip_netdev: error receiving packet\n"); DEBUG("lwip_netdev: error receiving packet\n");
@ -389,40 +382,35 @@ static void _event_cb(netdev_t *dev, netdev_event_t event)
DEBUG("lwip_netdev: error inputing packet\n"); DEBUG("lwip_netdev: error inputing packet\n");
return; return;
} }
break;
}
case NETDEV_EVENT_LINK_UP: {
/* Will wake up DHCP state machine */
netifapi_netif_set_link_up(netif);
break;
}
case NETDEV_EVENT_LINK_DOWN: {
netifapi_netif_set_link_down(netif);
break;
}
default:
break;
} }
break;
case NETDEV_EVENT_LINK_UP:
/* Will wake up DHCP state machine */
netifapi_netif_set_link_up(netif);
break;
case NETDEV_EVENT_LINK_DOWN:
netifapi_netif_set_link_down(netif);
break;
default:
break;
} }
} }
static void _isr(event_t *ev)
{
lwip_netif_t *compat_netif = container_of(ev, lwip_netif_t, ev_isr);
netdev_t *dev = compat_netif->lwip_netif.state;
dev->driver->isr(dev);
}
static void *_event_loop(void *arg) static void *_event_loop(void *arg)
{ {
struct netif *netif = arg; (void)arg;
msg_init_queue(_queue, LWIP_NETDEV_QUEUE_LEN); event_queue_claim(&lwip_event_queue);
while (1) { event_loop(&lwip_event_queue);
msg_t msg;
msg_receive(&msg); /* this should never be reached */
if (msg.type == LWIP_NETDEV_MSG_TYPE_EVENT) { assert(0);
netdev_t *dev = msg.content.ptr;
lwip_netif_dev_acquire(netif);
dev->driver->isr(dev);
lwip_netif_dev_release(netif);
}
else if (IS_USED(MODULE_BHP_MSG) && msg.type == BHP_MSG_BH_REQUEST) {
bhp_msg_handler(&msg);
}
}
return NULL; return NULL;
} }

View File

@ -19,10 +19,17 @@
#ifndef LWIP_H #ifndef LWIP_H
#define LWIP_H #define LWIP_H
#include "event.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/**
* @brief event queue for netdev events
*/
extern event_queue_t lwip_event_queue;
/** /**
* @brief Initializes lwIP stack. * @brief Initializes lwIP stack.
* *

View File

@ -20,9 +20,10 @@
#ifndef LWIP_NETIF_COMPAT_H #ifndef LWIP_NETIF_COMPAT_H
#define LWIP_NETIF_COMPAT_H #define LWIP_NETIF_COMPAT_H
#include "bhp/event.h"
#include "event.h"
#include "lwip/netif.h" #include "lwip/netif.h"
#include "net/netif.h" #include "net/netif.h"
#include "bhp/msg.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -32,11 +33,12 @@ extern "C" {
* @brief Representation of a network interface * @brief Representation of a network interface
*/ */
typedef struct { typedef struct {
netif_t common_netif; /**< network interface descriptor */ netif_t common_netif; /**< network interface descriptor */
struct netif lwip_netif; /**< lwIP interface data */ struct netif lwip_netif; /**< lwIP interface data */
rmutex_t lock; /**< lock for the interface */ rmutex_t lock; /**< lock for the interface */
#if IS_USED(MODULE_BHP_MSG) event_t ev_isr; /**< ISR event */
bhp_msg_t bhp; /**< IPC Bottom Half Processor */ #ifdef MODULE_BHP_EVENT
bhp_event_t bhp; /**< IPC Bottom Half Processor */
#endif #endif
} lwip_netif_t; } lwip_netif_t;
@ -73,26 +75,6 @@ static inline void lwip_netif_dev_release(struct netif *netif)
rmutex_unlock(&compat_netif->lock); rmutex_unlock(&compat_netif->lock);
} }
/**
* @brief Get the IPC based Bottom Half Processor for LWIP
*
* @param[in] netif pointer to the LWIP network interface
*
* @return pointer to the IPC based Bottom Half Processor descriptor, if
* @ref sys_bhp_msg is present.
* @return NULL otherwise
*/
static inline bhp_msg_t *lwip_netif_get_bhp(struct netif *netif)
{
#if IS_USED(MODULE_BHP_MSG)
lwip_netif_t *compat_netif = container_of(netif, lwip_netif_t, lwip_netif);
return &compat_netif->bhp;
#else
(void) netif;
return NULL;
#endif
}
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -1,11 +1,11 @@
/* /*
* Copyright (C) 2022 HAW Hamburg * Copyright (C) 2022 HAW Hamburg
* *
* This file is subject to the terms and conditions of the GNU Lesser * This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level * General Public License v2.1. See the file LICENSE in the top level
* directory for more details. * directory for more details.
* *
*/ */
/** /**
* @ingroup sys_auto_init_lwip_netif * @ingroup sys_auto_init_lwip_netif
@ -20,9 +20,10 @@
#include "kw2xrf.h" #include "kw2xrf.h"
#include "kw2xrf_params.h" #include "kw2xrf_params.h"
#include "lwip.h"
#include "lwip_init_devs.h" #include "lwip_init_devs.h"
#include "bhp/msg.h" #include "bhp/event.h"
#include "net/netdev/ieee802154_submac.h" #include "net/netdev/ieee802154_submac.h"
#define ENABLE_DEBUG 0 #define ENABLE_DEBUG 0
@ -37,9 +38,10 @@ static netdev_ieee802154_submac_t kw2xrf_netdev[NETIF_KW2XRF_NUMOF];
static void auto_init_kw2xrf(void) static void auto_init_kw2xrf(void)
{ {
for (unsigned i = 0; i < NETIF_KW2XRF_NUMOF; i++) { for (unsigned i = 0; i < NETIF_KW2XRF_NUMOF; i++) {
bhp_msg_init(&netif[i].bhp, &kw2xrf_radio_hal_irq_handler, &kw2xrf_netdev[i].submac.dev); bhp_event_init(&netif[i].bhp, &lwip_event_queue,
&kw2xrf_radio_hal_irq_handler, &kw2xrf_netdev[i].submac.dev);
kw2xrf_init(&kw2xrf_devs[i], &kw2xrf_params[i], &kw2xrf_netdev[i].submac.dev, kw2xrf_init(&kw2xrf_devs[i], &kw2xrf_params[i], &kw2xrf_netdev[i].submac.dev,
bhp_msg_isr_cb, &netif[i].bhp); bhp_event_isr_cb, &netif[i].bhp);
netdev_register(&kw2xrf_netdev[i].dev.netdev, NETDEV_KW2XRF, i); netdev_register(&kw2xrf_netdev[i].dev.netdev, NETDEV_KW2XRF, i);
netdev_ieee802154_submac_init(&kw2xrf_netdev[i]); netdev_ieee802154_submac_init(&kw2xrf_netdev[i]);

View File

@ -1,11 +1,11 @@
/* /*
* Copyright (C) 2017 Neo Nenaco <neo@nenaco.de> * Copyright (C) 2017 Neo Nenaco <neo@nenaco.de>
* *
* This file is subject to the terms and conditions of the GNU Lesser * This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level * General Public License v2.1. See the file LICENSE in the top level
* directory for more details. * directory for more details.
* *
*/ */
/** /**
* @ingroup sys_auto_init_lwip_netif * @ingroup sys_auto_init_lwip_netif
@ -21,8 +21,9 @@
#include "mrf24j40.h" #include "mrf24j40.h"
#include "mrf24j40_params.h" #include "mrf24j40_params.h"
#include "bhp/event.h"
#include "lwip.h"
#include "lwip_init_devs.h" #include "lwip_init_devs.h"
#include "bhp/msg.h"
#include "net/netdev/ieee802154_submac.h" #include "net/netdev/ieee802154_submac.h"
#define ENABLE_DEBUG 0 #define ENABLE_DEBUG 0
@ -37,9 +38,10 @@ static netdev_ieee802154_submac_t mrf24j40_netdev[NETIF_MRF24J40_NUMOF];
static void auto_init_mrf24j40(void) static void auto_init_mrf24j40(void)
{ {
for (unsigned i = 0; i < NETIF_MRF24J40_NUMOF; i++) { for (unsigned i = 0; i < NETIF_MRF24J40_NUMOF; i++) {
bhp_msg_init(&netif[i].bhp, &mrf24j40_radio_irq_handler, &mrf24j40_netdev[i].submac.dev); bhp_event_init(&netif[i].bhp, &lwip_event_queue, &mrf24j40_radio_irq_handler,
&mrf24j40_netdev[i].submac.dev);
mrf24j40_init(&mrf24j40_devs[i], &mrf24j40_params[i], &mrf24j40_netdev[i].submac.dev, mrf24j40_init(&mrf24j40_devs[i], &mrf24j40_params[i], &mrf24j40_netdev[i].submac.dev,
bhp_msg_isr_cb, &netif[i].bhp); bhp_event_isr_cb, &netif[i].bhp);
netdev_register(&mrf24j40_netdev[i].dev.netdev, NETDEV_MRF24J40, i); netdev_register(&mrf24j40_netdev[i].dev.netdev, NETDEV_MRF24J40, i);