Skip to content

drivers: serial: native_tty: config_get support #93149

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions drivers/serial/uart_native_tty.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <zephyr/drivers/uart.h>
#include <zephyr/kernel.h>

#include <nsi_errno.h>
#include <nsi_tracing.h>

#include "cmdline.h"
Expand Down Expand Up @@ -130,6 +131,73 @@ static int native_tty_conv_to_bottom_cfg(struct native_tty_bottom_cfg *bottom_cf
return 0;
}

/**
* @brief Convert from native_tty_bottom_cfg to uart_config
*
* @param bottom_cfg
* @param cfg
*
* @return 0 on success, negative errno otherwise.
*/
int native_tty_conv_from_bottom_cfg(int fd, struct uart_config *cfg)
{
struct native_tty_bottom_cfg bottom_cfg;
int rc = 0;

rc = native_tty_read_bottom_cfg(fd, &bottom_cfg);
if (rc != 0) {
return nsi_errno_from_mid(rc);
}

cfg->baudrate = bottom_cfg.baudrate;

switch (bottom_cfg.parity) {
case NTB_PARITY_NONE:
cfg->parity = UART_CFG_PARITY_NONE;
break;
case NTB_PARITY_ODD:
cfg->parity = UART_CFG_PARITY_ODD;
break;
case NTB_PARITY_EVEN:
cfg->parity = UART_CFG_PARITY_EVEN;
break;
default:
return -ENOTSUP;
}

switch (bottom_cfg.stop_bits) {
case NTB_STOP_BITS_1:
cfg->stop_bits = UART_CFG_STOP_BITS_1;
break;
case NTB_STOP_BITS_2:
cfg->stop_bits = UART_CFG_STOP_BITS_2;
break;
default:
return -ENOTSUP;
}

switch (bottom_cfg.data_bits) {
case NTB_DATA_BITS_5:
cfg->data_bits = UART_CFG_DATA_BITS_5;
break;
case NTB_DATA_BITS_6:
cfg->data_bits = UART_CFG_DATA_BITS_6;
break;
case NTB_DATA_BITS_7:
cfg->data_bits = UART_CFG_DATA_BITS_7;
break;
case NTB_DATA_BITS_8:
cfg->data_bits = UART_CFG_DATA_BITS_8;
break;
default:
return -ENOTSUP;
}

cfg->flow_ctrl = UART_CFG_FLOW_CTRL_NONE;

return 0;
}

/*
* @brief Output a character towards the serial port
*
Expand Down Expand Up @@ -177,6 +245,20 @@ static int native_tty_configure(const struct device *dev, const struct uart_conf
return native_tty_configure_bottom(fd, &bottom_cfg);
}

static int native_tty_config_get(const struct device *dev, struct uart_config *cfg)
{
int fd = ((struct native_tty_data *)dev->data)->fd;
int rc = 0;

rc = native_tty_conv_from_bottom_cfg(fd, cfg);
if (rc) {
WARN("Could not convert native tty bottom cfg to uart config\n");
return rc;
}

return 0;
}

#ifdef CONFIG_UART_INTERRUPT_DRIVEN
static int native_tty_uart_fifo_fill(const struct device *dev,
const uint8_t *tx_data,
Expand Down Expand Up @@ -375,6 +457,7 @@ static DEVICE_API(uart, native_tty_uart_driver_api) = {
.poll_in = native_tty_uart_poll_in,
#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
.configure = native_tty_configure,
.config_get = native_tty_config_get,
#endif
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
.fifo_fill = native_tty_uart_fifo_fill,
Expand Down
106 changes: 106 additions & 0 deletions drivers/serial/uart_native_tty_bottom.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <termios.h>
#include <unistd.h>

#include <nsi_errno.h>
#include <nsi_tracing.h>

#define WARN(...) nsi_print_warning(__VA_ARGS__)
Expand Down Expand Up @@ -90,6 +91,31 @@ static inline void native_tty_baud_speed_set(struct termios *ter, int baudrate)
ERROR("Could not set baudrate, as %d is not supported.\n", baudrate);
}

/**
* @brief Get the baud rate speed from the termios structure
*
* @param ter
* @param baudrate
*/
static inline void native_tty_baud_speed_get(const struct termios *ter, uint32_t *baudrate)
{
speed_t ispeed = cfgetispeed(ter);
speed_t ospeed = cfgetospeed(ter);

if (ispeed != ospeed) {
ERROR("Input and output baud rates differ: %d vs %d\n", ispeed, ospeed);
}

for (int i = 0; i < ARRAY_SIZE(baudrate_lut); i++) {
if (baudrate_lut[i].termios_baudrate == ispeed) {
*baudrate = baudrate_lut[i].baudrate;
return;
}
}

ERROR("Unsupported termios baudrate: %d\n", ispeed);
}

/**
* @brief Set parity setting in the termios structure
*
Expand Down Expand Up @@ -117,6 +143,24 @@ static inline void native_tty_baud_parity_set(struct termios *ter,
}
}

/**
* @brief Get the parity setting from the termios structure
*
* @param ter
* @param parity
*/
static inline void native_tty_baud_parity_get(const struct termios *ter,
enum native_tty_bottom_parity *parity)
{
if ((ter->c_cflag & PARENB) == 0) {
*parity = NTB_PARITY_NONE;
} else if (ter->c_cflag & PARODD) {
*parity = NTB_PARITY_ODD;
} else {
*parity = NTB_PARITY_EVEN;
}
}

/**
* @brief Set the number of stop bits in the termios structure
*
Expand All @@ -140,6 +184,18 @@ static inline void native_tty_stop_bits_set(struct termios *ter,
}
}

/**
* @brief Get the number of stop bits from the termios structure
*
* @param ter
* @param stop_bits
*/
static inline void native_tty_stop_bits_get(const struct termios *ter,
enum native_tty_bottom_stop_bits *stop_bits)
{
*stop_bits = (ter->c_cflag & CSTOPB) ? NTB_STOP_BITS_2 : NTB_STOP_BITS_1;
}

/**
* @brief Set the number of data bits in the termios structure
*
Expand Down Expand Up @@ -175,6 +231,33 @@ static inline void native_tty_data_bits_set(struct termios *ter,
ter->c_cflag |= data_bits_to_set;
}

/**
* @brief Get the number of data bits from the termios structure
*
* @param ter
* @param data_bits
*/
static inline void native_tty_data_bits_get(const struct termios *ter,
enum native_tty_bottom_data_bits *data_bits)
{
switch (ter->c_cflag & CSIZE) {
case CS5:
*data_bits = NTB_DATA_BITS_5;
break;
case CS6:
*data_bits = NTB_DATA_BITS_6;
break;
case CS7:
*data_bits = NTB_DATA_BITS_7;
break;
case CS8:
*data_bits = NTB_DATA_BITS_8;
break;
default:
ERROR("Unsupported data bits setting in termios.\n");
}
}

int native_tty_poll_bottom(int fd)
{
struct pollfd pfd = { .fd = fd, .events = POLLIN };
Expand Down Expand Up @@ -252,3 +335,26 @@ int native_tty_configure_bottom(int fd, struct native_tty_bottom_cfg *cfg)

return 0;
}

int native_tty_read_bottom_cfg(int fd, struct native_tty_bottom_cfg *cfg)
{
struct termios ter;
int rc = 0;

rc = tcgetattr(fd, &ter);
if (rc != 0) {
int err = 0;

err = errno;
Comment on lines +346 to +348
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
int err = 0;
err = errno;
int err = errno;

Just saw this now, but you don't need to bother with it if you don't need to push again

WARN("Could not read terminal driver settings: %s\n", strerror(err));
return -nsi_errno_to_mid(err);
}

native_tty_baud_speed_get(&ter, &cfg->baudrate);
native_tty_baud_parity_get(&ter, &cfg->parity);
native_tty_data_bits_get(&ter, &cfg->data_bits);
native_tty_stop_bits_get(&ter, &cfg->stop_bits);
cfg->flow_ctrl = NTB_FLOW_CTRL_NONE;

return 0;
}
10 changes: 10 additions & 0 deletions drivers/serial/uart_native_tty_bottom.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,16 @@ int native_tty_open_tty_bottom(const char *pathname);
*/
int native_tty_configure_bottom(int fd, struct native_tty_bottom_cfg *cfg);

/**
* @brief Read bottom tty configuration
*
* @param fd
* @param cfg
*
* @return 0 on success, negative value on error
*/
int native_tty_read_bottom_cfg(int fd, struct native_tty_bottom_cfg *cfg);

#ifdef __cplusplus
}
#endif
Expand Down