shell: backends: uart: avoid unnecessary TX IRQs
The shell UART TX code would only disable the TX IRQ when no data was available in the TX ring buffer. However, it should also disable the IRQ when all data retrieved from the buffer has been written. Otherwise it will just result in another immediate TX IRQ which results in the IRQ finally being disabled. For this to work, since ring_buf_get_claim may not always return all available data in the ring buffer on a single call, we need to loop until either no data is left in the ring buffer or the UART was unable to consume any of the data. Signed-off-by: Robert Hancock <robert.hancock@calian.com>
This commit is contained in:
parent
2d0b24bff2
commit
d2e5eeb51d
1 changed files with 17 additions and 10 deletions
|
@ -166,7 +166,8 @@ static void dtr_timer_handler(struct k_timer *timer)
|
|||
|
||||
static void uart_tx_handle(const struct device *dev, struct shell_uart_int_driven *sh_uart)
|
||||
{
|
||||
uint32_t len;
|
||||
uint32_t avail;
|
||||
uint32_t written;
|
||||
const uint8_t *data;
|
||||
|
||||
if (!uart_dtr_check(dev)) {
|
||||
|
@ -176,16 +177,22 @@ static void uart_tx_handle(const struct device *dev, struct shell_uart_int_drive
|
|||
return;
|
||||
}
|
||||
|
||||
len = ring_buf_get_claim(&sh_uart->tx_ringbuf, (uint8_t **)&data,
|
||||
do {
|
||||
avail = ring_buf_get_claim(&sh_uart->tx_ringbuf, (uint8_t **)&data,
|
||||
sh_uart->tx_ringbuf.size);
|
||||
if (len) {
|
||||
if (avail) {
|
||||
int err;
|
||||
|
||||
len = uart_fifo_fill(dev, data, len);
|
||||
err = ring_buf_get_finish(&sh_uart->tx_ringbuf, len);
|
||||
written = uart_fifo_fill(dev, data, avail);
|
||||
err = ring_buf_get_finish(&sh_uart->tx_ringbuf, written);
|
||||
__ASSERT_NO_MSG(err == 0);
|
||||
ARG_UNUSED(err);
|
||||
} else {
|
||||
written = 0;
|
||||
}
|
||||
} while (avail && written);
|
||||
|
||||
if (avail == 0) {
|
||||
uart_irq_tx_disable(dev);
|
||||
sh_uart->tx_busy = 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue