You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by we...@apache.org on 2017/03/24 23:15:39 UTC
[17/50] [abbrv] incubator-mynewt-core git commit: MYNEWT-671 UART
support in sim
MYNEWT-671 UART support in sim
Currently, sim always maps UARTs to ptys. This change allows the
application to specify a file (e.g., /dev/...) to map a UART to.
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/653a6974
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/653a6974
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/653a6974
Branch: refs/heads/nrf_cputime
Commit: 653a6974083f9918fc105b568559995dde6d7713
Parents: 7894657
Author: Christopher Collins <cc...@apache.org>
Authored: Wed Mar 8 19:39:20 2017 -0800
Committer: Christopher Collins <cc...@apache.org>
Committed: Wed Mar 15 11:17:54 2017 -0700
----------------------------------------------------------------------
hw/mcu/native/include/mcu/native_bsp.h | 2 +
hw/mcu/native/src/hal_uart.c | 65 ++++++-
hw/mcu/native/src/native_uart_cfg.c | 234 ++++++++++++++++++++++++++
hw/mcu/native/src/native_uart_cfg_priv.h | 12 ++
4 files changed, 310 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/653a6974/hw/mcu/native/include/mcu/native_bsp.h
----------------------------------------------------------------------
diff --git a/hw/mcu/native/include/mcu/native_bsp.h b/hw/mcu/native/include/mcu/native_bsp.h
index c8b6e13..dd79487 100644
--- a/hw/mcu/native/include/mcu/native_bsp.h
+++ b/hw/mcu/native/include/mcu/native_bsp.h
@@ -25,6 +25,8 @@ extern "C" {
extern const struct hal_flash native_flash_dev;
+int uart_set_dev(int port, const char *dev_str);
+
#ifdef __cplusplus
}
#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/653a6974/hw/mcu/native/src/hal_uart.c
----------------------------------------------------------------------
diff --git a/hw/mcu/native/src/hal_uart.c b/hw/mcu/native/src/hal_uart.c
index 4c2c076..d9328aa 100644
--- a/hw/mcu/native/src/hal_uart.c
+++ b/hw/mcu/native/src/hal_uart.c
@@ -17,6 +17,7 @@
* under the License.
*/
+#include "defs/error.h"
#include "os/os.h"
#include "hal/hal_uart.h"
#include "bsp/bsp.h"
@@ -33,6 +34,10 @@
#include <assert.h>
#include <unistd.h>
#include <string.h>
+#include <termios.h>
+#include <errno.h>
+
+#include "native_uart_cfg_priv.h"
#define UART_CNT 2
@@ -51,6 +56,8 @@ struct uart {
void *u_func_arg;
};
+const char *native_uart_dev_strs[UART_CNT];
+
/*
* XXXX should try to use O_ASYNC/SIGIO for byte arrival notification,
* so we wouldn't need an OS for pseudo ttys.
@@ -231,7 +238,7 @@ set_nonblock(int fd)
}
static int
-uart_set_attr(int fd)
+uart_pty_set_attr(int fd)
{
struct termios tios;
@@ -268,7 +275,7 @@ uart_pty(int port)
return -1;
}
- if (uart_set_attr(loop_slave)) {
+ if (uart_pty_set_attr(loop_slave)) {
goto err;
}
@@ -281,6 +288,37 @@ err:
return -1;
}
+/**
+ * Opens an external device terminal (/dev/cu.<...>).
+ */
+static int
+uart_open_dev(int port, int32_t baudrate, uint8_t databits,
+ uint8_t stopbits, enum hal_uart_parity parity,
+ enum hal_uart_flow_ctl flow_ctl)
+{
+ const char *filename;
+ int fd;
+ int rc;
+
+ filename = native_uart_dev_strs[port];
+ assert(filename != NULL);
+
+ fd = open(filename, O_RDWR);
+ if (fd < 0) {
+ return -1;
+ }
+
+ rc = uart_dev_set_attr(fd, baudrate, databits,
+ stopbits, parity, flow_ctl);
+ if (rc != 0) {
+ return rc;
+ }
+
+ dprintf(1, "uart%d at %s\n", port, filename);
+
+ return fd;
+}
+
void
hal_uart_start_tx(int port)
{
@@ -363,12 +401,19 @@ hal_uart_config(int port, int32_t baudrate, uint8_t databits, uint8_t stopbits,
return -1;
}
- uart->u_fd = uart_pty(port);
+ if (native_uart_dev_strs[port] == NULL) {
+ uart->u_fd = uart_pty(port);
+ } else {
+ uart->u_fd = uart_open_dev(port, baudrate, databits, stopbits,
+ parity, flow_ctl);
+ }
+
if (uart->u_fd < 0) {
return -1;
}
set_nonblock(uart->u_fd);
+
uart_open_log();
uart->u_open = 1;
return 0;
@@ -405,4 +450,18 @@ hal_uart_init(int port, void *arg)
return (0);
}
+int
+uart_set_dev(int port, const char *dev_str)
+{
+ if (port < 0 || port >= UART_CNT) {
+ return SYS_EINVAL;
+ }
+
+ if (uarts[port].u_open) {
+ return SYS_EBUSY;
+ }
+ native_uart_dev_strs[port] = dev_str;
+
+ return 0;
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/653a6974/hw/mcu/native/src/native_uart_cfg.c
----------------------------------------------------------------------
diff --git a/hw/mcu/native/src/native_uart_cfg.c b/hw/mcu/native/src/native_uart_cfg.c
new file mode 100644
index 0000000..4f9dcef
--- /dev/null
+++ b/hw/mcu/native/src/native_uart_cfg.c
@@ -0,0 +1,234 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <termios.h>
+
+#include "defs/error.h"
+#include "native_uart_cfg_priv.h"
+
+/* uint64 is used here to accommodate speed_t, whatever that is. */
+static const uint64_t uart_baud_table[][2] = {
+#ifdef B50
+ { 50, B50 },
+#endif
+#ifdef B75
+ { 75, B75 },
+#endif
+#ifdef B110
+ { 110, B110 },
+#endif
+#ifdef B134
+ { 134, B134 },
+#endif
+#ifdef B150
+ { 150, B150 },
+#endif
+#ifdef B200
+ { 200, B200 },
+#endif
+#ifdef B300
+ { 300, B300 },
+#endif
+#ifdef B600
+ { 600, B600 },
+#endif
+#ifdef B1200
+ { 1200, B1200 },
+#endif
+#ifdef B1800
+ { 1800, B1800 },
+#endif
+#ifdef B2400
+ { 2400, B2400 },
+#endif
+#ifdef B4800
+ { 4800, B4800 },
+#endif
+#ifdef B9600
+ { 9600, B9600 },
+#endif
+#ifdef B19200
+ { 19200, B19200 },
+#endif
+#ifdef B38400
+ { 38400, B38400 },
+#endif
+#ifdef B57600
+ { 57600, B57600 },
+#endif
+#ifdef B115200
+ { 115200, B115200 },
+#endif
+#ifdef B230400
+ { 230400, B230400 },
+#endif
+#ifdef B460800
+ { 460800, B460800 },
+#endif
+#ifdef B500000
+ { 500000, B500000 },
+#endif
+#ifdef B576000
+ { 576000, B576000 },
+#endif
+#ifdef B921600
+ { 921600, B921600 },
+#endif
+#ifdef B1000000
+ { 1000000, B1000000 },
+#endif
+#ifdef B1152000
+ { 1152000, B1152000 },
+#endif
+#ifdef B1500000
+ { 1500000, B1500000 },
+#endif
+#ifdef B2000000
+ { 2000000, B2000000 },
+#endif
+#ifdef B2500000
+ { 2500000, B2500000 },
+#endif
+#ifdef B3000000
+ { 3000000, B3000000 },
+#endif
+#ifdef B3500000
+ { 3500000, B3500000 },
+#endif
+#ifdef B3710000
+ { 3710000, B3710000 },
+#endif
+#ifdef B4000000
+ { 4000000, B4000000 },
+#endif
+};
+#define UART_BAUD_TABLE_SZ (sizeof uart_baud_table / sizeof uart_baud_table[0])
+
+/**
+ * Returns 0 on failure.
+ */
+speed_t
+uart_baud_to_speed(int_least32_t baud)
+{
+ int i;
+
+ for (i = 0; i < UART_BAUD_TABLE_SZ; i++) {
+ if (uart_baud_table[i][0] == baud) {
+ return uart_baud_table[i][1];
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * Configures an external device terminal (/dev/cu.<...>).
+ */
+int
+uart_dev_set_attr(int fd, int32_t baudrate, uint8_t databits,
+ uint8_t stopbits, enum hal_uart_parity parity,
+ enum hal_uart_flow_ctl flow_ctl)
+{
+ struct termios tty;
+ speed_t speed;
+ int rc;
+
+ assert(fd >= 0);
+
+ memset(&tty, 0, sizeof(tty));
+ cfmakeraw(&tty);
+
+ speed = uart_baud_to_speed(baudrate);
+ if (speed == 0) {
+ fprintf(stderr, "invalid baud rate: %d\n", (int)baudrate);
+ assert(0);
+ }
+
+ tty.c_cflag |= (speed | CLOCAL | CREAD);
+
+ /* Disable flow control. */
+ tty.c_cflag &= ~CRTSCTS;
+
+ errno = 0;
+ rc = cfsetospeed(&tty, speed);
+ if (rc != 0) {
+ fprintf(stderr, "cfsetospeed failed; %d (%s) baudrate=%d\n",
+ errno, strerror(errno), (int)baudrate);
+ return -1;
+ }
+
+ errno = 0;
+ rc = cfsetispeed(&tty, speed);
+ if (rc != 0) {
+ fprintf(stderr, "cfsetispeed failed; %d (%s) baudrate=%d\n",
+ errno, strerror(errno), (int)baudrate);
+ return -1;
+ }
+
+ switch (databits) {
+ case 7:
+ tty.c_cflag |= CS7;
+
+ switch (parity) {
+ case HAL_UART_PARITY_ODD:
+ tty.c_cflag |= PARENB;
+ tty.c_cflag |= PARODD;
+ tty.c_cflag &= ~CSTOPB;
+ tty.c_cflag &= ~CSIZE;
+ break;
+
+ case HAL_UART_PARITY_EVEN:
+ tty.c_cflag |= PARENB;
+ tty.c_cflag &= ~PARODD;
+ tty.c_cflag &= ~CSTOPB;
+ tty.c_cflag &= ~CSIZE;
+ break;
+
+ default:
+ return SYS_EINVAL;
+ }
+
+ case 8:
+ if (parity != HAL_UART_PARITY_NONE) {
+ return SYS_EINVAL;
+ }
+ tty.c_cflag |= CS8;
+ tty.c_cflag &= ~PARENB;
+ tty.c_cflag &= ~CSTOPB;
+ tty.c_cflag &= ~CSIZE;
+ break;
+
+ default:
+ return SYS_EINVAL;
+ }
+
+ rc = tcsetattr(fd, TCSANOW, &tty);
+ if (rc != 0) {
+ dprintf(1, "tcsetattr failed; %d (%s)\n", errno, strerror(errno));
+ return -1;
+ }
+
+ return 0;
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/653a6974/hw/mcu/native/src/native_uart_cfg_priv.h
----------------------------------------------------------------------
diff --git a/hw/mcu/native/src/native_uart_cfg_priv.h b/hw/mcu/native/src/native_uart_cfg_priv.h
new file mode 100644
index 0000000..243cd45
--- /dev/null
+++ b/hw/mcu/native/src/native_uart_cfg_priv.h
@@ -0,0 +1,12 @@
+#ifndef H_NATIVE_UART_CFG_PRIV_
+#define H_NATIVE_UART_CFG_PRIV_
+
+#include <termios.h>
+#include "hal/hal_uart.h"
+
+speed_t uart_baud_to_speed(int_least32_t baud);
+int uart_dev_set_attr(int fd, int32_t baudrate, uint8_t databits,
+ uint8_t stopbits, enum hal_uart_parity parity,
+ enum hal_uart_flow_ctl flow_ctl);
+
+#endif