drivers: serial: uart_async_rx: Add return value to consume function

Return availability of free buffers after data is consumed. This
information may be important for the module using uart_async_rx to
schedule next reception if there is a new buffer available.

Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
This commit is contained in:
Krzysztof Chruściński 2024-02-01 10:53:18 +01:00 committed by Anas Nashif
commit d2bd82eb5f
5 changed files with 45 additions and 40 deletions

View file

@ -104,7 +104,7 @@ size_t uart_async_rx_data_claim(struct uart_async_rx *rx_data, uint8_t **data, s
return MIN(length, rem);
}
void uart_async_rx_data_consume(struct uart_async_rx *rx_data, size_t length)
bool uart_async_rx_data_consume(struct uart_async_rx *rx_data, size_t length)
{
struct uart_async_rx_buf *buf = get_buf(rx_data, rx_data->rd_buf_idx);
@ -117,6 +117,8 @@ void uart_async_rx_data_consume(struct uart_async_rx *rx_data, size_t length)
atomic_sub(&rx_data->pending_bytes, length);
__ASSERT_NO_MSG(buf->rd_idx <= buf->wr_idx);
return rx_data->free_buf_cnt > 0;
}
void uart_async_rx_reset(struct uart_async_rx *rx_data)

View file

@ -198,11 +198,11 @@ int z_uart_async_to_irq_fifo_read(const struct device *dev,
}
memcpy(buf, claim_buf, claim_len);
uart_async_rx_data_consume(async_rx, claim_len);
bool buf_available = uart_async_rx_data_consume(async_rx, claim_len);
if (data->rx.pending_buf_req) {
if (data->rx.pending_buf_req && buf_available) {
buf = uart_async_rx_buf_req(async_rx);
if (buf) {
__ASSERT_NO_MSG(buf != NULL);
int err;
size_t rx_len = uart_async_rx_get_buf_len(async_rx);
@ -218,7 +218,6 @@ int z_uart_async_to_irq_fifo_read(const struct device *dev,
}
}
}
}
return (int)claim_len;
}

View file

@ -163,8 +163,11 @@ size_t uart_async_rx_data_claim(struct uart_async_rx *async_rx, uint8_t **data,
*
* @param async_rx Pointer to the helper instance.
* @param length Amount of data to consume. It must be less or equal than amount of claimed data.
*
* @retval true If there are free buffers in the pool after data got consumed.
* @retval false If there are no free buffers.
*/
void uart_async_rx_data_consume(struct uart_async_rx *async_rx, size_t length);
bool uart_async_rx_data_consume(struct uart_async_rx *async_rx, size_t length);
#ifdef __cplusplus
}

View file

@ -454,16 +454,15 @@ static int async_read(struct shell_uart_async *sh_uart,
memcpy(data, buf, blen);
#endif
uart_async_rx_data_consume(async_rx, sh_cnt);
bool buf_available = uart_async_rx_data_consume(async_rx, sh_cnt);
*cnt = sh_cnt;
if (sh_uart->pending_rx_req) {
if (sh_uart->pending_rx_req && buf_available) {
uint8_t *buf = uart_async_rx_buf_req(async_rx);
if (buf) {
int err;
size_t len = uart_async_rx_get_buf_len(async_rx);
int err;
__ASSERT_NO_MSG(buf != NULL);
atomic_dec(&sh_uart->pending_rx_req);
err = uart_rx_buf_rsp(sh_uart->common.dev, buf, len);
/* If it is too late and RX is disabled then re-enable it. */
@ -476,7 +475,6 @@ static int async_read(struct shell_uart_async *sh_uart,
}
}
}
}
return 0;
}

View file

@ -41,6 +41,7 @@ ZTEST(uart_async_rx, test_rx)
uint8_t *claim_buf;
uint8_t *aloc_buf;
struct uart_async_rx async_rx;
bool buf_available;
const struct uart_async_rx_config config = {
.buffer = buf,
.length = sizeof(buf),
@ -87,7 +88,8 @@ ZTEST(uart_async_rx, test_rx)
zassert_true(mem_check(claim_buf, 0, aloc_len - 2));
/* Consume first 2 bytes. */
uart_async_rx_data_consume(&async_rx, 2);
buf_available = uart_async_rx_data_consume(&async_rx, 2);
zassert_true(buf_available);
/* Now claim will return buffer taking into account that first 2 bytes are
* consumed.
@ -98,7 +100,8 @@ ZTEST(uart_async_rx, test_rx)
zassert_true(mem_check(claim_buf, 2, aloc_len - 4));
/* Consume rest of data. Get indication that it was end of the buffer. */
uart_async_rx_data_consume(&async_rx, aloc_len - 4);
buf_available = uart_async_rx_data_consume(&async_rx, aloc_len - 4);
zassert_true(buf_available);
}
ZTEST(uart_async_rx, test_rx_late_consume)
@ -134,7 +137,7 @@ ZTEST(uart_async_rx, test_rx_late_consume)
zassert_equal(claim_len, 1);
zassert_equal(claim_buf[0], (uint8_t)i);
uart_async_rx_data_consume(&async_rx, 1);
(void)uart_async_rx_data_consume(&async_rx, 1);
}
claim_len = uart_async_rx_data_claim(&async_rx, &claim_buf, 100);
@ -217,13 +220,13 @@ static bool consumer(void *user_data, uint32_t cnt, bool last, int prio)
test_data->exp_consume++;
}
uart_async_rx_data_consume(async_rx, len);
bool buf_released = uart_async_rx_data_consume(async_rx, len);
if (test_data->pending_req) {
if (buf_released && test_data->pending_req) {
buf = uart_async_rx_buf_req(async_rx);
if (buf) {
zassert_true(buf != NULL);
atomic_dec(&test_data->pending_req);
}
k_spinlock_key_t key = k_spin_lock(&test_data->lock);
if (test_data->curr_buf == NULL) {