subsys: console: tty: Allow to specify transmit timeout
Previously, transmit was effectively non-blocking - a character either went into buffer, or -1 was returned. Now it's possible to block if buffer is full. Timeout is K_FOREVER by default, can be adjusted with tty_set_tx_timeout() (similar to receive timeout). Signed-off-by: Paul Sokolovsky <paul.sokolovsky@linaro.org>
This commit is contained in:
parent
680085b3e2
commit
9d3b48fd48
2 changed files with 25 additions and 0 deletions
|
@ -23,9 +23,11 @@ struct tty_serial {
|
||||||
u16_t rx_get, rx_put;
|
u16_t rx_get, rx_put;
|
||||||
s32_t rx_timeout;
|
s32_t rx_timeout;
|
||||||
|
|
||||||
|
struct k_sem tx_sem;
|
||||||
u8_t *tx_ringbuf;
|
u8_t *tx_ringbuf;
|
||||||
u32_t tx_ringbuf_sz;
|
u32_t tx_ringbuf_sz;
|
||||||
u16_t tx_get, tx_put;
|
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;
|
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.
|
* @brief Input a character from a tty device.
|
||||||
*
|
*
|
||||||
|
|
|
@ -42,6 +42,7 @@ static void tty_uart_isr(void *user_data)
|
||||||
if (tty->tx_get >= tty->tx_ringbuf_sz) {
|
if (tty->tx_get >= tty->tx_ringbuf_sz) {
|
||||||
tty->tx_get = 0;
|
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;
|
unsigned int key;
|
||||||
int tx_next;
|
int tx_next;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
res = k_sem_take(&tty->tx_sem, tty->tx_timeout);
|
||||||
|
if (res < 0) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
key = irq_lock();
|
key = irq_lock();
|
||||||
tx_next = tty->tx_put + 1;
|
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->tx_ringbuf_sz = txbuf_sz;
|
||||||
tty->rx_get = tty->rx_put = tty->tx_get = tty->tx_put = 0;
|
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->rx_sem, 0, UINT_MAX);
|
||||||
|
k_sem_init(&tty->tx_sem, txbuf_sz - 1, UINT_MAX);
|
||||||
|
|
||||||
tty->rx_timeout = K_FOREVER;
|
tty->rx_timeout = K_FOREVER;
|
||||||
|
tty->tx_timeout = K_FOREVER;
|
||||||
|
|
||||||
uart_irq_callback_user_data_set(uart_dev, tty_uart_isr, tty);
|
uart_irq_callback_user_data_set(uart_dev, tty_uart_isr, tty);
|
||||||
uart_irq_rx_enable(uart_dev);
|
uart_irq_rx_enable(uart_dev);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue