diff --git a/Makefile.dep b/Makefile.dep index a75565ca16..6b1078d89d 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -672,11 +672,12 @@ ifneq (,$(filter can,$(USEMODULE))) ifneq (,$(filter can_mbox,$(USEMODULE))) USEMODULE += core_mbox endif - USEMODULE += gnrc_pktbuf_static + USEMODULE += memarray endif ifneq (,$(filter can_isotp,$(USEMODULE))) USEMODULE += xtimer + USEMODULE += gnrc_pktbuf endif ifneq (,$(filter conn_can,$(USEMODULE))) diff --git a/sys/can/dll.c b/sys/can/dll.c index ea221d65fd..13012147e3 100644 --- a/sys/can/dll.c +++ b/sys/can/dll.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 OTA keys S.A. + * Copyright (C) 2016-2018 OTA keys S.A. * * 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 directory for more @@ -112,7 +112,7 @@ int raw_can_abort(int ifnum, int handle) { msg_t msg, reply; can_pkt_t *pkt = NULL; - can_reg_entry_t *entry; + can_reg_entry_t *entry = NULL; assert(ifnum < candev_nb); @@ -263,6 +263,9 @@ int raw_can_unsubscribe_rx_mbox(int ifnum, struct can_filter *filter, mbox_t *mb int raw_can_free_frame(can_rx_data_t *frame) { + if (!frame) { + return 0; + } int ret = can_router_free_frame((struct can_frame *)frame->data.iov_base); can_pkt_free_rx_data(frame); @@ -386,6 +389,7 @@ int can_dll_dispatch_bus_off(kernel_pid_t pid) int can_dll_init(void) { can_pkt_init(); + can_router_init(); return 0; } diff --git a/sys/can/pkt.c b/sys/can/pkt.c index 05759e53c1..31107cd1b6 100644 --- a/sys/can/pkt.c +++ b/sys/can/pkt.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 OTA keys S.A. + * Copyright (C) 2016-2018 OTA keys S.A. * * 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 directory for more @@ -21,7 +21,7 @@ #include #include -#include "net/gnrc/pktbuf.h" +#include "memarray.h" #include "can/pkt.h" #include "mutex.h" @@ -33,10 +33,19 @@ static int handle; static mutex_t _mutex = MUTEX_INIT; +#ifndef CAN_PKT_BUF_SIZE +#define CAN_PKT_BUF_SIZE 128 +#endif + +static can_pkt_t _pkt_buf[CAN_PKT_BUF_SIZE]; +static memarray_t _pkt_array; +static_assert(sizeof(can_pkt_t) >= sizeof(can_rx_data_t), "sizeof(can_rx_data_t) must be at most sizeof(can_pkt_t)"); + void can_pkt_init(void) { mutex_lock(&_mutex); handle = 1; + memarray_init(&_pkt_array, _pkt_buf, sizeof(can_pkt_t), CAN_PKT_BUF_SIZE); mutex_unlock(&_mutex); } @@ -44,16 +53,16 @@ static can_pkt_t *_pkt_alloc(int ifnum, const struct can_frame *frame) { can_pkt_t *pkt; - gnrc_pktsnip_t *snip = gnrc_pktbuf_add(NULL, NULL, sizeof(*pkt), GNRC_NETTYPE_UNDEF); - if (!snip) { - DEBUG("can_pkt_alloc: out of memory\n"); + mutex_lock(&_mutex); + pkt = memarray_alloc(&_pkt_array); + mutex_unlock(&_mutex); + + if (!pkt) { return NULL; } - pkt = snip->data; pkt->entry.ifnum = ifnum; pkt->frame = *frame; - pkt->snip = snip; DEBUG("can_pkt_alloc: pkt allocated\n"); @@ -132,26 +141,28 @@ void can_pkt_free(can_pkt_t *pkt) DEBUG("can_pkt_free: free pkt=%p\n", (void*)pkt); - gnrc_pktbuf_release(pkt->snip); + mutex_lock(&_mutex); + memarray_free(&_pkt_array, pkt); + mutex_unlock(&_mutex); } can_rx_data_t *can_pkt_alloc_rx_data(void *data, size_t len, void *arg) { can_rx_data_t *rx; - gnrc_pktsnip_t *snip = gnrc_pktbuf_add(NULL, NULL, sizeof(*rx), GNRC_NETTYPE_UNDEF); - if (!snip) { - DEBUG("can_pkt_alloc_rx_data: out of memory\n"); + mutex_lock(&_mutex); + rx = memarray_alloc(&_pkt_array); + mutex_unlock(&_mutex); + + DEBUG("can_pkt_alloc_rx_data: rx=%p\n", (void *)rx); + + if (!rx) { return NULL; } - rx = snip->data; - DEBUG("can_pkt_alloc_rx_data: rx=%p\n", (void *)rx); - rx->data.iov_base = data; rx->data.iov_len = len; rx->arg = arg; - rx->snip = snip; return rx; } @@ -162,5 +173,7 @@ void can_pkt_free_rx_data(can_rx_data_t *data) return; } - gnrc_pktbuf_release(data->snip); + mutex_lock(&_mutex); + memarray_free(&_pkt_array, data); + mutex_unlock(&_mutex); } diff --git a/sys/can/router.c b/sys/can/router.c index 9b0103ca75..b009d6f5cb 100644 --- a/sys/can/router.c +++ b/sys/can/router.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 OTA keys S.A. + * Copyright (C) 2016-2018 OTA keys S.A. * * 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 directory for more @@ -22,14 +22,13 @@ #include "kernel_defines.h" -#include "net/gnrc/pktbuf.h" - #include "can/router.h" #include "can/pkt.h" #include "can/device.h" #include "utlist.h" #include "mutex.h" #include "assert.h" +#include "memarray.h" #ifdef MODULE_CAN_MBOX #include "mbox.h" @@ -50,7 +49,6 @@ typedef struct filter_el { canid_t can_id; /**< CAN ID of the element */ canid_t mask; /**< Mask of the element */ void *data; /**< Private data */ - gnrc_pktsnip_t *snip; /**< Pointer to the allocated snip */ } filter_el_t; /** @@ -58,7 +56,12 @@ typedef struct filter_el { */ static can_reg_entry_t *table[CAN_DLL_NUMOF]; +#ifndef CAN_ROUTER_MAX_FILTER +#define CAN_ROUTER_MAX_FILTER 64 +#endif +static filter_el_t _filter_buf[CAN_ROUTER_MAX_FILTER]; +static memarray_t _filter_array; static mutex_t lock = MUTEX_INIT; static filter_el_t *_alloc_filter_el(canid_t can_id, canid_t mask, void *data); @@ -86,21 +89,25 @@ static void _print_filters(void) #define PRINT_FILTERS() #endif +void can_router_init(void) +{ + mutex_init(&lock); + memarray_init(&_filter_array, _filter_buf, sizeof(filter_el_t), CAN_ROUTER_MAX_FILTER); +} + static filter_el_t *_alloc_filter_el(canid_t can_id, canid_t mask, void *data) { filter_el_t *el; - gnrc_pktsnip_t *snip = gnrc_pktbuf_add(NULL, NULL, sizeof(*el), GNRC_NETTYPE_UNDEF); - if (!snip) { + el = memarray_alloc(&_filter_array); + if (!el) { DEBUG("can_router: _alloc_canid_el: out of memory\n"); return NULL; } - el = snip->data; el->can_id = can_id; el->mask = mask; el->data = data; el->entry.next = NULL; - el->snip = snip; DEBUG("_alloc_canid_el: el allocated with can_id=0x%" PRIx32 ", mask=0x%" PRIx32 ", data=%p\n", can_id, mask, data); return el; @@ -108,10 +115,12 @@ static filter_el_t *_alloc_filter_el(canid_t can_id, canid_t mask, void *data) static void _free_filter_el(filter_el_t *el) { + assert(el); + DEBUG("_free_canid_el: el freed with can_id=0x%" PRIx32 ", mask=0x%" PRIx32 ", data=%p\n", el->can_id, el->mask, el->data); - gnrc_pktbuf_release(el->snip); + memarray_free(&_filter_array, el); } /* Insert to the list in a sorted way @@ -314,7 +323,7 @@ int can_router_dispatch_rx_indic(can_pkt_t *pkt) (void *)pkt, pkt->entry.ifnum, pkt->frame.can_id); mutex_lock(&lock); - can_reg_entry_t *entry; + can_reg_entry_t *entry = NULL; filter_el_t *el; LL_FOREACH(table[pkt->entry.ifnum], entry) { el = container_of(entry, filter_el_t, entry); @@ -383,9 +392,7 @@ int can_router_dispatch_tx_error(can_pkt_t *pkt) int can_router_free_frame(struct can_frame *frame) { - can_pkt_t *pkt = NULL; - - pkt = container_of(frame, can_pkt_t, frame); + can_pkt_t *pkt = container_of(frame, can_pkt_t, frame); DEBUG("can_router_free_frame: pkt=%p\n", (void*) pkt); diff --git a/sys/include/can/common.h b/sys/include/can/common.h index d6104990ed..ea255c0802 100644 --- a/sys/include/can/common.h +++ b/sys/include/can/common.h @@ -38,7 +38,6 @@ extern "C" { #ifdef MODULE_CAN_MBOX #include "mbox.h" #endif -#include "net/gnrc/pktbuf.h" /** * @brief CAN options @@ -123,10 +122,8 @@ enum can_msg { typedef struct can_rx_data { struct iovec data; /**< iovec containing received data */ void *arg; /**< upper layer private param */ - gnrc_pktsnip_t *snip; /**< pointer to the allocated snip */ } can_rx_data_t; - /** * @brief registry entry types */ diff --git a/sys/include/can/pkt.h b/sys/include/can/pkt.h index 2cb9c05181..c57ec0bd00 100644 --- a/sys/include/can/pkt.h +++ b/sys/include/can/pkt.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 OTA keys S.A. + * Copyright (C) 2016-2018 OTA keys S.A. * * 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 directory for more @@ -26,8 +26,6 @@ extern "C" { #include -#include "net/gnrc/pktbuf.h" - #include "can/common.h" #include "can/can.h" #include "msg.h" @@ -45,7 +43,6 @@ typedef struct { atomic_uint ref_count; /**< Reference counter (for rx frames) */ int handle; /**< handle (for tx frames */ struct can_frame frame; /**< CAN Frame */ - gnrc_pktsnip_t *snip; /**< Pointer to the allocated snip */ } can_pkt_t; /** diff --git a/sys/include/can/router.h b/sys/include/can/router.h index cf2aeb97fc..4120c00ca4 100644 --- a/sys/include/can/router.h +++ b/sys/include/can/router.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 OTA keys S.A. + * Copyright (C) 2016-2018 OTA keys S.A. * * 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 directory for more @@ -29,6 +29,11 @@ extern "C" { #include "can/can.h" #include "can/pkt.h" +/** + * @brief Initialize CAN router + */ +void can_router_init(void); + /** * @brief Register a user @p entry to receive a frame @p can_id * diff --git a/tests/conn_can/Makefile b/tests/conn_can/Makefile index 7e895d3a01..a224fb9400 100644 --- a/tests/conn_can/Makefile +++ b/tests/conn_can/Makefile @@ -25,4 +25,8 @@ USEMODULE += can_trx FEATURES_REQUIRED += periph_can FEATURES_REQUIRED += periph_gpio_irq +CFLAGS += -DGNRC_PKTBUF_SIZE=4096 +CFLAGS += -DCAN_PKT_BUF_SIZE=64 +CFLAGS += -DCAN_ROUTER_MAX_FILTER=32 + include $(RIOTBASE)/Makefile.include