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.
native: add UART driver based on /dev/tty
uart0 functionality is removed by RIOT-OS#3164. This patch implements periph/uart, rather than deprecated uart0, using /dev/tty. To use with netdev2_tap simultaneously, this patch adds asynchronus read system and modifies netdev2_tap to use it. A TTY device is specified on command line with -c (COM) option, since -t was used by the old implementation. This patch also implements empty GPIO driver needed by the xbee driver.
- Loading branch information
1 parent
e6f3349
commit 5b38c87
Showing
11 changed files
with
581 additions
and
62 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
/** | ||
* Multiple asynchronus read on file descriptors | ||
* | ||
* Copyright (C) 2015 Ludwig Knüpfer <ludwig.knuepfer@fu-berlin.de>, | ||
* Martine Lenders <mlenders@inf.fu-berlin.de> | ||
* Kaspar Schleiser <kaspar@schleiser.de> | ||
* Ell-i open source co-operative | ||
* Takuo Yonezawa <Yonezawa-T2@mail.dnp.co.jp> | ||
* | ||
* 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 <Yonezawa-T2@mail.dnp.co.jp> | ||
*/ | ||
|
||
#include <err.h> | ||
#include <signal.h> | ||
#include <stdlib.h> | ||
#include <unistd.h> | ||
#include <fcntl.h> | ||
|
||
#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 suspend(), the process stops | ||
// forever, so using sigwait instead. | ||
|
||
int sig; | ||
|
||
sigemptyset(&sigmask); | ||
sigaddset(&sigmask, SIGCONT); | ||
sigwait(&sigmask, &sig); | ||
} | ||
} | ||
#endif | ||
/** @} */ |
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,74 @@ | ||
/* | ||
* Copyright (C) 2015 Takuo Yonezawa <Yonezawa-T2@mail.dnp.co.jp> | ||
* | ||
* 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 <Yonezawa-T2@mail.dnp.co.jp> | ||
*/ | ||
#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 | ||
/** @} */ |
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,46 @@ | ||
/* | ||
* Copyright (C) 2015 Takuo Yonezawa <Yonezawa-T2@mail.dnp.co.jp> | ||
* | ||
* 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 <Yonezawa-T2@mail.dnp.co.jp> | ||
*/ | ||
|
||
#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 | ||
/** @} */ |
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.