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

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)))
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)))

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
* 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;
}

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
* Public License v2.1. See the file LICENSE in the top level directory for more
@ -21,7 +21,7 @@
#include <limits.h>
#include <errno.h>
#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);
}

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
* 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);

View File

@ -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
*/

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
* 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 "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;
/**

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
* 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
*