drivers: uart_emul: Add Emulated Errors

Allows test code to set UART errors, for driver code wanting
to test proper error handling.

Signed-off-by: Nick Kraus <nick@nckraus.com>
This commit is contained in:
Nick Kraus 2023-10-15 15:14:24 -04:00 committed by Carles Cufí
parent aeb85db627
commit 0f50df41f1
3 changed files with 48 additions and 1 deletions

View file

@ -29,6 +29,7 @@ struct uart_emul_work {
/* Device run time data */
struct uart_emul_data {
struct uart_config cfg;
int errors;
struct ring_buf *rx_rb;
struct k_spinlock rx_lock;
@ -93,7 +94,11 @@ static void uart_emul_poll_out(const struct device *dev, unsigned char out_char)
static int uart_emul_err_check(const struct device *dev)
{
return 0;
struct uart_emul_data *drv_data = dev->data;
int errors = drv_data->errors;
drv_data->errors = 0;
return errors;
}
#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
@ -350,6 +355,10 @@ uint32_t uart_emul_put_rx_data(const struct device *dev, uint8_t *data, size_t s
IF_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN, (irq_en = drv_data->rx_irq_en;));
}
if (count < size) {
uart_emul_set_errors(dev, UART_ERROR_OVERRUN);
}
IF_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN, (
if (count > 0 && irq_en && !empty) {
(void)k_work_submit(&drv_data->irq_work.work);
@ -397,6 +406,13 @@ uint32_t uart_emul_flush_tx_data(const struct device *dev)
return count;
}
void uart_emul_set_errors(const struct device *dev, int errors)
{
struct uart_emul_data *drv_data = dev->data;
drv_data->errors |= errors;
}
#define UART_EMUL_RX_FIFO_SIZE(inst) (DT_INST_PROP(inst, rx_fifo_size))
#define UART_EMUL_TX_FIFO_SIZE(inst) (DT_INST_PROP(inst, tx_fifo_size))

View file

@ -83,6 +83,14 @@ uint32_t uart_emul_flush_rx_data(const struct device *dev);
*/
uint32_t uart_emul_flush_tx_data(const struct device *dev);
/**
* @brief Sets one or more driver errors
*
* @param dev The emulated UART device instance
* @param errors The @ref uart_rx_stop_reason errors to set
*/
void uart_emul_set_errors(const struct device *dev, int errors);
#ifdef __cplusplus
}
#endif

View file

@ -40,6 +40,8 @@ static void uart_emul_before(void *f)
uart_emul_flush_rx_data(fixture->dev);
uart_emul_flush_tx_data(fixture->dev);
uart_err_check(fixture->dev);
}
ZTEST_F(uart_emul, test_polling_out)
@ -78,6 +80,27 @@ ZTEST_F(uart_emul, test_polling_in)
zassert_equal(rc, -1, "RX buffer should be empty");
}
ZTEST_F(uart_emul, test_errors)
{
int errors;
uart_emul_set_errors(fixture->dev, (UART_ERROR_PARITY | UART_ERROR_FRAMING));
errors = uart_err_check(fixture->dev);
zassert_equal(errors, (UART_ERROR_PARITY | UART_ERROR_FRAMING), "UART errors do not match");
/* uart_err_check should also clear existing errors */
errors = uart_err_check(fixture->dev);
zassert_equal(errors, 0, "Should be no errors");
/* overflowing rx buffer should produce an overrun error */
uart_emul_put_rx_data(fixture->dev, fixture->sample_data, SAMPLE_DATA_SIZE);
errors = uart_err_check(fixture->dev);
zassert_equal(errors, 0, "Should be no errors");
uart_emul_put_rx_data(fixture->dev, fixture->sample_data, SAMPLE_DATA_SIZE);
errors = uart_err_check(fixture->dev);
zassert_equal(errors, UART_ERROR_OVERRUN, "UART errors do not match");
}
static void uart_emul_isr(const struct device *dev, void *user_data)
{
/* always of size SAMPLE_DATA_SIZE */