diff --git a/boards/native/Makefile.features b/boards/native/Makefile.features index 49cf688d30f9..db176c5d7680 100644 --- a/boards/native/Makefile.features +++ b/boards/native/Makefile.features @@ -3,6 +3,8 @@ FEATURES_PROVIDED += periph_cpuid FEATURES_PROVIDED += periph_hwrng FEATURES_PROVIDED += periph_rtc FEATURES_PROVIDED += periph_timer +FEATURES_PROVIDED += periph_uart +FEATURES_PROVIDED += periph_gpio # Various other features (if any) FEATURES_PROVIDED += config diff --git a/cpu/native/async_read.c b/cpu/native/async_read.c new file mode 100644 index 000000000000..e99b6ac32a3b --- /dev/null +++ b/cpu/native/async_read.c @@ -0,0 +1,160 @@ +/** + * Multiple asynchronus read on file descriptors + * + * Copyright (C) 2015 Ludwig Knüpfer , + * Martine Lenders + * Kaspar Schleiser + * Ell-i open source co-operative + * Takuo Yonezawa + * + * 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. + * + * @ingroup native_cpu + * @{ + * @file + * @author Takuo Yonezawa + */ + +#include +#include +#include +#include +#include + +#include "async_read.h" +#include "native_internal.h" + +static int _next_index; +static int _fds[ASYNC_READ_NUMOF]; +static native_async_read_callback_t _native_async_read_callbacks[ASYNC_READ_NUMOF]; + +#ifdef __MACH__ +static pid_t _sigio_child_pids[ASYNC_READ_NUMOF]; +static void _sigio_child(int fd); +#endif + +static void _async_io_isr(void) { + fd_set rfds; + + FD_ZERO(&rfds); + + int max_fd = 0; + + for (int i = 0; i < _next_index; i++) { + FD_SET(_fds[i], &rfds); + + if (max_fd < _fds[i]) { + max_fd = _fds[i]; + } + } + + if (real_select(max_fd + 1, &rfds, NULL, NULL, NULL) > 0) { + for (int i = 0; i < _next_index; i++) { + if (FD_ISSET(_fds[i], &rfds)) { + _native_async_read_callbacks[i](_fds[i]); + } + } + } +} + +void native_async_read_setup(void) { + register_interrupt(SIGIO, _async_io_isr); +} + +void native_async_read_cleanup(void) { + unregister_interrupt(SIGIO); + +#ifdef __MACH__ + for (int i = 0; i < _next_index; i++) { + kill(_sigio_child_pids[i], SIGKILL); + } +#endif +} + +void native_async_read_continue(int fd) { + (void) fd; +#ifdef __MACH__ + for (int i = 0; i < _next_index; i++) { + if (_fds[i] == fd) { + kill(_sigio_child_pids[i], SIGCONT); + } + } +#endif +} + +void native_async_read_add_handler(int fd, native_async_read_callback_t handler) { + if (_next_index >= ASYNC_READ_NUMOF) { + err(EXIT_FAILURE, "native_async_read_add_handler(): too many callbacks"); + } + + _fds[_next_index] = fd; + _native_async_read_callbacks[_next_index] = handler; + +#ifdef __MACH__ + /* tuntap signalled IO is not working in OSX, + * * check http://sourceforge.net/p/tuntaposx/bugs/17/ */ + _sigio_child(_next_index); +#else + /* configure fds to send signals on io */ + if (fcntl(fd, F_SETOWN, _native_pid) == -1) { + err(EXIT_FAILURE, "native_async_read_add_handler(): fcntl(F_SETOWN)"); + } + /* set file access mode to non-blocking */ + if (fcntl(fd, F_SETFL, O_NONBLOCK | O_ASYNC) == -1) { + err(EXIT_FAILURE, "native_async_read_add_handler(): fcntl(F_SETFL)"); + } +#endif /* not OSX */ + + _next_index++; +} + +#ifdef __MACH__ +static void _sigio_child(int index) +{ + int fd = _fds[index]; + pid_t parent = _native_pid; + pid_t child; + if ((child = real_fork()) == -1) { + err(EXIT_FAILURE, "sigio_child: fork"); + } + if (child > 0) { + _sigio_child_pids[index] = child; + + /* return in parent process */ + return; + } + + sigset_t sigmask; + + sigemptyset(&sigmask); + sigaddset(&sigmask, SIGCONT); + sigprocmask(SIG_BLOCK, &sigmask, NULL); + + /* watch tap interface and signal parent process if data is + * available */ + fd_set rfds; + while (1) { + FD_ZERO(&rfds); + FD_SET(fd, &rfds); + if (real_select(fd + 1, &rfds, NULL, NULL, NULL) == 1) { + kill(parent, SIGIO); + } + else { + kill(parent, SIGKILL); + err(EXIT_FAILURE, "osx_sigio_child: select"); + } + + /* If SIGCONT is sent before calling pause(), the process stops + * forever, so using sigwait instead. */ + + int sig; + + sigemptyset(&sigmask); + sigaddset(&sigmask, SIGCONT); + sigwait(&sigmask, &sig); + } +} +#endif +/** @} */ diff --git a/cpu/native/include/async_read.h b/cpu/native/include/async_read.h new file mode 100644 index 000000000000..0a1edf237cd7 --- /dev/null +++ b/cpu/native/include/async_read.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2015 Takuo Yonezawa + * + * 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. + */ + +/** + * @ingroup native_cpu + * @{ + * + * @file + * @brief Multiple asynchronus read on file descriptors + * + * @author Takuo Yonezawa + */ +#ifndef ASYNC_READ_H +#define ASYNC_READ_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Maximum number of file descriptors + */ +#ifndef ASYNC_READ_NUMOF +#define ASYNC_READ_NUMOF 2 +#endif + +/** + * @brief asynchronus read callback type + */ +typedef void (*native_async_read_callback_t)(int fd); + +/** + * @brief initialize asynchronus read system + * + * This registers SIGIO signal handler. + */ +void native_async_read_setup(void); + +/** + * @brief shutdown asynchronus read system + * + * This deregisters SIGIO signal handler. + */ +void native_async_read_cleanup(void); + +/** + * @brief resume monitoring of file descriptors + * + * Call this function after reading file descriptors. + * + * @param[in] fd The file descriptor to monitor + */ +void native_async_read_continue(int fd); + +/** + * @brief start monitoring of file descriptor + * + * @param[in] fd The file descriptor to monitor + * @param[in] handler The callback function to be called when the file + * descriptor is ready to read. + */ +void native_async_read_add_handler(int fd, native_async_read_callback_t handler); + +#ifdef __cplusplus +} +#endif + +#endif +/** @} */ diff --git a/cpu/native/include/periph_conf.h b/cpu/native/include/periph_conf.h index 6788dcea48b1..6995be428376 100644 --- a/cpu/native/include/periph_conf.h +++ b/cpu/native/include/periph_conf.h @@ -63,6 +63,15 @@ /** @} */ +/** + * @brief UART configuration + * @{ + */ +#ifndef UART_NUMOF +#define UART_NUMOF (1U) +#endif +/** @} */ + #ifdef __cplusplus } #endif diff --git a/cpu/native/include/tty_uart.h b/cpu/native/include/tty_uart.h new file mode 100644 index 000000000000..0c9feaef41cd --- /dev/null +++ b/cpu/native/include/tty_uart.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2015 Takuo Yonezawa + * + * 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. + */ + +/** + * @ingroup native_cpu + * @{ + * + * @file + * @brief UART implementation based on /dev/tty devices on host + * + * @author Takuo Yonezawa + */ + +#ifndef TTY_UART_H +#define TTY_UART_H + +#include "periph/uart.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief register /dev/tty device to be used for UART + * + * @param[in] uart UART id + * @param[in] name path name for /dev/tty device + */ +void tty_uart_setup(uart_t uart, const char *name); + +/** + * @brief closes files opened + */ +void uart_cleanup(void); + +#ifdef __cplusplus +} +#endif + +#endif +/** @} */ diff --git a/cpu/native/netdev2_tap/netdev2_tap.c b/cpu/native/netdev2_tap/netdev2_tap.c index e50e78e9d117..b12631af571a 100644 --- a/cpu/native/netdev2_tap/netdev2_tap.c +++ b/cpu/native/netdev2_tap/netdev2_tap.c @@ -48,6 +48,8 @@ #include "native_internal.h" +#include "async_read.h" + #include "net/eui64.h" #include "net/netdev2.h" #include "net/netdev2/eth.h" @@ -63,11 +65,6 @@ /* support one tap interface for now */ netdev2_tap_t netdev2_tap; -#ifdef __MACH__ -pid_t _sigio_child_pid; -static void _sigio_child(netdev2_tap_t *dev); -#endif - /* netdev2 interface */ static int _init(netdev2_t *netdev); static int _send(netdev2_t *netdev, const struct iovec *vector, int n); @@ -187,12 +184,58 @@ static inline bool _is_addr_multicast(uint8_t *addr) return (addr[0] & 0x01); } +static void _continue_reading(netdev2_tap_t *dev) +{ + /* work around lost signals */ + fd_set rfds; + struct timeval t; + memset(&t, 0, sizeof(t)); + FD_ZERO(&rfds); + FD_SET(dev->tap_fd, &rfds); + + _native_in_syscall++; /* no switching here */ + + if (real_select(dev->tap_fd + 1, &rfds, NULL, NULL, &t) == 1) { + int sig = SIGIO; + extern int _sig_pipefd[2]; + extern ssize_t (*real_write)(int fd, const void * buf, size_t count); + real_write(_sig_pipefd[1], &sig, sizeof(int)); + _native_sigpend++; + DEBUG("netdev2_tap: sigpend++\n"); + } + else { + DEBUG("netdev2_tap: native_async_read_continue\n"); + native_async_read_continue(dev->tap_fd); + } + + _native_in_syscall--; +} + static int _recv(netdev2_t *netdev2, char *buf, int len, void *info) { netdev2_tap_t *dev = (netdev2_tap_t*)netdev2; (void)info; if (!buf) { + if (len > 0) { + /* no memory available in pktbuf, discarding the frame */ + DEBUG("netdev2_tap: discarding the frame\n"); + + /* repeating `real_read` for small size on tap device results in + * freeze for some reason. Using a large buffer for now. */ + /* + uint8_t buf[4]; + while (real_read(dev->tap_fd, buf, sizeof(buf)) > 0) { + } + */ + + static uint8_t buf[ETHERNET_FRAME_LEN]; + + real_read(dev->tap_fd, buf, sizeof(buf)); + + _continue_reading(dev); + } + /* no way of figuring out packet size without racey buffering, * so we return the maximum possible size */ return ETHERNET_FRAME_LEN; @@ -210,35 +253,13 @@ static int _recv(netdev2_t *netdev2, char *buf, int len, void *info) "That's not me => Dropped\n", hdr->dst[0], hdr->dst[1], hdr->dst[2], hdr->dst[3], hdr->dst[4], hdr->dst[5]); -#ifdef __MACH__ - kill(_sigio_child_pid, SIGCONT); -#endif + + native_async_read_continue(dev->tap_fd); + return 0; } - /* work around lost signals */ - fd_set rfds; - struct timeval t; - memset(&t, 0, sizeof(t)); - FD_ZERO(&rfds); - FD_SET(dev->tap_fd, &rfds); - - _native_in_syscall++; /* no switching here */ - - if (real_select(dev->tap_fd + 1, &rfds, NULL, NULL, &t) == 1) { - int sig = SIGIO; - extern int _sig_pipefd[2]; - extern ssize_t (*real_write)(int fd, const void * buf, size_t count); - real_write(_sig_pipefd[1], &sig, sizeof(int)); - _native_sigpend++; - DEBUG("netdev2_tap: sigpend++\n"); - } - else { -#ifdef __MACH__ - kill(_sigio_child_pid, SIGCONT); -#endif - } - _native_in_syscall--; + _continue_reading(dev); #ifdef MODULE_NETSTATS_L2 netdev2->stats.rx_count++; @@ -284,7 +305,9 @@ void netdev2_tap_setup(netdev2_tap_t *dev, const netdev2_tap_params_t *params) { strncpy(dev->tap_name, *(params->tap_name), IFNAMSIZ); } -static void _tap_isr(void) { +static void _tap_isr(int fd) { + (void) fd; + netdev2_t *netdev = (netdev2_t *)&netdev2_tap; if (netdev->event_callback) { @@ -320,7 +343,7 @@ static int _init(netdev2_t *netdev) /* initialize device descriptor */ dev->promiscous = 0; /* implicitly create the tap interface */ - if ((dev->tap_fd = real_open(clonedev , O_RDWR)) == -1) { + if ((dev->tap_fd = real_open(clonedev, O_RDWR | O_NONBLOCK)) == -1) { err(EXIT_FAILURE, "open(%s)", clonedev); } #if (defined(__MACH__) || defined(__FreeBSD__)) /* OSX/FreeBSD */ @@ -365,22 +388,11 @@ static int _init(netdev2_t *netdev) DEBUG("gnrc_tapnet_init(): dev->addr = %02x:%02x:%02x:%02x:%02x:%02x\n", dev->addr[0], dev->addr[1], dev->addr[2], dev->addr[3], dev->addr[4], dev->addr[5]); + /* configure signal handler for fds */ - register_interrupt(SIGIO, _tap_isr); -#ifdef __MACH__ - /* tuntap signalled IO is not working in OSX, - * * check http://sourceforge.net/p/tuntaposx/bugs/17/ */ - _sigio_child(dev); -#else - /* configure fds to send signals on io */ - if (fcntl(dev->tap_fd, F_SETOWN, _native_pid) == -1) { - err(EXIT_FAILURE, "gnrc_tapnet_init(): fcntl(F_SETOWN)"); - } - /* set file access mode to non-blocking */ - if (fcntl(dev->tap_fd, F_SETFL, O_NONBLOCK | O_ASYNC) == -1) { - err(EXIT_FAILURE, "gnrc_tabnet_init(): fcntl(F_SETFL)"); - } -#endif /* not OSX */ + native_async_read_setup(); + native_async_read_add_handler(dev->tap_fd, _tap_isr); + #ifdef MODULE_NETSTATS_L2 memset(&netdev->stats, 0, sizeof(netstats_t)); #endif @@ -396,40 +408,8 @@ void netdev2_tap_cleanup(netdev2_tap_t *dev) } /* cleanup signal handling */ - unregister_interrupt(SIGIO); -#ifdef __MACH__ - kill(_sigio_child_pid, SIGKILL); -#endif + native_async_read_cleanup(); /* close the tap device */ real_close(dev->tap_fd); } - -#ifdef __MACH__ -static void _sigio_child(netdev2_tap_t *dev) -{ - pid_t parent = _native_pid; - if ((_sigio_child_pid = real_fork()) == -1) { - err(EXIT_FAILURE, "sigio_child: fork"); - } - if (_sigio_child_pid > 0) { - /* return in parent process */ - return; - } - /* watch tap interface and signal parent process if data is - * available */ - fd_set rfds; - while (1) { - FD_ZERO(&rfds); - FD_SET(dev->tap_fd, &rfds); - if (real_select(dev->tap_fd + 1, &rfds, NULL, NULL, NULL) == 1) { - kill(parent, SIGIO); - } - else { - kill(parent, SIGKILL); - err(EXIT_FAILURE, "osx_sigio_child: select"); - } - pause(); - } -} -#endif diff --git a/cpu/native/periph/gpio.c b/cpu/native/periph/gpio.c new file mode 100644 index 000000000000..45b0c29e1f5b --- /dev/null +++ b/cpu/native/periph/gpio.c @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2015 Takuo Yonezawa + * + * 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. + */ + +/** + * @ingroup native_cpu + * @{ + * + * @file + * @brief empty GPIO implementation + * + * @author Takuo Yonezawa + */ + +#include "periph/gpio.h" + +int gpio_init(gpio_t pin, gpio_mode_t mode) { + (void) pin; + (void) mode; + + return -1; +} + +int gpio_init_int(gpio_t pin, gpio_mode_t mode, gpio_flank_t flank, + gpio_cb_t cb, void *arg){ + (void) pin; + (void) mode; + (void) flank; + (void) cb; + (void) arg; + + return -1; +} + +void gpio_irq_enable(gpio_t pin) { + (void) pin; +} + +void gpio_irq_disable(gpio_t pin) { + (void) pin; +} + +int gpio_read(gpio_t pin) { + (void) pin; + + return 0; +} + +void gpio_set(gpio_t pin) { + (void) pin; +} + +void gpio_clear(gpio_t pin) { + (void) pin; +} + +void gpio_toggle(gpio_t pin) { + (void) pin; +} + +void gpio_write(gpio_t pin, int value) { + (void) pin; + (void) value; +} +/** @} */ diff --git a/cpu/native/periph/uart.c b/cpu/native/periph/uart.c new file mode 100644 index 000000000000..fcbc5e89729d --- /dev/null +++ b/cpu/native/periph/uart.c @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2015 Takuo Yonezawa + * + * 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. + */ + +/** + * @ingroup native_cpu + * @{ + * + * @file + * @brief UART implementation based on /dev/tty devices on host + * + * @author Takuo Yonezawa + */ + +#include +#include +#include +#include +#include +#include + +#include "thread.h" +#include "periph/uart.h" +#include "native_internal.h" +#include "async_read.h" + +#define ENABLE_DEBUG (0) +#include "debug.h" + +/** + * @brief callback function and its argument + */ +static uart_isr_ctx_t uart_config[UART_NUMOF]; + +/** + * @brief filenames of /dev/tty + */ +static char *tty_device_filenames[UART_NUMOF]; + +/** + * @brief file descriptors of /dev/tty + */ +static int tty_fds[UART_NUMOF]; + +void tty_uart_setup(uart_t uart, const char *filename) +{ + tty_device_filenames[uart] = strndup(filename, PATH_MAX - 1); +} + +static void io_signal_handler(int fd) +{ + uart_t uart; + + for (uart = 0; uart < UART_NUMOF; uart++) { + if (tty_fds[uart] == fd) { + break; + } + } + + int is_first = 1; + + while (1) { + char c; + int status = real_read(fd, &c, 1); + + if (status == 1) { + if (is_first) { + is_first = 0; + DEBUG("read char from serial port"); + } + + DEBUG(" %02x", (unsigned char) c); + + uart_config[uart].rx_cb(uart_config[uart].arg, c); + } else { + if (status == -1 && errno != EAGAIN) { + DEBUG("error: cannot read from serial port\n"); + + uart_config[uart].rx_cb = NULL; + } + + break; + } + } + + if (!is_first) { + DEBUG("\n"); + } + + native_async_read_continue(fd); +} + +int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg) +{ + if (uart >= UART_NUMOF) { + return -1; + } + + struct termios termios; + + memset(&termios, 0, sizeof(termios)); + + termios.c_iflag = 0; + termios.c_oflag = 0; + termios.c_cflag = CS8 | CREAD | CLOCAL; + termios.c_lflag = 0; + + speed_t speed; + + switch (baudrate) { + case 0: speed = B0; break; + case 50: speed = B50; break; + case 75: speed = B75; break; + case 110: speed = B110; break; + case 134: speed = B134; break; + case 150: speed = B150; break; + case 200: speed = B200; break; + case 300: speed = B300; break; + case 600: speed = B600; break; + case 1200: speed = B1200; break; + case 1800: speed = B1800; break; + case 2400: speed = B2400; break; + case 4800: speed = B4800; break; + case 9600: speed = B9600; break; + case 19200: speed = B19200; break; + case 38400: speed = B38400; break; + case 57600: speed = B57600; break; + case 115200: speed = B115200; break; + case 230400: speed = B230400 ; break; + default: + return -1; + break; + } + + cfsetospeed(&termios, speed); + cfsetispeed(&termios, speed); + + tty_fds[uart] = real_open(tty_device_filenames[uart], O_RDWR | O_NONBLOCK); + + if (tty_fds[uart] < 0) { + return -3; + } + + tcsetattr(tty_fds[uart], TCSANOW, &termios); + + uart_config[uart].rx_cb = rx_cb; + uart_config[uart].arg = arg; + + native_async_read_setup(); + native_async_read_add_handler(tty_fds[uart], io_signal_handler); + + return 0; +} + +void uart_write(uart_t uart, const uint8_t *data, size_t len) +{ + DEBUG("writing to serial port "); + +#if ENABLE_DEBUG + for (size_t i = 0; i < len; i++) { + DEBUG("%02x ", (unsigned char) data[i]); + } + for (size_t i = 0; i < len; i++) { + DEBUG("%c", (char) data[i]); + } +#endif + + DEBUG("\n"); + + _native_write(tty_fds[uart], data, len); +} + +void uart_cleanup(void) { + native_async_read_cleanup(); + + for (uart_t uart = 0; uart < UART_NUMOF; uart++) { + if (uart_config[uart].rx_cb != NULL) { + real_close(tty_fds[uart]); + } + } +} + +/** @} */ diff --git a/cpu/native/reboot.c b/cpu/native/reboot.c index 6641a9ed95a8..c54bec1328ff 100644 --- a/cpu/native/reboot.c +++ b/cpu/native/reboot.c @@ -20,6 +20,7 @@ #include "native_internal.h" #include "netdev2_tap.h" +#include "tty_uart.h" void reboot(void) { @@ -29,6 +30,8 @@ void reboot(void) netdev2_tap_cleanup(&netdev2_tap); #endif + uart_cleanup(); + if (real_execve(_native_argv[0], _native_argv, NULL) == -1) { err(EXIT_FAILURE, "reboot: execve"); } diff --git a/cpu/native/startup.c b/cpu/native/startup.c index 28360ce9ab5e..3e1dfbc28b36 100644 --- a/cpu/native/startup.c +++ b/cpu/native/startup.c @@ -35,6 +35,7 @@ #include "board_internal.h" #include "native_internal.h" +#include "tty_uart.h" int _native_null_in_pipe[2]; int _native_null_out_file; @@ -200,7 +201,7 @@ void usage_exit(void) real_printf(" "); #endif - real_printf(" [-i ] [-d] [-e|-E] [-o]\n"); + real_printf(" [-i ] [-d] [-e|-E] [-o] [-c ]\n"); real_printf(" help: %s -h\n", _progname); @@ -216,7 +217,8 @@ void usage_exit(void) -E do not redirect stderr (i.e. leave sterr unchanged despite\n\ daemon/socket io)\n\ -o redirect stdout to file (/tmp/riot.stdout.PID) when not attached\n\ - to socket\n"); + to socket\n\ +-c specify TTY device for UART\n"); real_printf("\n\ The order of command line arguments matters.\n"); @@ -239,6 +241,7 @@ __attribute__((constructor)) static void startup(int argc, char **argv) char *stderrtype = "stdio"; char *stdouttype = "stdio"; char *stdiotype = "stdio"; + int uart = 0; #if defined(MODULE_NETDEV2_TAP) if ( @@ -297,6 +300,16 @@ __attribute__((constructor)) static void startup(int argc, char **argv) else if (strcmp("-o", arg) == 0) { stdouttype = "file"; } + else if (strcmp("-c", arg) == 0) { + if (argp + 1 < argc) { + argp++; + } + else { + usage_exit(); + } + + tty_uart_setup(uart++, argv[argp]); + } else { usage_exit(); } diff --git a/drivers/include/net/netdev2.h b/drivers/include/net/netdev2.h index 6b9238c8e8c2..18b6d3e56b34 100644 --- a/drivers/include/net/netdev2.h +++ b/drivers/include/net/netdev2.h @@ -135,6 +135,9 @@ typedef struct netdev2_driver { * * Supposed to be called from netdev2_event_handler(). * + * If buf == NULL and len == 0, returns the packet size without dropping it. + * If buf == NULL and len > 0, drops the packet and returns the packet size. + * * @param[in] dev network device descriptor * @param[out] buf buffer to write into or NULL * @param[in] len maximum nr. of bytes to read diff --git a/sys/net/gnrc/link_layer/netdev2/gnrc_netdev2_eth.c b/sys/net/gnrc/link_layer/netdev2/gnrc_netdev2_eth.c index eab49221d9b2..bf7b0dd7204a 100644 --- a/sys/net/gnrc/link_layer/netdev2/gnrc_netdev2_eth.c +++ b/sys/net/gnrc/link_layer/netdev2/gnrc_netdev2_eth.c @@ -42,6 +42,10 @@ static gnrc_pktsnip_t *_recv(gnrc_netdev2_t *gnrc_netdev2) if(!pkt) { DEBUG("_recv_ethernet_packet: cannot allocate pktsnip.\n"); + + /* drop the packet */ + dev->driver->recv(dev, NULL, bytes_expected, NULL); + goto out; } diff --git a/tests/periph_uart/main.c b/tests/periph_uart/main.c index 56b85c99301c..b741e698c4c2 100644 --- a/tests/periph_uart/main.c +++ b/tests/periph_uart/main.c @@ -56,7 +56,7 @@ static int parse_dev(char *arg) printf("Error: The selected UART_DEV(%i) is used for the shell!\n", dev); return -2; } - if (dev < 0 || dev >= UART_NUMOF) { + if (dev < 0 || (uart_t) dev >= UART_NUMOF) { printf("Error: Invalid UART_DEV device specified (%i).\n", dev); return -1; } @@ -65,7 +65,7 @@ static int parse_dev(char *arg) static void rx_cb(void *arg, uint8_t data) { - int dev = (int)arg; + uart_t dev = (uart_t)arg; ringbuffer_add_one(&(ctx[dev].rx_buf), data); if (data == 0) { @@ -84,7 +84,7 @@ static void *printer(void *arg) while (1) { msg_receive(&msg); - int dev = (int)msg.content.value; + uart_t dev = (uart_t)msg.content.value; char c; printf("UART_DEV(%i) RX: ", dev); @@ -179,7 +179,7 @@ int main(void) printf("UART used for STDIO (the shell): UART_DEV(%i)\n\n", UART_STDIO_DEV); /* initialize ringbuffers */ - for (int i = 0; i < UART_NUMOF; i++) { + for (uart_t i = 0; i < UART_NUMOF; i++) { ringbuffer_init(&(ctx[i].rx_buf), ctx[i].rx_mem, UART_BUFSIZE); }