forked from RIOT-OS/RIOT
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'slipdev/api/slip-port-to-netdev' (RIOT-OS#7381) into RI…
- Loading branch information
Showing
21 changed files
with
552 additions
and
465 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
/* | ||
* Copyright (C) 2015-17 Freie Universität Berlin | ||
* | ||
* 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 details. | ||
*/ | ||
|
||
/** | ||
* @defgroup drivers_slipdev SLIP network device | ||
* @ingroup drivers_netdev | ||
* @brief SLIP network device over @ref drivers_periph_uart | ||
* @see [RFC 1055](https://github.com/RIOT-OS/RIOT/pull/6487) | ||
* @{ | ||
* | ||
* @file | ||
* @brief SLIP device definitions | ||
* | ||
* @author Martine Lenders <[email protected]> | ||
*/ | ||
#ifndef SLIPDEV_H | ||
#define SLIPDEV_H | ||
|
||
#include <stdint.h> | ||
|
||
#include "cib.h" | ||
#include "net/netdev.h" | ||
#include "periph/uart.h" | ||
#include "ringbuffer.h" | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
/** | ||
* @brief UART buffer size used for TX and RX buffers | ||
* | ||
* Reduce this value if your expected traffic does not include full IPv6 MTU | ||
* sized packets | ||
*/ | ||
#ifndef SLIPDEV_BUFSIZE | ||
#define SLIPDEV_BUFSIZE (1500U) | ||
#endif | ||
|
||
/** | ||
* @brief Packet FIFO size | ||
* | ||
* @note For GNRC it is recommended to have it the same size as the link-layer | ||
* thread's message queue, but it MUST be of power of 2 | ||
*/ | ||
#ifndef SLIPDEV_PKTFIFO_SIZE | ||
#define SLIPDEV_PKTFIFO_SIZE (8U) | ||
#endif | ||
|
||
/** | ||
* @brief Configuration parameters for a slipdev | ||
*/ | ||
typedef struct { | ||
uart_t uart; /**< UART interface the device is connected to */ | ||
uint32_t baudrate; /**< baudrate to use with slipdev_params_t::uart */ | ||
} slipdev_params_t; | ||
|
||
/** | ||
* @brief Device descriptor for slipdev | ||
* | ||
* @extends netdev_t | ||
*/ | ||
typedef struct { | ||
netdev_t netdev; /**< parent class */ | ||
slipdev_params_t config; /**< configuration parameters */ | ||
ringbuffer_t inbuf; /**< RX buffer */ | ||
char rxmem[SLIPDEV_BUFSIZE]; /**< memory used by RX buffer */ | ||
uint16_t pktfifo[SLIPDEV_PKTFIFO_SIZE]; /**< FIFO of sizes of fully received | ||
* packets */ | ||
cib_t pktfifo_idx; /**< CIB for slipdev_t::pktfifo */ | ||
uint16_t inbytes; /**< the number of bytes received of | ||
* a currently incoming packet */ | ||
uint16_t inesc; /**< device previously received an escape | ||
* byte */ | ||
} slipdev_t; | ||
|
||
/** | ||
* @brief Setup a slipdev device state | ||
* | ||
* @param[in] dev device descriptor | ||
* @param[in] params parameters for device initialization | ||
*/ | ||
void slipdev_setup(slipdev_t *dev, const slipdev_params_t *params); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif /* SLIPDEV_H */ | ||
/** @} */ |
2 changes: 0 additions & 2 deletions
2
sys/net/gnrc/link_layer/slip/Makefile → drivers/slipdev/Makefile
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1 @@ | ||
MODULE = gnrc_slip | ||
|
||
include $(RIOTBASE)/Makefile.base |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,220 @@ | ||
/* | ||
* Copyright (C) 2017 Freie Universität Berlin | ||
* | ||
* 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 details. | ||
*/ | ||
|
||
/** | ||
* @{ | ||
* | ||
* @file | ||
* @author Martine Lenders <[email protected]> | ||
*/ | ||
|
||
#include <errno.h> | ||
#include <string.h> | ||
|
||
#include "log.h" | ||
#include "slipdev.h" | ||
|
||
#define ENABLE_DEBUG (0) | ||
#include "debug.h" | ||
|
||
#define SLIP_END (0xc0U) | ||
#define SLIP_ESC (0xdbU) | ||
#define SLIP_END_ESC (0xdcU) | ||
#define SLIP_ESC_ESC (0xddU) | ||
|
||
static int _send(netdev_t *dev, const struct iovec *vector, unsigned count); | ||
static int _recv(netdev_t *dev, void *buf, size_t len, void *info); | ||
static int _init(netdev_t *dev); | ||
static void _isr(netdev_t *dev); | ||
static int _get(netdev_t *dev, netopt_t opt, void *value, size_t max_len); | ||
static int _set(netdev_t *dev, netopt_t opt, void *value, size_t value_len); | ||
|
||
static const netdev_driver_t slip_driver = { | ||
.send = _send, | ||
.recv = _recv, | ||
.init = _init, | ||
.isr = _isr, | ||
.get = _get, | ||
.set = _set, | ||
}; | ||
|
||
void slipdev_setup(slipdev_t *dev, const slipdev_params_t *params) | ||
{ | ||
/* set device descriptor fields */ | ||
memcpy(&dev->config, params, sizeof(dev->config)); | ||
dev->inbytes = 0U; | ||
dev->inesc = 0U; | ||
dev->netdev.driver = &slip_driver; | ||
} | ||
|
||
static inline void _add_byte_to_inbuf(slipdev_t *dev, uint8_t byte) | ||
{ | ||
if (ringbuffer_add_one(&dev->inbuf, byte) < 0) { | ||
dev->inbytes++; | ||
} | ||
} | ||
|
||
static void _slip_rx_cb(void *arg, uint8_t data) | ||
{ | ||
slipdev_t *dev = arg; | ||
|
||
if ((data == SLIP_END) && (dev->netdev.event_callback != NULL)) { | ||
int idx = cib_put(&dev->pktfifo_idx); | ||
if (idx >= 0) { | ||
dev->netdev.event_callback((netdev_t *)dev, NETDEV_EVENT_ISR); | ||
dev->pktfifo[idx] = dev->inbytes; | ||
} | ||
else { | ||
/* can't handover packet => dropping it */ | ||
ringbuffer_remove(&dev->inbuf, dev->inbytes); | ||
} | ||
dev->inbytes = 0; | ||
} | ||
else if (dev->inesc) { | ||
dev->inesc = 0U; | ||
uint8_t actual = (data == SLIP_END_ESC) ? SLIP_END : | ||
((data == SLIP_ESC_ESC) ? SLIP_ESC : 0); | ||
|
||
switch (data) { | ||
case SLIP_END_ESC: | ||
case SLIP_ESC_ESC: | ||
_add_byte_to_inbuf(dev, actual); | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
else if (data == SLIP_ESC) { | ||
dev->inesc = 1U; | ||
} | ||
else { | ||
_add_byte_to_inbuf(dev, data); | ||
} | ||
} | ||
|
||
static int _init(netdev_t *netdev) | ||
{ | ||
slipdev_t *dev = (slipdev_t *)netdev; | ||
|
||
DEBUG("slipdev: initializing device %p on UART %i with baudrate %" PRIu32 "\n", | ||
(void *)dev, dev->config.uart, dev->config.baudrate); | ||
/* initialize buffers */ | ||
ringbuffer_init(&dev->inbuf, dev->rxmem, sizeof(dev->rxmem)); | ||
cib_init(&dev->pktfifo_idx, SLIPDEV_PKTFIFO_SIZE); | ||
if (uart_init(dev->config.uart, dev->config.baudrate, _slip_rx_cb, | ||
dev) != UART_OK) { | ||
LOG_ERROR("slipdev: error initializing UART %i with baudrate %" PRIu32 "\n", | ||
dev->config.uart, dev->config.baudrate); | ||
return -ENODEV; | ||
} | ||
return 0; | ||
} | ||
|
||
static inline void _write_byte(slipdev_t *dev, uint8_t byte) | ||
{ | ||
uart_write(dev->config.uart, &byte, 1); | ||
} | ||
|
||
static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count) | ||
{ | ||
slipdev_t *dev = (slipdev_t *)netdev; | ||
int bytes = 0; | ||
|
||
DEBUG("slipdev: sending vector of length %u\n", count); | ||
for (unsigned i = 0; i < count; i++) { | ||
uint8_t *data = vector[i].iov_base; | ||
|
||
for (unsigned j = 0; j < vector[i].iov_len; j++, data++) { | ||
switch(*data) { | ||
case SLIP_END: | ||
/* escaping END byte*/ | ||
_write_byte(dev, SLIP_ESC); | ||
_write_byte(dev, SLIP_END_ESC); | ||
break; | ||
case SLIP_ESC: | ||
/* escaping ESC byte*/ | ||
_write_byte(dev, SLIP_ESC); | ||
_write_byte(dev, SLIP_ESC_ESC); | ||
break; | ||
default: | ||
_write_byte(dev, *data); | ||
} | ||
bytes++; | ||
} | ||
} | ||
_write_byte(dev, SLIP_END); | ||
return bytes; | ||
} | ||
|
||
static int _recv(netdev_t *netdev, void *buf, size_t len, void *info) | ||
{ | ||
slipdev_t *dev = (slipdev_t *)netdev; | ||
int res, idx = cib_peek(&dev->pktfifo_idx); | ||
|
||
(void)info; | ||
if (idx < 0) { | ||
return -EFAULT; | ||
} | ||
if (buf == NULL) { | ||
if (len > 0) { | ||
/* drop packet */ | ||
cib_get(&dev->pktfifo_idx); | ||
/* and remove data */ | ||
res = ringbuffer_remove(&dev->inbuf, len); | ||
} | ||
else { | ||
res = dev->pktfifo[idx]; | ||
} | ||
} | ||
else if (len < dev->pktfifo[idx]) { | ||
res = -ENOBUFS; | ||
} | ||
else { | ||
size_t bytes = dev->pktfifo[cib_get(&dev->pktfifo_idx)]; | ||
bytes = ringbuffer_get(&dev->inbuf, buf, bytes); | ||
res = bytes; | ||
} | ||
return res; | ||
} | ||
|
||
static void _isr(netdev_t *netdev) | ||
{ | ||
DEBUG("slipdev: handling ISR event\n"); | ||
if (netdev->event_callback != NULL) { | ||
DEBUG("slipdev: event handler set, issuing RX_COMPLETE event\n"); | ||
netdev->event_callback(netdev, NETDEV_EVENT_RX_COMPLETE); | ||
} | ||
} | ||
|
||
static int _get(netdev_t *netdev, netopt_t opt, void *value, size_t max_len) | ||
{ | ||
(void)netdev; | ||
(void)value; | ||
(void)max_len; | ||
switch (opt) { | ||
case NETOPT_IS_WIRED: | ||
return 1; | ||
case NETOPT_DEVICE_TYPE: | ||
assert(max_len != sizeof(uint16_t)); | ||
*((uint16_t *)value) = NETDEV_TYPE_SLIP; | ||
return sizeof(uint16_t); | ||
default: | ||
return -ENOTSUP; | ||
} | ||
} | ||
|
||
static int _set(netdev_t *netdev, netopt_t opt, void *value, size_t value_len) | ||
{ | ||
(void)netdev; | ||
(void)opt; | ||
(void)value; | ||
(void)value_len; | ||
return -ENOTSUP; | ||
} | ||
|
||
/** @} */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,16 +16,16 @@ | |
* @author Martine Lenders <[email protected]> | ||
*/ | ||
|
||
#ifndef SLIP_PARAMS_H | ||
#define SLIP_PARAMS_H | ||
#ifndef SLIPDEV_PARAMS_H | ||
#define SLIPDEV_PARAMS_H | ||
|
||
#include "net/gnrc/slip.h" | ||
#include "slipdev.h" | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
static gnrc_slip_params_t gnrc_slip_params[] = { | ||
static slipdev_params_t slipdev_params[] = { | ||
{ | ||
.uart = SLIP_UART, | ||
.baudrate = SLIP_BAUDRATE, | ||
|
@@ -35,5 +35,5 @@ static gnrc_slip_params_t gnrc_slip_params[] = { | |
#ifdef __cplusplus | ||
} | ||
#endif | ||
#endif /* SLIP_PARAMS_H */ | ||
#endif /* SLIPDEV_PARAMS_H */ | ||
/** @} */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.