drivers/serial/tcdrain: tcdrain() was recently added to the NuttX C library. But there is a problem. The specification of tcdrain() requires that it be a cancellation point. In order to do this, tcdrain was moved from the C library into the OS and the addition cancellation point hooks were added. In non-FLAT builds, access via system calls is also now supported.

This commit is contained in:
Gregory Nutt 2017-10-06 10:55:36 -06:00
parent 936df1bcb5
commit 5b04c25dcd
12 changed files with 61 additions and 43 deletions

2
TODO
View File

@ -530,7 +530,7 @@ o pthreads (sched/pthreads)
NA clock_nanosleep() NA msgsnd() read() sigwaitinfo()
close() NA msync() NA readv() 01 sleep()
connect() nanosleep() recv() 02 system()
-- creat() open() recvfrom() NA tcdrain()
-- creat() open() recvfrom() tcdrain()
fcntl() pause() NA recvmsg() 01 usleep()
NA fdatasync() poll() select() -- wait()
fsync() pread() sem_timedwait() waitid()

View File

@ -7,27 +7,22 @@ comment "LC823450 Configuration Options"
menu "LC823450 Peripheral Support"
config SERIAL_TERMIOS
bool "Serial driver TERMIOS supported"
default n
---help---
Serial driver supports termios.h interfaces (tcsetattr, tcflush, etc.).
If this is not defined, then the terminal settings (baud, parity, etc).
are not configurable at runtime; serial streams cannot be flushed, etc..
config LC823450_UART0
bool "UART0"
select UART0_SERIALDRIVER
select ARCH_HAVE_SERIAL_TERMIOS
default n
config LC823450_UART1
bool "UART1"
select UART1_SERIALDRIVER
select ARCH_HAVE_SERIAL_TERMIOS
default n
config LC823450_UART2
bool "UART2"
select UART2_SERIALDRIVER
select ARCH_HAVE_SERIAL_TERMIOS
default n
config LC823450_WDT

View File

@ -56,6 +56,7 @@ config LPC11_PLL
config LPC11_UART0
bool "UART0"
select UART0_SERIALDRIVER
select ARCH_HAVE_SERIAL_TERMIOS
default y
config LPC11_CAN0
@ -100,20 +101,6 @@ config LPC11_FLASH
endmenu
menu "Serial driver options"
depends on LPC11_UART0 || LPC11_UART1 || LPC11_UART2 || LPC11_UART3 || LPC11_UART4
config SERIAL_TERMIOS
bool "Serial driver TERMIOS supported"
depends on LPC11_UART0 || LPC11_UART1 || LPC11_UART2 || LPC11_UART3
default n
---help---
Serial driver supports termios.h interfaces (tcsetattr, tcflush, etc.).
If this is not defined, then the terminal settings (baud, parity, etc).
are not configurable at runtime; serial streams cannot be flushed, etc..
endmenu
menu "ADC driver options"
depends on LPC11_ADC

View File

@ -32,24 +32,12 @@ menu "ATMega Peripheral Selections"
config AVR_USART0
bool "USART0"
select USART0_SERIALDRIVER
select ARCH_HAVE_SERIAL_TERMIOS
config AVR_USART1
bool "USART1"
select USART1_SERIALDRIVER
select ARCH_HAVE_SERIAL_TERMIOS
endmenu # ATMega Peripheral Selections
menu "Low level USART driver options"
depends on AVR_USART0 || AVR_USART1
config SERIAL_TERMIOS
bool "Serial driver TERMIOS supported"
depends on AVR_USART0 || AVR_USART1
default n
---help---
Serial driver supports termios.h interfaces (tcsetattr, tcflush, etc.).
If this is not defined, then the terminal settings (baud, parity, etc).
are not configurable at runtime; serial streams cannot be flushed, etc..
endmenu
endif

View File

@ -1,7 +1,7 @@
############################################################################
# drivers/serial/Make.defs
#
# Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
# Copyright (C) 2009, 2011, 2017 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
@ -47,6 +47,12 @@ ifeq ($(CONFIG_16550_UART),y)
CSRCS += uart_16550.c
endif
# termios support
ifeq ($(CONFIG_SERIAL_TERMIOS),y)
CSRCS += tcdrain.c
endif
# Pseudo-terminal support
ifeq ($(CONFIG_PSEUDOTERM),y)

View File

@ -1,5 +1,5 @@
/****************************************************************************
* libc/termios/lib_tcdrain.c
* drivers/serial/tcdrain.c
*
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
* Copyright (C) 2017 Sebastien Lorquet. All rights reserved.
@ -45,6 +45,7 @@
#include <termios.h>
#include <errno.h>
#include <nuttx/cancelpt.h>
#include <nuttx/serial/tioctl.h>
/****************************************************************************
@ -68,5 +69,33 @@
int tcdrain(int fd)
{
return ioctl(fd, TCDRN, (unsigned long)0);
int ret;
/* tcdrain is a cancellation point */
if (enter_cancellation_point())
{
#ifdef CONFIG_CANCELLATION_POINTS
/* If there is a pending cancellation, then do not perform
* the wait. Exit now with ECANCELED.
*/
set_errno(ECANCELED);
leave_cancellation_point();
return ERROR;
#endif
}
/* Perform the TCDRM IOCTL command. It is safe to use the file descriptor
* in this context because we are executing on the calling application's
* thread.
*
* NOTE: ioctl() will set the errno variable and return ERROR is any error
* occurs.
*/
ret = ioctl(fd, TCDRN, (unsigned long)0);
leave_cancellation_point();
return ret;
}

View File

@ -298,9 +298,15 @@
# ifndef CONFIG_DISABLE_POLL
# define SYS_poll __SYS_poll
# define SYS_select (__SYS_poll+1)
# define __SYS_boardctl (__SYS_poll+2)
# define __SYS_termios (__SYS_poll+2)
# else
# define __SYS_boardctl __SYS_poll
# define __SYS_termios __SYS_poll
# endif
# ifndef CONFIG_SERIAL_TERMIOS
# define SYS_tcdrain __SYS_termios
# define __SYS_boardctl (__SYS_termios+1)
# else
# define __SYS_boardctl __SYS_termios
# endif
#else
# define __SYS_boardctl __SYS_descriptors

View File

@ -42,7 +42,7 @@ ifeq ($(CONFIG_SERIAL_TERMIOS),y)
# Add the termios C files to the build
CSRCS += lib_cfgetspeed.c lib_cfsetspeed.c lib_isatty.c lib_tcflush.c
CSRCS += lib_tcgetattr.c lib_tcsetattr.c lib_tcdrain.c
CSRCS += lib_tcgetattr.c lib_tcsetattr.c
# Add the termios directory to the build

View File

@ -153,6 +153,7 @@
"task_setcancelstate","sched.h","","int","int","FAR int*"
"task_setcanceltype","sched.h","defined(CONFIG_CANCELLATION_POINTS)","int","int","FAR int*"
"task_testcancel","pthread.h","defined(CONFIG_CANCELLATION_POINTS)","void"
"tcdrain","termios.h","defined(CONFIG_SERIAL_TERMIOS)","int","int"
"telldir","dirent.h","CONFIG_NFILE_DESCRIPTORS > 0","off_t","FAR DIR*"
"timer_create","time.h","!defined(CONFIG_DISABLE_POSIX_TIMERS)","int","clockid_t","FAR struct sigevent*","FAR timer_t*"
"timer_delete","time.h","!defined(CONFIG_DISABLE_POSIX_TIMERS)","int","timer_t"

Can't render this file because it has a wrong number of fields in line 2.

View File

@ -72,6 +72,7 @@
#include <signal.h>
#include <mqueue.h>
#include <spawn.h>
#include <termios.h>
#include <assert.h>
/* Errno access is awkward. We need to generate get_errno() and set_errno()

View File

@ -211,6 +211,9 @@ SYSCALL_LOOKUP(up_assert, 2, STUB_up_assert)
SYSCALL_LOOKUP(poll, 3, STUB_poll)
SYSCALL_LOOKUP(select, 5, STUB_select)
# endif
# ifndef CONFIG_SERIAL_TERMIOS
SYSCALL_LOOKUP(tcdrain, 1, STUB_tcdrain)
# endif
#endif
/* Board support */

View File

@ -210,6 +210,8 @@ uintptr_t STUB_aio_write(int nbr, uintptr_t parm1);
uintptr_t STUB_aio_fsync(int nbr, uintptr_t parm1, uintptr_t parm2);
uintptr_t STUB_aio_cancel(int nbr, uintptr_t parm1, uintptr_t parm2);
uintptr_t STUB_tcdrain(int nbr, uintptr_t parm1);
/* Board support */
uintptr_t STUB_boardctl(int nbr, uintptr_t parm1, uintptr_t parm2);