Skip to content
Open
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
7 changes: 5 additions & 2 deletions bsp/nxp/imx/imx6ull-smart/drivers/drv_uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,11 @@ static rt_err_t _uart_ops_configure( struct rt_serial_device *dev,
RT_ASSERT(RT_NULL != dev);
RT_ASSERT(RT_NULL != cfg);

if (cfg->baud_rate == 0 || cfg->baud_rate > BAUD_RATE_921600)
{
return -RT_EINVAL;
}

uart = (struct imx_uart*)dev;
periph = (UART_Type*)uart->periph.vaddr;

Expand All @@ -188,8 +193,6 @@ static rt_err_t _uart_ops_configure( struct rt_serial_device *dev,
periph->UFCR &= ~UART_UFCR_RFDIV_MASK;
periph->UFCR |= UART_UFCR_RFDIV(5);

RT_ASSERT(cfg->baud_rate <= BAUD_RATE_921600);

periph->UBIR = UART_UBIR_INC(15);
periph->UBMR = UART_UBMR_MOD(HW_UART_BUS_CLOCK / cfg->baud_rate - 1);

Expand Down
140 changes: 133 additions & 7 deletions components/drivers/serial/dev_serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@
#include <unistd.h>
#include <poll.h>
#include <sys/ioctl.h>
#ifdef RT_USING_LWP
#include <lwp.h>
#include <lwp_user_mm.h>
#endif

#ifdef RT_USING_POSIX_TERMIOS
#include <termios.h>
Expand Down Expand Up @@ -138,6 +142,114 @@ static int serial_fops_ioctl(struct dfs_file *fd, int cmd, void *args)
break;
}

#ifdef RT_USING_LWP
if (lwp_self() != RT_NULL)
{
union serial_user_ioctl_arg
{
struct serial_configure config;
struct winsize winsize;
#ifdef RT_USING_POSIX_TERMIOS
struct termios termios;
struct termio termio;
#endif
rt_uint16_t oflag;
int unread_bytes;
} karg;
size_t arg_size = 0;
void *kptr = args;
rt_bool_t copy_in = RT_FALSE;
rt_bool_t copy_out = RT_FALSE;

rt_memset(&karg, 0, sizeof(karg));

switch ((rt_ubase_t)cmd)
{
case RT_DEVICE_CTRL_CONFIG:
arg_size = sizeof(karg.config);
kptr = &karg.config;
copy_in = RT_TRUE;
break;
case RT_DEVICE_CTRL_NOTIFY_SET:
return -RT_EPERM;
case RT_DEVICE_CTRL_CONSOLE_OFLAG:
arg_size = sizeof(karg.oflag);
kptr = &karg.oflag;
copy_out = RT_TRUE;
break;
case FIONREAD:
arg_size = sizeof(karg.unread_bytes);
kptr = &karg.unread_bytes;
copy_out = RT_TRUE;
Comment on lines +180 to +183
break;
#ifdef RT_USING_POSIX_TERMIOS
case TCGETA:
arg_size = sizeof(karg.termio);
kptr = &karg.termio;
copy_out = RT_TRUE;
break;
case TCGETS:
arg_size = sizeof(karg.termios);
kptr = &karg.termios;
copy_out = RT_TRUE;
break;
case TCSETA:
case TCSETAW:
case TCSETAF:
arg_size = sizeof(karg.termio);
kptr = &karg.termio;
copy_in = RT_TRUE;
Comment on lines +196 to +201
break;
case TCSETS:
case TCSETSW:
case TCSETSF:
arg_size = sizeof(karg.termios);
kptr = &karg.termios;
copy_in = RT_TRUE;
break;
#endif
case TIOCSWINSZ:
arg_size = sizeof(karg.winsize);
kptr = &karg.winsize;
copy_in = RT_TRUE;
break;
case TIOCGWINSZ:
arg_size = sizeof(karg.winsize);
kptr = &karg.winsize;
copy_out = RT_TRUE;
break;
default:
break;
}

if (arg_size)
{
int ret;

if (args == RT_NULL || !lwp_user_accessable(args, arg_size))
{
return -RT_EFAULT;
}
if (copy_in && lwp_get_from_user(kptr, args, arg_size) != arg_size)
{
return -RT_EFAULT;
}

ret = rt_device_control(device, cmd, kptr);
if (ret != RT_EOK)
{
return ret;
}

if (copy_out && lwp_put_to_user(args, kptr, arg_size) != arg_size)
{
return -RT_EFAULT;
}
return ret;
}
}
#endif

return rt_device_control(device, cmd, args);
}

Expand Down Expand Up @@ -1090,13 +1202,22 @@ static rt_err_t rt_serial_control(struct rt_device *dev,
/*can not change buffer size*/
return -RT_EBUSY;
}
/* set serial configure */
serial->config = *pconfig;
if (pconfig->baud_rate == 0)
{
return -RT_EINVAL;
}

if (serial->parent.ref_count)
{
/* serial device has been opened, to configure it */
serial->ops->configure(serial, (struct serial_configure *) args);
ret = serial->ops->configure(serial, pconfig);
if (ret != RT_EOK)
{
return ret;
}
}
/* set serial configure */
serial->config = *pconfig;
}
break;
case RT_DEVICE_CTRL_NOTIFY_SET:
Expand All @@ -1117,7 +1238,7 @@ static rt_err_t rt_serial_control(struct rt_device *dev,
case TCGETA:
case TCGETS:
{
struct termios *tio, tmp;
struct termios *tio, tmp = { 0 };

if (cmd == TCGETS)
{
Expand Down Expand Up @@ -1218,7 +1339,12 @@ static rt_err_t rt_serial_control(struct rt_device *dev,
}
else config.parity = PARITY_NONE;

serial->ops->configure(serial, &config);
ret = serial->ops->configure(serial, &config);
if (ret != RT_EOK)
{
return ret;
}
serial->config = config;
}
break;
#ifndef RT_USING_TTY
Expand Down Expand Up @@ -1327,14 +1453,14 @@ static rt_err_t rt_serial_control(struct rt_device *dev,
break;
case FIONREAD:
{
rt_size_t recved = 0;
rt_ssize_t recved = 0;
rt_base_t level;

level = rt_spin_lock_irqsave(&(serial->spinlock));
recved = _serial_fifo_calc_recved_len(serial);
rt_spin_unlock_irqrestore(&(serial->spinlock), level);

*(rt_size_t *)args = recved;
*(int *)args = (int)recved;
}
break;
#endif /* RT_USING_POSIX_STDIO */
Expand Down
Loading
Loading