can: use memarray for pkt and router allocation

This commit is contained in:
Vincent Dupont 2018-06-22 12:19:31 -07:00
parent abd1cd51b7
commit 9207e6b446
7 changed files with 64 additions and 40 deletions

View File

@ -672,11 +672,12 @@ ifneq (,$(filter can,$(USEMODULE)))
ifneq (,$(filter can_mbox,$(USEMODULE))) ifneq (,$(filter can_mbox,$(USEMODULE)))
USEMODULE += core_mbox USEMODULE += core_mbox
endif endif
USEMODULE += gnrc_pktbuf_static USEMODULE += memarray
endif endif
ifneq (,$(filter can_isotp,$(USEMODULE))) ifneq (,$(filter can_isotp,$(USEMODULE)))
USEMODULE += xtimer USEMODULE += xtimer
USEMODULE += gnrc_pktbuf
endif endif
ifneq (,$(filter conn_can,$(USEMODULE))) ifneq (,$(filter conn_can,$(USEMODULE)))

View File

@ -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 * 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 * 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; msg_t msg, reply;
can_pkt_t *pkt = NULL; can_pkt_t *pkt = NULL;
can_reg_entry_t *entry; can_reg_entry_t *entry = NULL;
assert(ifnum < candev_nb); 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) 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); int ret = can_router_free_frame((struct can_frame *)frame->data.iov_base);
can_pkt_free_rx_data(frame); 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) int can_dll_init(void)
{ {
can_pkt_init(); can_pkt_init();
can_router_init();
return 0; return 0;
} }

View File

@ -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 * 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 * Public License v2.1. See the file LICENSE in the top level directory for more
@ -21,7 +21,7 @@
#include <limits.h> #include <limits.h>
#include <errno.h> #include <errno.h>
#include "net/gnrc/pktbuf.h" #include "memarray.h"
#include "can/pkt.h" #include "can/pkt.h"
#include "mutex.h" #include "mutex.h"
@ -33,10 +33,19 @@
static int handle; static int handle;
static mutex_t _mutex = MUTEX_INIT; 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) void can_pkt_init(void)
{ {
mutex_lock(&_mutex); mutex_lock(&_mutex);
handle = 1; handle = 1;
memarray_init(&_pkt_array, _pkt_buf, sizeof(can_pkt_t), CAN_PKT_BUF_SIZE);
mutex_unlock(&_mutex); mutex_unlock(&_mutex);
} }
@ -44,16 +53,16 @@ static can_pkt_t *_pkt_alloc(int ifnum, const struct can_frame *frame)
{ {
can_pkt_t *pkt; can_pkt_t *pkt;
gnrc_pktsnip_t *snip = gnrc_pktbuf_add(NULL, NULL, sizeof(*pkt), GNRC_NETTYPE_UNDEF); mutex_lock(&_mutex);
if (!snip) { pkt = memarray_alloc(&_pkt_array);
DEBUG("can_pkt_alloc: out of memory\n"); mutex_unlock(&_mutex);
if (!pkt) {
return NULL; return NULL;
} }
pkt = snip->data;
pkt->entry.ifnum = ifnum; pkt->entry.ifnum = ifnum;
pkt->frame = *frame; pkt->frame = *frame;
pkt->snip = snip;
DEBUG("can_pkt_alloc: pkt allocated\n"); 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); 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 *can_pkt_alloc_rx_data(void *data, size_t len, void *arg)
{ {
can_rx_data_t *rx; can_rx_data_t *rx;
gnrc_pktsnip_t *snip = gnrc_pktbuf_add(NULL, NULL, sizeof(*rx), GNRC_NETTYPE_UNDEF); mutex_lock(&_mutex);
if (!snip) { rx = memarray_alloc(&_pkt_array);
DEBUG("can_pkt_alloc_rx_data: out of memory\n"); mutex_unlock(&_mutex);
DEBUG("can_pkt_alloc_rx_data: rx=%p\n", (void *)rx);
if (!rx) {
return NULL; return NULL;
} }
rx = snip->data;
DEBUG("can_pkt_alloc_rx_data: rx=%p\n", (void *)rx);
rx->data.iov_base = data; rx->data.iov_base = data;
rx->data.iov_len = len; rx->data.iov_len = len;
rx->arg = arg; rx->arg = arg;
rx->snip = snip;
return rx; return rx;
} }
@ -162,5 +173,7 @@ void can_pkt_free_rx_data(can_rx_data_t *data)
return; return;
} }
gnrc_pktbuf_release(data->snip); mutex_lock(&_mutex);
memarray_free(&_pkt_array, data);
mutex_unlock(&_mutex);
} }

View File

@ -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 * 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 * Public License v2.1. See the file LICENSE in the top level directory for more
@ -22,14 +22,13 @@
#include "kernel_defines.h" #include "kernel_defines.h"
#include "net/gnrc/pktbuf.h"
#include "can/router.h" #include "can/router.h"
#include "can/pkt.h" #include "can/pkt.h"
#include "can/device.h" #include "can/device.h"
#include "utlist.h" #include "utlist.h"
#include "mutex.h" #include "mutex.h"
#include "assert.h" #include "assert.h"
#include "memarray.h"
#ifdef MODULE_CAN_MBOX #ifdef MODULE_CAN_MBOX
#include "mbox.h" #include "mbox.h"
@ -50,7 +49,6 @@ typedef struct filter_el {
canid_t can_id; /**< CAN ID of the element */ canid_t can_id; /**< CAN ID of the element */
canid_t mask; /**< Mask of the element */ canid_t mask; /**< Mask of the element */
void *data; /**< Private data */ void *data; /**< Private data */
gnrc_pktsnip_t *snip; /**< Pointer to the allocated snip */
} filter_el_t; } filter_el_t;
/** /**
@ -58,7 +56,12 @@ typedef struct filter_el {
*/ */
static can_reg_entry_t *table[CAN_DLL_NUMOF]; 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 mutex_t lock = MUTEX_INIT;
static filter_el_t *_alloc_filter_el(canid_t can_id, canid_t mask, void *data); 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() #define PRINT_FILTERS()
#endif #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) static filter_el_t *_alloc_filter_el(canid_t can_id, canid_t mask, void *data)
{ {
filter_el_t *el; filter_el_t *el;
gnrc_pktsnip_t *snip = gnrc_pktbuf_add(NULL, NULL, sizeof(*el), GNRC_NETTYPE_UNDEF); el = memarray_alloc(&_filter_array);
if (!snip) { if (!el) {
DEBUG("can_router: _alloc_canid_el: out of memory\n"); DEBUG("can_router: _alloc_canid_el: out of memory\n");
return NULL; return NULL;
} }
el = snip->data;
el->can_id = can_id; el->can_id = can_id;
el->mask = mask; el->mask = mask;
el->data = data; el->data = data;
el->entry.next = NULL; el->entry.next = NULL;
el->snip = snip;
DEBUG("_alloc_canid_el: el allocated with can_id=0x%" PRIx32 ", mask=0x%" PRIx32 DEBUG("_alloc_canid_el: el allocated with can_id=0x%" PRIx32 ", mask=0x%" PRIx32
", data=%p\n", can_id, mask, data); ", data=%p\n", can_id, mask, data);
return el; 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) 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 DEBUG("_free_canid_el: el freed with can_id=0x%" PRIx32 ", mask=0x%" PRIx32
", data=%p\n", el->can_id, el->mask, el->data); ", 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 /* 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); (void *)pkt, pkt->entry.ifnum, pkt->frame.can_id);
mutex_lock(&lock); mutex_lock(&lock);
can_reg_entry_t *entry; can_reg_entry_t *entry = NULL;
filter_el_t *el; filter_el_t *el;
LL_FOREACH(table[pkt->entry.ifnum], entry) { LL_FOREACH(table[pkt->entry.ifnum], entry) {
el = container_of(entry, filter_el_t, 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) int can_router_free_frame(struct can_frame *frame)
{ {
can_pkt_t *pkt = NULL; can_pkt_t *pkt = container_of(frame, can_pkt_t, frame);
pkt = container_of(frame, can_pkt_t, frame);
DEBUG("can_router_free_frame: pkt=%p\n", (void*) pkt); DEBUG("can_router_free_frame: pkt=%p\n", (void*) pkt);

View File

@ -38,7 +38,6 @@ extern "C" {
#ifdef MODULE_CAN_MBOX #ifdef MODULE_CAN_MBOX
#include "mbox.h" #include "mbox.h"
#endif #endif
#include "net/gnrc/pktbuf.h"
/** /**
* @brief CAN options * @brief CAN options
@ -123,10 +122,8 @@ enum can_msg {
typedef struct can_rx_data { typedef struct can_rx_data {
struct iovec data; /**< iovec containing received data */ struct iovec data; /**< iovec containing received data */
void *arg; /**< upper layer private param */ void *arg; /**< upper layer private param */
gnrc_pktsnip_t *snip; /**< pointer to the allocated snip */
} can_rx_data_t; } can_rx_data_t;
/** /**
* @brief registry entry types * @brief registry entry types
*/ */

View File

@ -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 * 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 * Public License v2.1. See the file LICENSE in the top level directory for more
@ -26,8 +26,6 @@ extern "C" {
#include <stdatomic.h> #include <stdatomic.h>
#include "net/gnrc/pktbuf.h"
#include "can/common.h" #include "can/common.h"
#include "can/can.h" #include "can/can.h"
#include "msg.h" #include "msg.h"
@ -45,7 +43,6 @@ typedef struct {
atomic_uint ref_count; /**< Reference counter (for rx frames) */ atomic_uint ref_count; /**< Reference counter (for rx frames) */
int handle; /**< handle (for tx frames */ int handle; /**< handle (for tx frames */
struct can_frame frame; /**< CAN Frame */ struct can_frame frame; /**< CAN Frame */
gnrc_pktsnip_t *snip; /**< Pointer to the allocated snip */
} can_pkt_t; } can_pkt_t;
/** /**

View File

@ -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 * 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 * 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/can.h"
#include "can/pkt.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 * @brief Register a user @p entry to receive a frame @p can_id
* *