diff --git a/arch/arm/src/stm32/chip/stm32_exti.h b/arch/arm/src/stm32/chip/stm32_exti.h index 791bed1f174..e18b60cf71b 100644 --- a/arch/arm/src/stm32/chip/stm32_exti.h +++ b/arch/arm/src/stm32/chip/stm32_exti.h @@ -188,9 +188,9 @@ /* Pending register */ -#define EXTI_IMR_BIT(n) STM32_EXTI_BIT(n) /* 1=Selected trigger request occurred */ -#define EXTI_IMR_SHIFT (0) /* Bits 0-X: Pending bit for all lines */ -#define EXTI_IMR_MASK STM32_EXTI_MASK +#define EXTI_PR_BIT(n) STM32_EXTI_BIT(n) /* 1=Selected trigger request occurred */ +#define EXTI_PR_SHIFT (0) /* Bits 0-X: Pending bit for all lines */ +#define EXTI_PR_MASK STM32_EXTI_MASK /* Compatibility Definitions ********************************************************/ diff --git a/arch/arm/src/stm32f7/Kconfig b/arch/arm/src/stm32f7/Kconfig index d8eabdcd4bd..2c21fadf610 100644 --- a/arch/arm/src/stm32f7/Kconfig +++ b/arch/arm/src/stm32f7/Kconfig @@ -1634,7 +1634,7 @@ config SERIAL_DISABLE_REORDERING config STM32F7_FLOWCONTROL_BROKEN bool "Use Software UART RTS flow control" - depends on STM32F7_USART + depends on STM32F7_USART && SERIAL_IFLOWCONTROL_WATERMARKS default n ---help--- Enable UART RTS flow control using Software. Because STM diff --git a/arch/arm/src/stm32f7/chip/stm32_exti.h b/arch/arm/src/stm32f7/chip/stm32_exti.h index 288f51b228c..8663d2f08e7 100644 --- a/arch/arm/src/stm32f7/chip/stm32_exti.h +++ b/arch/arm/src/stm32f7/chip/stm32_exti.h @@ -125,9 +125,9 @@ /* Pending register */ -#define EXTI_IMR_BIT(n) STM32_EXTI_BIT(n) /* 1=Selected trigger request occurred */ -#define EXTI_IMR_SHIFT (0) /* Bits 0-X: Pending bit for all lines */ -#define EXTI_IMR_MASK STM32_EXTI_MASK +#define EXTI_PR_BIT(n) STM32_EXTI_BIT(n) /* 1=Selected trigger request occurred */ +#define EXTI_PR_SHIFT (0) /* Bits 0-X: Pending bit for all lines */ +#define EXTI_PR_MASK STM32_EXTI_MASK #endif /* CONFIG_STM32F7_STM32F74XX || CONFIG_STM32F7_STM32F75XX || CONFIG_STM32F7_STM32F76XX || CONFIG_STM32F7_STM32F77XX */ #endif /* __ARCH_ARM_SRC_STM32F7_CHIP_STM32_EXTI_H */ diff --git a/arch/arm/src/stm32f7/stm32_serial.c b/arch/arm/src/stm32f7/stm32_serial.c index ec97ec7096c..5c2b8b74bcc 100644 --- a/arch/arm/src/stm32f7/stm32_serial.c +++ b/arch/arm/src/stm32f7/stm32_serial.c @@ -220,43 +220,56 @@ /* Warnings for potentially unsafe configuration combinations. */ +#if defined(CONFIG_STM32F7_FLOWCONTROL_BROKEN) && \ + !defined(CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS) +# error "CONFIG_STM32F7_FLOWCONTROL_BROKEN requires \ + CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS to be enabled." +#endif + +#ifndef CONFIG_STM32F7_FLOWCONTROL_BROKEN /* Combination of RXDMA + IFLOWCONTROL does not work as one might expect. * Since RXDMA uses circular DMA-buffer, DMA will always keep reading new * data from USART peripheral even if DMA buffer underruns. Thus this * combination only does following: RTS is asserted on USART setup and * deasserted on shutdown and does not perform actual RTS flow-control. + * + * With SW flow-control, RTS is asserted before UART receive buffer fully + * fills, thus preventing data loss if application is slow to process data + * from serial device node. However, if RxDMA interrupt is blocked for too + * long, data loss is still possible as SW flow-control would also be + * blocked. */ -#if defined(CONFIG_USART1_RXDMA) && defined(CONFIG_USART1_IFLOWCONTROL) -# warning "RXDMA and IFLOWCONTROL both enabled for USART1. \ - This combination can lead to data loss." -#endif +# if defined(CONFIG_USART1_RXDMA) && defined(CONFIG_USART1_IFLOWCONTROL) +# warning "RXDMA and IFLOWCONTROL both enabled for USART1. \ + This combination can lead to data loss." +# endif -#if defined(CONFIG_USART2_RXDMA) && defined(CONFIG_USART2_IFLOWCONTROL) -# warning "RXDMA and IFLOWCONTROL both enabled for USART2. \ - This combination can lead to data loss." -#endif +# if defined(CONFIG_USART2_RXDMA) && defined(CONFIG_USART2_IFLOWCONTROL) +# warning "RXDMA and IFLOWCONTROL both enabled for USART2. \ + This combination can lead to data loss." +# endif -#if defined(CONFIG_USART3_RXDMA) && defined(CONFIG_USART3_IFLOWCONTROL) -# warning "RXDMA and IFLOWCONTROL both enabled for USART3. \ - This combination can lead to data loss." -#endif +# if defined(CONFIG_USART3_RXDMA) && defined(CONFIG_USART3_IFLOWCONTROL) +# warning "RXDMA and IFLOWCONTROL both enabled for USART3. \ + This combination can lead to data loss." +# endif -#if defined(CONFIG_USART6_RXDMA) && defined(CONFIG_USART6_IFLOWCONTROL) -# warning "RXDMA and IFLOWCONTROL both enabled for USART6. \ - This combination can lead to data loss." -#endif +# if defined(CONFIG_USART6_RXDMA) && defined(CONFIG_USART6_IFLOWCONTROL) +# warning "RXDMA and IFLOWCONTROL both enabled for USART6. \ + This combination can lead to data loss." +# endif -#if defined(CONFIG_UART7_RXDMA) && defined(CONFIG_UART7_IFLOWCONTROL) -# warning "RXDMA and IFLOWCONTROL both enabled for UART7. \ - This combination can lead to data loss." -#endif - -#if defined(CONFIG_UART8_RXDMA) && defined(CONFIG_UART8_IFLOWCONTROL) -# warning "RXDMA and IFLOWCONTROL both enabled for UART8. \ - This combination can lead to data loss." -#endif +# if defined(CONFIG_UART7_RXDMA) && defined(CONFIG_UART7_IFLOWCONTROL) +# warning "RXDMA and IFLOWCONTROL both enabled for UART7. \ + This combination can lead to data loss." +# endif +# if defined(CONFIG_UART8_RXDMA) && defined(CONFIG_UART8_IFLOWCONTROL) +# warning "RXDMA and IFLOWCONTROL both enabled for UART8. \ + This combination can lead to data loss." +# endif +#endif /* CONFIG_STM32F7_FLOWCONTROL_BROKEN */ /**************************************************************************** * Private Types @@ -2211,6 +2224,22 @@ static bool up_rxflowcontrol(struct uart_dev_s *dev, /* Assert/de-assert nRTS set it high resume/stop sending */ stm32_gpiowrite(priv->rts_gpio, upper); + + if (upper) + { + /* With heavy Rx traffic, RXNE might be set and data pending. + * Returning 'true' in such case would cause RXNE left unhandled + * and causing interrupt storm. Sending end might be also be slow + * to react on nRTS, and returning 'true' here would prevent + * processing that data. + * + * Therefore, return 'false' so input data is still being processed + * until sending end reacts on nRTS signal and stops sending more. + */ + + return false; + } + return upper; } diff --git a/arch/arm/src/stm32l4/chip/stm32l4_exti.h b/arch/arm/src/stm32l4/chip/stm32l4_exti.h index 1fb1628a7a9..f9f087a051e 100644 --- a/arch/arm/src/stm32l4/chip/stm32l4_exti.h +++ b/arch/arm/src/stm32l4/chip/stm32l4_exti.h @@ -167,13 +167,13 @@ /* Pending register */ -#define EXTI_IMR1_BIT(n) STM32L4_EXTI1_BIT(n) /* 1=Selected trigger request occurred */ -#define EXTI_IMR1_SHIFT (0) /* Bits 0-X: Pending bit for all lines */ -#define EXTI_IMR1_MASK STM32L4_EXTI1_MASK +#define EXTI_PR1_BIT(n) STM32L4_EXTI1_BIT(n) /* 1=Selected trigger request occurred */ +#define EXTI_PR1_SHIFT (0) /* Bits 0-X: Pending bit for all lines */ +#define EXTI_PR1_MASK STM32L4_EXTI1_MASK -#define EXTI_IMR2_BIT(n) STM32L4_EXTI2_BIT(n) /* 1=Selected trigger request occurred */ -#define EXTI_IMR2_SHIFT (0) /* Bits 0-X: Pending bit for all lines */ -#define EXTI_IMR2_MASK STM32L4_EXTI2_MASK +#define EXTI_PR2_BIT(n) STM32L4_EXTI2_BIT(n) /* 1=Selected trigger request occurred */ +#define EXTI_PR2_SHIFT (0) /* Bits 0-X: Pending bit for all lines */ +#define EXTI_PR2_MASK STM32L4_EXTI2_MASK #endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_EXTI_H */ diff --git a/include/nuttx/net/arp.h b/include/nuttx/net/arp.h index 4a33994a1b7..477240a5d68 100644 --- a/include/nuttx/net/arp.h +++ b/include/nuttx/net/arp.h @@ -69,6 +69,7 @@ */ #define ARPHRD_ETHER 1 /* Ethernet */ +#define ARPHRD_IEEE80211    801 /* IEEE 802.11 */ #define ARPHRD_IEEE802154 804 /* IEEE 802.15.4 */ /**************************************************************************** diff --git a/include/nuttx/wireless/wireless.h b/include/nuttx/wireless/wireless.h index 74908e7350b..bd9f93ba8f7 100644 --- a/include/nuttx/wireless/wireless.h +++ b/include/nuttx/wireless/wireless.h @@ -213,11 +213,26 @@ #define IW_MODE_SECOND 5 /* Secondary master/repeater (backup) */ #define IW_MODE_MONITOR 6 /* Passive monitor (listen only) */ #define IW_MODE_MESH 7 /* Mesh (IEEE 802.11s) network */ +#define IW_MODE_NFLAGS 8 /* Frequency flags */ -#define IW_FREQ_AUTO 0x00 /* Let the driver decides */ -#define IW_FREQ_FIXED 0x01 /* Force a specific value */ +#define IW_FREQ_AUTO 0 /* Let the driver decides */ +#define IW_FREQ_FIXED 1 /* Force a specific value */ +#define IW_FREQ_NFLAGS 2 + +#define IW_MAX_FREQUENCIES 32 /* Max. frequencies in struct iw_range */ + +/* Transmit Power flags available */ + +#define IW_TXPOW_DBM 0 /* Value is in dBm */ +#define IW_TXPOW_MWATT 1 /* Value is in mW */ +#define IW_TXPOW_RELATIVE 2 /* Value is in arbitrary units */ +#define IW_TXPOW_NFLAGS 3 + +/* Scan-related */ + +#define IW_SCAN_MAX_DATA 4096 /* Maximum size of returned data */ /************************************************************************************ * Public Types @@ -312,16 +327,33 @@ union iwreq_data struct iw_param param; /* Other small parameters */ struct iw_point data; /* Other large parameters */ }; - + /* This is the structure used to exchange data in wireless IOCTLs. This structure * is the same as 'struct ifreq', but defined for use with wireless IOCTLs. */ struct iwreq { - char ifrn_name[IFNAMSIZ]; /* Interface name, e.g. "eth0" */ + char ifr_name[IFNAMSIZ]; /* Interface name, e.g. "eth0" */ union iwreq_data u; /* Data payload */ }; +/* Range of parameters (currently only frequencies) */ + +struct iw_range +{ + uint8_t num_frequency; /* Number of frequencies in the freq[] list */ + struct iw_freq freq[IW_MAX_FREQUENCIES]; +}; + +/* A Wireless Event. */ + +struct iw_event +{ + uint16_t len; /* Real length of ata */ + uint16_t cmd; /* Wireless IOCTL command*/ + union iwreq_data u; /* Fixed IOCTL payload */ +}; + #endif /* CONFIG_DRIVERS_WIRELESS */ #endif /* __INCLUDE_NUTTX_WIRELESS_H */ diff --git a/libxx/Makefile b/libxx/Makefile index 766bd5d62d3..9f5ba9c9ac7 100644 --- a/libxx/Makefile +++ b/libxx/Makefile @@ -50,13 +50,19 @@ endif ifeq (,$(findstring y,$(CONFIG_UCLIBCXX) $(CONFIG_LIBCXX))) CXXSRCS += libxx_delete.cxx libxx_deletea.cxx libxx_new.cxx libxx_newa.cxx -CXXSRCS += libxx_stdthrow.cxx libxx_cxa_guard.cxx +CXXSRCS += libxx_stdthrow.cxx else ifeq (,$(findstring y,$(CONFIG_UCLIBCXX_EXCEPTION) $(CONFIG_LIBCXX_EXCEPTION))) CXXSRCS += libxx_stdthrow.cxx endif endif +# uClibc++ doesn't need this file + +ifneq ($(CONFIG_UCLIBCXX),y) +CXXSRCS += libxx_cxa_guard.cxx +endif + # Paths DEPPATH = --dep-path . diff --git a/sched/pthread/pthread.h b/sched/pthread/pthread.h index b4e87d95339..69e08e1445a 100644 --- a/sched/pthread/pthread.h +++ b/sched/pthread/pthread.h @@ -121,6 +121,14 @@ void pthread_mutex_inconsistent(FAR struct pthread_tcb_s *tcb); # define pthread_mutex_give(m) pthread_givesemaphore(&(m)->sem) #endif +#ifdef CONFIG_CANCELLATION_POINTS +uint16_t pthread_disable_cancel(void); +void pthread_enable_cancel(uint16_t oldstate); +#else +# define pthread_disable_cancel() (0) +# define pthread_enable_cancel(s) UNUSED(s) +#endif + #ifdef CONFIG_PTHREAD_MUTEX_TYPES int pthread_mutexattr_verifytype(int type); #endif diff --git a/sched/pthread/pthread_condtimedwait.c b/sched/pthread/pthread_condtimedwait.c index 4ed8c5aed6e..22ce470770a 100644 --- a/sched/pthread/pthread_condtimedwait.c +++ b/sched/pthread/pthread_condtimedwait.c @@ -167,9 +167,10 @@ int pthread_cond_timedwait(FAR pthread_cond_t *cond, FAR pthread_mutex_t *mutex, FAR const struct timespec *abstime) { FAR struct tcb_s *rtcb = this_task(); + irqstate_t flags; + uint16_t oldstate; int ticks; int mypid = (int)getpid(); - irqstate_t flags; int ret = OK; int status; @@ -316,7 +317,11 @@ int pthread_cond_timedwait(FAR pthread_cond_t *cond, FAR pthread_mutex_t *mutex, /* Reacquire the mutex (retaining the ret). */ sinfo("Re-locking...\n"); + + oldstate = pthread_disable_cancel(); status = pthread_mutex_take(mutex, false); + pthread_enable_cancel(oldstate); + if (status == OK) { mutex->pid = mypid; diff --git a/sched/pthread/pthread_condwait.c b/sched/pthread/pthread_condwait.c index 9bcba234a5f..91138215fa3 100644 --- a/sched/pthread/pthread_condwait.c +++ b/sched/pthread/pthread_condwait.c @@ -95,6 +95,8 @@ int pthread_cond_wait(FAR pthread_cond_t *cond, FAR pthread_mutex_t *mutex) } else { + uint16_t oldstate; + /* Give up the mutex */ sinfo("Give up mutex / take cond\n"); @@ -117,12 +119,17 @@ int pthread_cond_wait(FAR pthread_cond_t *cond, FAR pthread_mutex_t *mutex) /* Reacquire the mutex. * - * REVISIT: When cancellation points are enabled, we will almost - * certainly hold the mutex when the pthread is canceled. + * When cancellation points are enabled, we need to + * hold the mutex when the pthread is canceled and + * cleanup handlers, if any, are entered. */ sinfo("Reacquire mutex...\n"); + + oldstate = pthread_disable_cancel(); status = pthread_mutex_take(mutex, false); + pthread_enable_cancel(oldstate); + if (ret == OK) { /* Report the first failure that occurs */ diff --git a/sched/pthread/pthread_mutex.c b/sched/pthread/pthread_mutex.c index afd296407ef..45c4ffd3fa8 100644 --- a/sched/pthread/pthread_mutex.c +++ b/sched/pthread/pthread_mutex.c @@ -95,8 +95,8 @@ static void pthread_mutex_add(FAR struct pthread_mutex_s *mutex) * mutex to the list of mutexes held by this thread. * * Parameters: - * mutex - The mux to be locked - * intr - false: ignore EINTR errors when locking; true tread EINTR as + * mutex - The mutex to be locked + * intr - false: ignore EINTR errors when locking; true treat EINTR as * other errors by returning the errno value * * Return Value: @@ -126,15 +126,11 @@ int pthread_mutex_take(FAR struct pthread_mutex_s *mutex, bool intr) else { /* Take semaphore underlying the mutex. pthread_takesemaphore - * returns zero on success and a positive errno value on failue. + * returns zero on success and a positive errno value on failure. */ ret = pthread_takesemaphore(&mutex->sem, intr); - if (ret != OK) - { - ret = get_errno(); - } - else + if (ret == OK) { /* Check if the holder of the mutex has terminated without * releasing. In that case, the state of the mutex is @@ -169,8 +165,8 @@ int pthread_mutex_take(FAR struct pthread_mutex_s *mutex, bool intr) * mutex to the list of mutexes held by this thread. * * Parameters: - * mutex - The mux to be locked - * intr - false: ignore EINTR errors when locking; true tread EINTR as + * mutex - The mutex to be locked + * intr - false: ignore EINTR errors when locking; true treat EINTR as * other errors by returning the errno value * * Return Value: @@ -283,3 +279,70 @@ int pthread_mutex_give(FAR struct pthread_mutex_s *mutex) return ret; } +/**************************************************************************** + * Name: pthread_disable_cancel() and pthread_enable_cancel() + * + * Description: + * Temporarily disable cancellation and return old cancel state, which + * can later be restored. This is useful when a cancellation point + * function is called from within the OS by a non-cancellation point: + * In certain such cases, we need to defer the cancellation to prevent + * bad things from happening. + * + * Parameters: + * saved cancel flags for pthread_enable_cancel() + * + * Return Value: + * old cancel flags for pthread_disable_cancel() + * + ****************************************************************************/ + +#ifdef CONFIG_CANCELLATION_POINTS +uint16_t pthread_disable_cancel(void) +{ + FAR struct pthread_tcb_s *tcb = (FAR struct pthread_tcb_s *)this_task(); + irqstate_t flags; + uint16_t old; + + /* We need perform the following operations from within a critical section + * because it can compete with interrupt level activity. + */ + + flags = enter_critical_section(); + old = tcb->cmn.flags & (TCB_FLAG_CANCEL_PENDING | TCB_FLAG_NONCANCELABLE); + tcb->cmn.flags &= ~(TCB_FLAG_CANCEL_PENDING | TCB_FLAG_NONCANCELABLE); + leave_critical_section(flags); + return old; +} + +void pthread_enable_cancel(uint16_t cancelflags) +{ + FAR struct pthread_tcb_s *tcb = (FAR struct pthread_tcb_s *)this_task(); + irqstate_t flags; + + /* We need perform the following operations from within a critical section + * because it can compete with interrupt level activity. + */ + + flags = enter_critical_section(); + tcb->cmn.flags |= cancelflags; + + /* What should we do if there is a pending cancellation? + * + * If the thread is executing with deferred cancellation, we need do + * nothing more; the cancellation cannot occur until the next + * cancellation point. + * + * However, if the thread is executing in asynchronous cancellation mode, + * then we need to terminate now by simply calling pthread_exit(). + */ + + if ((tcb->cmn.flags & TCB_FLAG_CANCEL_DEFERRED) == 0 && + (tcb->cmn.flags & TCB_FLAG_CANCEL_PENDING) != 0) + { + pthread_exit(NULL); + } + + leave_critical_section(flags); +} +#endif /* CONFIG_CANCELLATION_POINTS */