arch/sim/src/: Reimplement sim uart on top of serial driver framework
The benefits include: 1. Simplify the implementation 2. Support Ctrl+C automatically 3. Support poll automatically 4. Call pm_activity automatically 5. Save one polling thread
This commit is contained in:
parent
6d69439f58
commit
fa3e66fe82
@ -84,6 +84,7 @@ ifeq ($(CONFIG_SMP),y)
|
||||
CSRCS += up_smpsignal.c up_smphook.c up_cpuidlestack.c
|
||||
HOSTCFLAGS += -DCONFIG_SMP=1 -DCONFIG_SMP_NCPUS=$(CONFIG_SMP_NCPUS)
|
||||
HOSTSRCS += up_simsmp.c
|
||||
STDLIBS += -lpthread
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SCHED_INSTRUMENTATION),y)
|
||||
@ -94,7 +95,7 @@ endif
|
||||
|
||||
ifeq ($(CONFIG_DEV_CONSOLE),y)
|
||||
ifneq ($(CONFIG_SYSLOG_RPMSG),y)
|
||||
CSRCS += up_devconsole.c up_uartwait.c
|
||||
CSRCS += up_devconsole.c
|
||||
HOSTSRCS += up_simuart.c
|
||||
endif
|
||||
endif
|
||||
@ -135,6 +136,7 @@ endif
|
||||
|
||||
ifeq ($(CONFIG_FS_FAT),y)
|
||||
CSRCS += up_blockdevice.c up_deviceimage.c
|
||||
STDLIBS += -lz
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARCH_ROMGETC),y)
|
||||
@ -208,13 +210,6 @@ endif
|
||||
EXTRA_LIBS ?=
|
||||
EXTRA_LIBPATHS ?=
|
||||
|
||||
ifeq ($(CONFIG_FS_FAT),y)
|
||||
STDLIBS += -lz
|
||||
endif
|
||||
|
||||
STDLIBS += -lc
|
||||
STDLIBS += -lpthread
|
||||
|
||||
# Determine which objects are required in the link. The
|
||||
# up_head object normally draws in all that is needed, but
|
||||
# there are a fews that must be included because they
|
||||
@ -223,12 +218,6 @@ STDLIBS += -lpthread
|
||||
LINKOBJS = up_head$(OBJEXT)
|
||||
REQUIREDOBJS = $(LINKOBJS)
|
||||
|
||||
ifeq ($(CONFIG_DEV_CONSOLE),y)
|
||||
ifneq ($(CONFIG_SYSLOG_RPMSG),y)
|
||||
REQUIREDOBJS += up_uartwait$(OBJEXT)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SIM_X11FB),y)
|
||||
ifeq ($(CONFIG_SIM_TOUCHSCREEN),y)
|
||||
REQUIREDOBJS += up_touchscreen$(OBJEXT)
|
||||
|
@ -38,37 +38,70 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdbool.h>
|
||||
#include <sched.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/serial/serial.h>
|
||||
|
||||
#include "up_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define DEVCONSOLE_BUFSIZE 256
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
static ssize_t devconsole_read(FAR struct file *filep, FAR char *buffer,
|
||||
size_t buflen);
|
||||
static ssize_t devconsole_write(FAR struct file *filep,
|
||||
FAR const char *buffer, size_t buflen);
|
||||
static int devconsole_poll(FAR struct file *filep, FAR struct pollfd *fds,
|
||||
bool setup);
|
||||
static int devconsole_setup(FAR struct uart_dev_s *dev);
|
||||
static void devconsole_shutdown(FAR struct uart_dev_s *dev);
|
||||
static int devconsole_attach(FAR struct uart_dev_s *dev);
|
||||
static void devconsole_detach(FAR struct uart_dev_s *dev);
|
||||
static int devconsole_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
|
||||
static int devconsole_receive(FAR struct uart_dev_s *dev, uint32_t *status);
|
||||
static void devconsole_rxint(FAR struct uart_dev_s *dev, bool enable);
|
||||
static bool devconsole_rxavailable(FAR struct uart_dev_s *dev);
|
||||
static void devconsole_send(FAR struct uart_dev_s *dev, int ch);
|
||||
static void devconsole_txint(FAR struct uart_dev_s *dev, bool enable);
|
||||
static bool devconsole_txready(FAR struct uart_dev_s *dev);
|
||||
static bool devconsole_txempty(FAR struct uart_dev_s *dev);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static const struct file_operations devconsole_fops =
|
||||
static const struct uart_ops_s g_devconsole_ops =
|
||||
{
|
||||
.read = devconsole_read,
|
||||
.write = devconsole_write,
|
||||
.poll = devconsole_poll,
|
||||
.setup = devconsole_setup,
|
||||
.shutdown = devconsole_shutdown,
|
||||
.attach = devconsole_attach,
|
||||
.detach = devconsole_detach,
|
||||
.ioctl = devconsole_ioctl,
|
||||
.receive = devconsole_receive,
|
||||
.rxint = devconsole_rxint,
|
||||
.rxavailable = devconsole_rxavailable,
|
||||
.send = devconsole_send,
|
||||
.txint = devconsole_txint,
|
||||
.txready = devconsole_txready,
|
||||
.txempty = devconsole_txempty,
|
||||
};
|
||||
|
||||
static char g_devconsole_rxbuf[DEVCONSOLE_BUFSIZE];
|
||||
static char g_devconsole_txbuf[DEVCONSOLE_BUFSIZE];
|
||||
|
||||
static struct uart_dev_s g_devconsole_dev =
|
||||
{
|
||||
.isconsole = true,
|
||||
.ops = &g_devconsole_ops,
|
||||
.xmit =
|
||||
{
|
||||
.size = DEVCONSOLE_BUFSIZE,
|
||||
.buffer = g_devconsole_txbuf,
|
||||
},
|
||||
.recv =
|
||||
{
|
||||
.size = DEVCONSOLE_BUFSIZE,
|
||||
.buffer = g_devconsole_rxbuf,
|
||||
},
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
@ -76,83 +109,176 @@ static const struct file_operations devconsole_fops =
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: devconsole_read
|
||||
* Name: devconsole_setup
|
||||
*
|
||||
* Description:
|
||||
* Configure the UART baud, bits, parity, fifos, etc. This
|
||||
* method is called the first time that the serial port is
|
||||
* opened.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static ssize_t devconsole_read(struct file *filep, char *buffer, size_t len)
|
||||
{
|
||||
size_t remaining = len;
|
||||
ssize_t nread;
|
||||
int ch;
|
||||
|
||||
/* Loop until all requested bytes have been read. No error checking */
|
||||
|
||||
sched_lock();
|
||||
for (remaining = len, nread = 0; remaining > 0; remaining--)
|
||||
{
|
||||
/* Read the next character from the console, we should only wait
|
||||
* on the first read.
|
||||
*/
|
||||
|
||||
ch = simuart_getc(!(filep->f_oflags & O_NONBLOCK));
|
||||
if (ch < 0)
|
||||
{
|
||||
/* errno is set in upper layer according to returned value */
|
||||
|
||||
sched_unlock();
|
||||
return ch;
|
||||
}
|
||||
|
||||
*buffer++ = ch;
|
||||
nread++;
|
||||
|
||||
/* We have at least one character. Return now if no further
|
||||
* characters are available without waiting.
|
||||
*/
|
||||
|
||||
if (!simuart_checkc())
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sched_unlock();
|
||||
return nread;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: devconsole_write
|
||||
****************************************************************************/
|
||||
|
||||
static ssize_t devconsole_write(struct file *filep, const char *buffer, size_t len)
|
||||
{
|
||||
int remaining;
|
||||
int ret = OK;
|
||||
|
||||
for (remaining = len; remaining > 0 && ret >= 0; remaining--)
|
||||
{
|
||||
unsigned char ch = *buffer++;
|
||||
ret = simuart_putc((int)ch);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
return -ret;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: devconsole_poll
|
||||
****************************************************************************/
|
||||
|
||||
static int devconsole_poll(FAR struct file *filep, FAR struct pollfd *fds,
|
||||
bool setup)
|
||||
static int devconsole_setup(FAR struct uart_dev_s *dev)
|
||||
{
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: devconsole_shutdown
|
||||
*
|
||||
* Description:
|
||||
* Disable the UART. This method is called when the serial
|
||||
* port is closed
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void devconsole_shutdown(struct uart_dev_s *dev)
|
||||
{
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: devconsole_attach
|
||||
*
|
||||
* Description:
|
||||
* Configure the UART to operation in interrupt driven mode. This method is
|
||||
* called when the serial port is opened. Normally, this is just after the
|
||||
* the setup() method is called, however, the serial console may operate in
|
||||
* a non-interrupt driven mode during the boot phase.
|
||||
*
|
||||
* RX and TX interrupts are not enabled when by the attach method (unless the
|
||||
* hardware supports multiple levels of interrupt enabling). The RX and TX
|
||||
* interrupts are not enabled until the txint() and rxint() methods are called.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int devconsole_attach(struct uart_dev_s *dev)
|
||||
{
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: devconsole_detach
|
||||
*
|
||||
* Description:
|
||||
* Detach UART interrupts. This method is called when the serial port is
|
||||
* closed normally just before the shutdown method is called. The exception is
|
||||
* the serial console which is never shutdown.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void devconsole_detach(FAR struct uart_dev_s *dev)
|
||||
{
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: devconsole_ioctl
|
||||
*
|
||||
* Description:
|
||||
* All ioctl calls will be routed through this method
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int devconsole_ioctl(struct file *filep, int cmd, unsigned long arg)
|
||||
{
|
||||
return -ENOTTY;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: devconsole_receive
|
||||
*
|
||||
* Description:
|
||||
* Called (usually) from the interrupt level to receive one
|
||||
* character from the UART. Error bits associated with the
|
||||
* receipt are provided in the return 'status'.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int devconsole_receive(struct uart_dev_s *dev, uint32_t *status)
|
||||
{
|
||||
*status = 0;
|
||||
return simuart_getc();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: devconsole_rxint
|
||||
*
|
||||
* Description:
|
||||
* Call to enable or disable RX interrupts
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void devconsole_rxint(struct uart_dev_s *dev, bool enable)
|
||||
{
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: devconsole_rxavailable
|
||||
*
|
||||
* Description:
|
||||
* Return true if the receive fifo is not empty
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static bool devconsole_rxavailable(struct uart_dev_s *dev)
|
||||
{
|
||||
return simuart_checkc();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: devconsole_send
|
||||
*
|
||||
* Description:
|
||||
* This method will send one byte on the UART
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void devconsole_send(struct uart_dev_s *dev, int ch)
|
||||
{
|
||||
simuart_putc(ch);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: devconsole_txint
|
||||
*
|
||||
* Description:
|
||||
* Call to enable or disable TX interrupts
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void devconsole_txint(struct uart_dev_s *dev, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
uart_xmitchars(&g_devconsole_dev);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: devconsole_txready
|
||||
*
|
||||
* Description:
|
||||
* Return true if the tranmsit fifo is not full
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static bool devconsole_txready(struct uart_dev_s *dev)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: devconsole_txempty
|
||||
*
|
||||
* Description:
|
||||
* Return true if the transmit fifo is empty
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static bool devconsole_txempty(struct uart_dev_s *dev)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -163,7 +289,20 @@ static int devconsole_poll(FAR struct file *filep, FAR struct pollfd *fds,
|
||||
|
||||
void up_devconsole(void)
|
||||
{
|
||||
register_driver("/dev/console", &devconsole_fops, 0666, NULL);
|
||||
uart_register("/dev/console", &g_devconsole_dev);
|
||||
uart_register("/dev/ttyS0", &g_devconsole_dev);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_devconloop
|
||||
****************************************************************************/
|
||||
|
||||
void up_devconloop(void)
|
||||
{
|
||||
if (simuart_checkc())
|
||||
{
|
||||
uart_recvchars(&g_devconsole_dev);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -1,7 +1,8 @@
|
||||
/****************************************************************************
|
||||
* arch/sim/src/sim/up_idle.c
|
||||
*
|
||||
* Copyright (C) 2007-2009, 2011-2012, 2014, 2016 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2009, 2011-2012, 2014, 2016, 2020 Gregory Nutt. All
|
||||
* rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -44,10 +45,6 @@
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
# include <nuttx/power/pm.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
# include <nuttx/spinlock.h>
|
||||
#endif
|
||||
@ -132,14 +129,7 @@ void up_idle(void)
|
||||
#ifdef USE_DEVCONSOLE
|
||||
/* Handle UART data availability */
|
||||
|
||||
if (g_uart_data_available)
|
||||
{
|
||||
#ifdef CONFIG_PM
|
||||
pm_activity(PM_IDLE_DOMAIN, 100); /* Report important activity to PM */
|
||||
#endif
|
||||
g_uart_data_available = 0;
|
||||
simuart_post();
|
||||
}
|
||||
up_devconloop();
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_NET_ETHERNET) && defined(CONFIG_SIM_NETDEV)
|
||||
|
@ -98,7 +98,7 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Context Switching Definitions ******************************************/
|
||||
/* Context Switching Definitions ********************************************/
|
||||
|
||||
#if defined(CONFIG_HOST_X86_64) && !defined(CONFIG_SIM_M32)
|
||||
/* Storage order: %rbx, %rsp, %rbp, %r12, %r13, %r14, %r15, %rip */
|
||||
@ -155,7 +155,7 @@
|
||||
# define JB_PC 9
|
||||
#endif
|
||||
|
||||
/* Simulated Heap Definitions **********************************************/
|
||||
/* Simulated Heap Definitions ***********************************************/
|
||||
|
||||
/* Size of the simulated heap */
|
||||
|
||||
@ -204,10 +204,6 @@ extern volatile int g_eventloop;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef USE_DEVCONSOLE
|
||||
extern volatile int g_uart_data_available;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/* These spinlocks are used in the SMP configuration in order to implement
|
||||
* up_cpu_pause(). The protocol for CPUn to pause CPUm is as follows
|
||||
@ -231,42 +227,42 @@ volatile spinlock_t g_cpu_paused[CONFIG_SMP_NCPUS] SP_SECTION;
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/* up_setjmp32.S **********************************************************/
|
||||
/* up_setjmp32.S ************************************************************/
|
||||
|
||||
int up_setjmp(xcpt_reg_t *jb);
|
||||
void up_longjmp(xcpt_reg_t *jb, int val) noreturn_function;
|
||||
|
||||
/* up_hostusleep.c ********************************************************/
|
||||
/* up_hostusleep.c **********************************************************/
|
||||
|
||||
int up_hostusleep(unsigned int usec);
|
||||
|
||||
/* up_simsmp.c ************************************************************/
|
||||
/* up_simsmp.c **************************************************************/
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
int sim_cpu0_initialize(void);
|
||||
void sim_cpu0_start(void);
|
||||
#endif
|
||||
|
||||
/* up_smpsignal.c *********************************************************/
|
||||
/* up_smpsignal.c ***********************************************************/
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
void sim_cpu_pause(int cpu, FAR volatile spinlock_t *wait,
|
||||
FAR volatile unsigned char *paused);
|
||||
#endif
|
||||
|
||||
/* up_smphook.c ***********************************************************/
|
||||
/* up_smphook.c *************************************************************/
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
void sim_smp_hook(void);
|
||||
#endif
|
||||
|
||||
/* up_tickless.c **********************************************************/
|
||||
/* up_tickless.c ************************************************************/
|
||||
|
||||
#ifdef CONFIG_SCHED_TICKLESS
|
||||
void up_timer_update(void);
|
||||
#endif
|
||||
|
||||
/* rpmsg_serialinit *******************************************************/
|
||||
/* rpmsg_serialinit *********************************************************/
|
||||
|
||||
#ifdef CONFIG_RPMSG_UART
|
||||
void rpmsg_serialinit(void);
|
||||
@ -274,35 +270,30 @@ void rpmsg_serialinit(void);
|
||||
# define rpmsg_serialinit()
|
||||
#endif
|
||||
|
||||
/* up_devconsole.c ********************************************************/
|
||||
/* up_devconsole.c **********************************************************/
|
||||
|
||||
void up_devconsole(void);
|
||||
void up_registerblockdevice(void);
|
||||
void up_devconloop(void);
|
||||
|
||||
/* up_simuart.c ***********************************************************/
|
||||
/* up_simuart.c *************************************************************/
|
||||
|
||||
void simuart_start(void);
|
||||
int simuart_putc(int ch);
|
||||
int simuart_getc(bool block);
|
||||
int simuart_getc(void);
|
||||
bool simuart_checkc(void);
|
||||
|
||||
/* up_uartwait.c **********************************************************/
|
||||
|
||||
void simuart_initialize(void);
|
||||
void simuart_post(void);
|
||||
void simuart_wait(void);
|
||||
|
||||
/* up_deviceimage.c *******************************************************/
|
||||
/* up_deviceimage.c *********************************************************/
|
||||
|
||||
char *up_deviceimage(void);
|
||||
void up_registerblockdevice(void);
|
||||
|
||||
/* up_netdev.c ************************************************************/
|
||||
/* up_netdev.c **************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET
|
||||
unsigned long up_getwalltime(void);
|
||||
#endif
|
||||
|
||||
/* up_x11framebuffer.c ****************************************************/
|
||||
/* up_x11framebuffer.c ******************************************************/
|
||||
|
||||
#ifdef CONFIG_SIM_X11FB
|
||||
int up_x11initialize(unsigned short width, unsigned short height,
|
||||
@ -315,45 +306,45 @@ int up_x11cmap(unsigned short first, unsigned short len,
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* up_touchscreen.c *******************************************************/
|
||||
/* up_touchscreen.c *********************************************************/
|
||||
|
||||
int sim_tsc_initialize(int minor);
|
||||
void sim_tsc_uninitialize(void);
|
||||
|
||||
/* up_pminitialize.c ******************************************************/
|
||||
/* up_pminitialize.c ********************************************************/
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
void up_pminitialize(void);
|
||||
#endif
|
||||
|
||||
/* up_eventloop.c *********************************************************/
|
||||
/* up_eventloop.c ***********************************************************/
|
||||
|
||||
#if defined(CONFIG_SIM_X11FB) && \
|
||||
(defined(CONFIG_SIM_TOUCHSCREEN) || defined(CONFIG_SIM_AJOYSTICK))
|
||||
void up_x11events(void);
|
||||
#endif
|
||||
|
||||
/* up_eventloop.c *********************************************************/
|
||||
/* up_eventloop.c ***********************************************************/
|
||||
|
||||
#if defined(CONFIG_SIM_X11FB) && \
|
||||
(defined(CONFIG_SIM_TOUCHSCREEN) || defined(CONFIG_SIM_AJOYSTICK))
|
||||
int up_buttonevent(int x, int y, int buttons);
|
||||
#endif
|
||||
|
||||
/* up_ajoystick.c *********************************************************/
|
||||
/* up_ajoystick.c ***********************************************************/
|
||||
|
||||
#ifdef CONFIG_SIM_AJOYSTICK
|
||||
int sim_ajoy_initialize(void);
|
||||
#endif
|
||||
|
||||
/* up_ioexpander.c ********************************************************/
|
||||
/* up_ioexpander.c **********************************************************/
|
||||
|
||||
#ifdef CONFIG_SIM_IOEXPANDER
|
||||
struct ioexpander_dev_s;
|
||||
FAR struct ioexpander_dev_s *sim_ioexpander_initialize(void);
|
||||
#endif
|
||||
|
||||
/* up_tapdev.c ************************************************************/
|
||||
/* up_tapdev.c **************************************************************/
|
||||
|
||||
#if defined(CONFIG_NET_ETHERNET) && !defined(__CYGWIN__)
|
||||
void tapdev_init(void);
|
||||
@ -369,7 +360,7 @@ void tapdev_ifdown(void);
|
||||
# define netdev_ifdown() tapdev_ifdown()
|
||||
#endif
|
||||
|
||||
/* up_wpcap.c *************************************************************/
|
||||
/* up_wpcap.c ***************************************************************/
|
||||
|
||||
#if defined(CONFIG_NET_ETHERNET) && defined(__CYGWIN__)
|
||||
void wpcap_init(void);
|
||||
@ -383,7 +374,7 @@ void wpcap_send(unsigned char *buf, unsigned int buflen);
|
||||
# define netdev_ifdown() {}
|
||||
#endif
|
||||
|
||||
/* up_netdriver.c *********************************************************/
|
||||
/* up_netdriver.c ***********************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_ETHERNET
|
||||
int netdriver_init(void);
|
||||
@ -393,12 +384,12 @@ void netdriver_loop(void);
|
||||
|
||||
#ifdef CONFIG_RPTUN
|
||||
|
||||
/* up_shmem.c *************************************************************/
|
||||
/* up_shmem.c ***************************************************************/
|
||||
|
||||
void *shmem_open(const char *name, size_t size, int master);
|
||||
void shmem_close(void *mem);
|
||||
|
||||
/* up_rptun.c *************************************************************/
|
||||
/* up_rptun.c ***************************************************************/
|
||||
|
||||
int up_rptun_init(void);
|
||||
void up_rptun_loop(void);
|
||||
|
@ -42,42 +42,7 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <termios.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Simulated console UART input buffer size */
|
||||
/* Must match the defintion in up_internal.h */
|
||||
|
||||
#define SIMUART_BUFSIZE 256
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static char g_uartbuffer[SIMUART_BUFSIZE];
|
||||
static volatile int g_uarthead;
|
||||
static volatile int g_uarttail;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
volatile int g_uart_data_available;
|
||||
|
||||
/****************************************************************************
|
||||
* NuttX Domain Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
void sched_lock(void);
|
||||
void sched_unlock(void);
|
||||
|
||||
void simuart_initialize(void);
|
||||
void simuart_post(void);
|
||||
void simuart_wait(void);
|
||||
#include <poll.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
@ -125,67 +90,6 @@ static void restoremode(void)
|
||||
tcsetattr(0, TCSANOW, &g_cooked);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: simuart_thread
|
||||
****************************************************************************/
|
||||
|
||||
static void *simuart_thread(void *arg)
|
||||
{
|
||||
unsigned char ch;
|
||||
ssize_t nread;
|
||||
int next;
|
||||
int prev;
|
||||
|
||||
/* Now loop, collecting a buffering data from stdin forever */
|
||||
|
||||
for (; ; )
|
||||
{
|
||||
/* Read one character from stdin */
|
||||
|
||||
nread = read(0, &ch, 1);
|
||||
|
||||
/* Check for failures (but don't do anything) */
|
||||
|
||||
if (nread == 1)
|
||||
{
|
||||
/* Get the index to the next slot in the UART buffer */
|
||||
|
||||
prev = g_uarthead;
|
||||
next = prev + 1;
|
||||
if (next >= SIMUART_BUFSIZE)
|
||||
{
|
||||
next = 0;
|
||||
}
|
||||
|
||||
/* Would adding this character cause an overflow? */
|
||||
|
||||
if (next != g_uarttail)
|
||||
{
|
||||
/* No.. Add the character to the UART buffer */
|
||||
|
||||
g_uartbuffer[prev] = ch;
|
||||
|
||||
/* Update the head index (BEFORE posting) */
|
||||
|
||||
g_uarthead = next;
|
||||
|
||||
/* Was the buffer previously empty? */
|
||||
|
||||
if (prev == g_uarttail)
|
||||
{
|
||||
/* Yes.. signal any (NuttX) threads waiting for serial
|
||||
* input.
|
||||
*/
|
||||
|
||||
g_uart_data_available = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: simuart_putraw
|
||||
****************************************************************************/
|
||||
@ -213,13 +117,6 @@ int simuart_putraw(int ch)
|
||||
|
||||
void simuart_start(void)
|
||||
{
|
||||
pthread_t tid;
|
||||
|
||||
/* This thread runs in the host domain */
|
||||
/* Perform the NuttX domain initialization */
|
||||
|
||||
simuart_initialize();
|
||||
|
||||
/* Put stdin into raw mode */
|
||||
|
||||
setrawmode();
|
||||
@ -227,12 +124,6 @@ void simuart_start(void)
|
||||
/* Restore the original terminal mode before exit */
|
||||
|
||||
atexit(restoremode);
|
||||
|
||||
/* Start the simulated UART thread -- all default settings; no error
|
||||
* checking.
|
||||
*/
|
||||
|
||||
pthread_create(&tid, NULL, simuart_thread, NULL);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -260,56 +151,24 @@ int simuart_putc(int ch)
|
||||
* Name: simuart_getc
|
||||
****************************************************************************/
|
||||
|
||||
int simuart_getc(bool block)
|
||||
int simuart_getc(void)
|
||||
{
|
||||
int index;
|
||||
int ret;
|
||||
int ch;
|
||||
|
||||
/* Locking the scheduler should eliminate the race conditions in the
|
||||
* unlikely case of multiple reading threads.
|
||||
*/
|
||||
|
||||
sched_lock();
|
||||
for (; ; )
|
||||
{
|
||||
/* Wait for a byte to become available */
|
||||
|
||||
if (!block && (g_uarthead == g_uarttail))
|
||||
{
|
||||
sched_unlock();
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
while (g_uarthead == g_uarttail)
|
||||
{
|
||||
simuart_wait();
|
||||
}
|
||||
|
||||
/* The UART buffer is non-empty... Take the next byte from the tail
|
||||
* of the buffer.
|
||||
*/
|
||||
|
||||
index = g_uarttail;
|
||||
ch = (int)g_uartbuffer[index];
|
||||
|
||||
/* Increment the tai index (with wrapping) */
|
||||
|
||||
if (++index >= SIMUART_BUFSIZE)
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
|
||||
g_uarttail = index;
|
||||
sched_unlock();
|
||||
return ch;
|
||||
}
|
||||
ret = read(0, &ch, 1);
|
||||
return ret < 0 ? ret : ch;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: simuart_getc
|
||||
* Name: simuart_checkc
|
||||
****************************************************************************/
|
||||
|
||||
bool simuart_checkc(void)
|
||||
{
|
||||
return g_uarthead != g_uarttail;
|
||||
struct pollfd pfd;
|
||||
|
||||
pfd.fd = 0;
|
||||
pfd.events = POLLIN;
|
||||
return poll(&pfd, 1, 0) == 1;
|
||||
}
|
||||
|
@ -1,86 +0,0 @@
|
||||
/****************************************************************************
|
||||
* arch/sim/src/sim/up_uartwait.c
|
||||
*
|
||||
* Copyright (C) 2014 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/semaphore.h>
|
||||
|
||||
#include "up_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static sem_t g_uartavail;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: simuart_initialize
|
||||
****************************************************************************/
|
||||
|
||||
void simuart_initialize(void)
|
||||
{
|
||||
/* The g_uartavail semaphore is used for signaling and, hence, should not
|
||||
* have priority inheritance enabled.
|
||||
*/
|
||||
|
||||
nxsem_init(&g_uartavail, 0, 0);
|
||||
nxsem_setprotocol(&g_uartavail, SEM_PRIO_NONE);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: simuart_post
|
||||
****************************************************************************/
|
||||
|
||||
void simuart_post(void)
|
||||
{
|
||||
nxsem_post(&g_uartavail);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: simuart_wait
|
||||
****************************************************************************/
|
||||
|
||||
void simuart_wait(void)
|
||||
{
|
||||
/* Should only fail if interrupted by a signal */
|
||||
|
||||
while (nxsem_wait(&g_uartavail) < 0);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user