diff --git a/cpu/native/async_read.c b/cpu/native/async_read.c index 5705535406..806e1c4cf4 100644 --- a/cpu/native/async_read.c +++ b/cpu/native/async_read.c @@ -97,6 +97,34 @@ void native_async_read_add_handler(int fd, void *arg, native_async_read_callback _next_index++; } +void native_async_read_remove_handler(int fd) +{ + int res = real_fcntl(fd, F_GETFL); + if (res < 0) { + err(EXIT_FAILURE, "native_async_read_remove_handler(): fcntl(F_GETFL)"); + } + unsigned flags = (unsigned)res & !O_ASYNC; + res = real_fcntl(fd, F_SETFL, flags); + if (res < 0) { + err(EXIT_FAILURE, "native_async_read_remove_handler(): fcntl(F_SETFL)"); + } + + unsigned i; + for (i = 0; (i < (unsigned)_next_index) && (_fds[i].fd != fd); i++) { }; + if (i == (unsigned)_next_index) { + return; + } + + unregister_interrupt(SIGIO); + for (; i < (unsigned)_next_index - 1; i++) { + _fds[i] = _fds[i + 1]; + } + _next_index--; + register_interrupt(SIGIO, _async_io_isr); + + _fds[_next_index] = (struct pollfd){ 0 }; +} + void native_async_read_add_int_handler(int fd, void *arg, native_async_read_callback_t handler) { if (_next_index >= ASYNC_READ_NUMOF) { err(EXIT_FAILURE, "native_async_read_add_int_handler(): too many callbacks"); diff --git a/cpu/native/include/async_read.h b/cpu/native/include/async_read.h index 1c2edd9a56..3f36ab1af5 100644 --- a/cpu/native/include/async_read.h +++ b/cpu/native/include/async_read.h @@ -80,6 +80,13 @@ void native_async_read_continue(int fd); */ void native_async_read_add_handler(int fd, void *arg, native_async_read_callback_t handler); +/** + * @brief stop monitoring of file descriptor + * + * @param[in] fd The file descriptor to stop monitoring + */ +void native_async_read_remove_handler(int fd); + /** * @brief start monitoring of file descriptor as interrupt * diff --git a/cpu/native/periph/uart.c b/cpu/native/periph/uart.c index 5584ba5c47..d7809e31e4 100644 --- a/cpu/native/periph/uart.c +++ b/cpu/native/periph/uart.c @@ -134,7 +134,22 @@ int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg) case 38400: speed = B38400; break; case 57600: speed = B57600; break; case 115200: speed = B115200; break; - case 230400: speed = B230400 ; break; + case 230400: speed = B230400; break; +#if __linux__ + case 460800 : speed = B460800; break; + case 500000 : speed = B500000; break; + case 576000 : speed = B576000; break; + case 921600 : speed = B921600; break; + case 1000000: speed = B1000000; break; + case 1152000: speed = B1152000; break; + case 1500000: speed = B1500000; break; + case 2000000: speed = B2000000; break; + case 2500000: speed = B2500000; break; + case 3000000: speed = B3000000; break; + case 3500000: speed = B3500000; break; + case 4000000: speed = B4000000; break; +#endif + default: return UART_NOBAUD; break; @@ -175,7 +190,9 @@ void uart_write(uart_t uart, const uint8_t *data, size_t len) DEBUG("\n"); - _native_write(tty_fds[uart], data, len); + if (tty_fds[uart] >= 0) { + _native_write(tty_fds[uart], data, len); + } } void uart_poweron(uart_t uart) @@ -186,6 +203,9 @@ void uart_poweron(uart_t uart) void uart_poweroff(uart_t uart) { - (void)uart; - /* not implemented (yet) */ + if (tty_fds[uart] >= 0) { + native_async_read_remove_handler(tty_fds[uart]); + real_close(tty_fds[uart]); + tty_fds[uart] = -1; + } }