diff --git a/include/console.h b/include/console.h index 599036bdc77..ce3425be2e4 100644 --- a/include/console.h +++ b/include/console.h @@ -23,9 +23,11 @@ struct tty_serial { u16_t rx_get, rx_put; s32_t rx_timeout; + struct k_sem tx_sem; u8_t *tx_ringbuf; u32_t tx_ringbuf_sz; u16_t tx_get, tx_put; + s32_t tx_timeout; }; /** @@ -62,6 +64,20 @@ static inline void tty_set_rx_timeout(struct tty_serial *tty, s32_t timeout) tty->rx_timeout = timeout; } +/** + * @brief Set transmit timeout for tty device. + * + * Set timeout for putchar() operation, for a case when output buffer is full. + * Default timeout after device initialization is K_FOREVER. + * + * @param tty tty device structure + * @param timeout timeout in milliseconds, or K_FOREVER, or K_NO_WAIT + */ +static inline void tty_set_tx_timeout(struct tty_serial *tty, s32_t timeout) +{ + tty->tx_timeout = timeout; +} + /** * @brief Input a character from a tty device. * diff --git a/subsys/console/tty.c b/subsys/console/tty.c index 0d916c7d92c..d4fd5d48b6c 100644 --- a/subsys/console/tty.c +++ b/subsys/console/tty.c @@ -42,6 +42,7 @@ static void tty_uart_isr(void *user_data) if (tty->tx_get >= tty->tx_ringbuf_sz) { tty->tx_get = 0; } + k_sem_give(&tty->tx_sem); } } } @@ -72,6 +73,12 @@ int tty_putchar(struct tty_serial *tty, u8_t c) { unsigned int key; int tx_next; + int res; + + res = k_sem_take(&tty->tx_sem, tty->tx_timeout); + if (res < 0) { + return res; + } key = irq_lock(); tx_next = tty->tx_put + 1; @@ -123,8 +130,10 @@ void tty_init(struct tty_serial *tty, struct device *uart_dev, tty->tx_ringbuf_sz = txbuf_sz; tty->rx_get = tty->rx_put = tty->tx_get = tty->tx_put = 0; k_sem_init(&tty->rx_sem, 0, UINT_MAX); + k_sem_init(&tty->tx_sem, txbuf_sz - 1, UINT_MAX); tty->rx_timeout = K_FOREVER; + tty->tx_timeout = K_FOREVER; uart_irq_callback_user_data_set(uart_dev, tty_uart_isr, tty); uart_irq_rx_enable(uart_dev);