Skip to content

Commit

Permalink
drivers: serial: uart_async_rx: Optimize RAM usage
Browse files Browse the repository at this point in the history
Since there is only one consumer of the data stored in the buffers,
it is enough to have one read index variable which can be stored in
the data associated with the module and not in the buffer space (where
there is a read index for each buffer).

Additionally, we can safely assume that module works with small buffers
so 127 byte limit is enough. Based on that assumption completed flag
can be stored on a single byte together with write index. After this
change, control data for each buffer takes 1 byte (3 bytes previously).

Signed-off-by: Krzysztof Chruściński <[email protected]>
  • Loading branch information
nordic-krch authored and nashif committed Mar 26, 2024
1 parent 17dc3da commit 8bc5111
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 12 deletions.
16 changes: 11 additions & 5 deletions drivers/serial/uart_async_rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,14 @@ void uart_async_rx_on_rdy(struct uart_async_rx *rx_data, uint8_t *buffer, size_t

static void buf_reset(struct uart_async_rx_buf *buf)
{
buf->rd_idx = 0;
buf->wr_idx = 0;
buf->completed = 0;
}

static void usr_rx_buf_release(struct uart_async_rx *rx_data, struct uart_async_rx_buf *buf)
{
buf_reset(buf);
rx_data->rd_idx = 0;
rx_data->rd_buf_idx = inc(rx_data, rx_data->rd_buf_idx);
atomic_inc(&rx_data->free_buf_cnt);
__ASSERT_NO_MSG(rx_data->free_buf_cnt <= rx_data->config->buf_cnt);
Expand Down Expand Up @@ -98,8 +99,8 @@ size_t uart_async_rx_data_claim(struct uart_async_rx *rx_data, uint8_t **data, s
}
} while (1);

*data = &buf->buffer[buf->rd_idx];
rem = buf->wr_idx - buf->rd_idx;
*data = &buf->buffer[rx_data->rd_idx];
rem = buf->wr_idx - rx_data->rd_idx;

return MIN(length, rem);
}
Expand All @@ -108,22 +109,23 @@ 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);

buf->rd_idx += length;
rx_data->rd_idx += length;
/* Attempt to release the buffer if it is completed and all data is consumed. */
if ((buf->completed == 1) && (rx_data->rd_idx == buf->wr_idx)) {
usr_rx_buf_release(rx_data, buf);
}

atomic_sub(&rx_data->pending_bytes, length);

__ASSERT_NO_MSG(buf->rd_idx <= buf->wr_idx);
__ASSERT_NO_MSG(rx_data->rd_idx <= buf->wr_idx);

return rx_data->free_buf_cnt > 0;
}

void uart_async_rx_reset(struct uart_async_rx *rx_data)
{
rx_data->free_buf_cnt = rx_data->config->buf_cnt;
rx_data->rd_idx = 0;
for (uint8_t i = 0; i < rx_data->config->buf_cnt; i++) {
buf_reset(get_buf(rx_data, i));
}
Expand All @@ -136,6 +138,10 @@ int uart_async_rx_init(struct uart_async_rx *rx_data,
memset(rx_data, 0, sizeof(*rx_data));
rx_data->config = config;
rx_data->buf_len = (config->length / config->buf_cnt) - UART_ASYNC_RX_BUF_OVERHEAD;

if (rx_data->buf_len >= BIT(7)) {
return -EINVAL;
}
uart_async_rx_reset(rx_data);

return 0;
Expand Down
14 changes: 7 additions & 7 deletions include/zephyr/drivers/serial/uart_async_rx.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,10 @@ struct uart_async_rx_buf {
/* Write index which is incremented whenever new data is reported to be
* received to that buffer.
*/
uint8_t wr_idx;

/* Read index which is incremented whenever data is consumed from the buffer.
* Read index cannot be higher than the write index.
*/
uint8_t rd_idx;
uint8_t wr_idx:7;

/* Set to one if buffer is released by the driver. */
uint8_t completed;
uint8_t completed:1;

/* Location which is passed to the UART driver. */
uint8_t buffer[];
Expand All @@ -56,6 +51,11 @@ struct uart_async_rx {

/* Current buffer from which data is being consumed. */
uint8_t rd_buf_idx;

/* Current read index in the buffer from which data is being consumed.
* Read index which is incremented whenever data is consumed from the buffer.
*/
uint8_t rd_idx;
};

/** @brief UART asynchronous RX helper configuration structure. */
Expand Down

0 comments on commit 8bc5111

Please sign in to comment.