mirror of
https://github.com/apache/nuttx.git
synced 2025-12-06 17:23:49 +08:00
Compare commits
7 Commits
df3fe0e16f
...
ba05c7f133
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ba05c7f133 | ||
|
|
817e4ee354 | ||
|
|
bc561c677a | ||
|
|
df17524e55 | ||
|
|
7421846c94 | ||
|
|
a232815648 | ||
|
|
02db473e97 |
@@ -155,7 +155,15 @@ IOCTL Commands
|
||||
The full list of ``ioctl()`` commands can be found in
|
||||
``include/nuttx/eeprom/eeprom.h``.
|
||||
|
||||
- ``EEPIOC_GEOMETRY``: Get the EEPROM geometry
|
||||
- ``EEPIOC_GEOMETRY``
|
||||
*Argument:* ``struct eeprom_geometry_s *``
|
||||
|
||||
Get the EEPROM geometry
|
||||
|
||||
- ``EEPIOC_SETSPEED``
|
||||
*Argument:* ``uint32_t``
|
||||
|
||||
Set the SPI/I2C bus frequency
|
||||
|
||||
File Systems
|
||||
============
|
||||
|
||||
@@ -24,12 +24,45 @@ if SPI_EE_25XX
|
||||
config EE25XX_SPIMODE
|
||||
int "SPI mode (0-3)"
|
||||
default 0
|
||||
depends on SPI_EE_25XX
|
||||
|
||||
config EE25XX_FREQUENCY
|
||||
int "SPI EEPROM SCK frequency"
|
||||
default 10000000
|
||||
depends on SPI_EE_25XX
|
||||
---help---
|
||||
Default SPI bus frequency, it can be overwritten at runtime using the
|
||||
EEPIOC_SETSPEED ioctl. See eeprom/eeprom.h.
|
||||
|
||||
config EE25XX_START_DELAY
|
||||
int "SPI start delay"
|
||||
depends on SPI_DELAY_CONTROL
|
||||
range 0 1000000
|
||||
default 5000
|
||||
---help---
|
||||
The delay between CS active and first CLK. In ns.
|
||||
|
||||
config EE25XX_STOP_DELAY
|
||||
int "SPI stop delay"
|
||||
depends on SPI_DELAY_CONTROL
|
||||
range 0 1000000
|
||||
default 5000
|
||||
---help---
|
||||
The delay between last CLK and CS inactive. In ns.
|
||||
|
||||
config EE25XX_CS_DELAY
|
||||
int "SPI CS delay"
|
||||
depends on SPI_DELAY_CONTROL
|
||||
range 0 1000000
|
||||
default 5000
|
||||
---help---
|
||||
The delay between CS inactive and CS active again. In ns.
|
||||
|
||||
config EE25XX_IFDELAY
|
||||
int "SPI interface delay"
|
||||
depends on SPI_DELAY_CONTROL
|
||||
range 0 1000000
|
||||
default 5000
|
||||
---help---
|
||||
The delay between frames. In ns.
|
||||
|
||||
endif # SPI_EE_25XX
|
||||
|
||||
@@ -46,12 +79,13 @@ if I2C_EE_24XX
|
||||
config EE24XX_FREQUENCY
|
||||
int "I2C EEPROM frequency (100000 or 400000)"
|
||||
default 100000
|
||||
depends on I2C_EE_24XX
|
||||
---help---
|
||||
Default I2C bus frequency, it can be overwritten at runtime using the
|
||||
EEPIOC_SETSPEED ioctl. See eeprom/eeprom.h.
|
||||
|
||||
config AT24CS_UUID
|
||||
bool "Device driver support for Atmel AT24CSxx UUID"
|
||||
default n
|
||||
depends on I2C_EE_24XX
|
||||
---help---
|
||||
The Atmel AT24CSxx family have a 128-bit UUID which appears as
|
||||
another I2C slave whose address is offset from the EEPROM by +8.
|
||||
|
||||
@@ -96,10 +96,6 @@
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_EE24XX_FREQUENCY
|
||||
# define CONFIG_EE24XX_FREQUENCY 100000
|
||||
#endif
|
||||
|
||||
#define UUID_SIZE 16
|
||||
|
||||
/****************************************************************************
|
||||
@@ -124,23 +120,23 @@ struct ee24xx_dev_s
|
||||
{
|
||||
/* Bus management */
|
||||
|
||||
FAR struct i2c_master_s *i2c; /* I2C device where the EEPROM is attached */
|
||||
uint32_t freq; /* I2C bus speed */
|
||||
uint8_t addr; /* 7-bit unshifted I2C device address */
|
||||
FAR struct i2c_master_s *i2c; /* I2C device where the EEPROM is attached */
|
||||
uint32_t freq; /* I2C bus speed */
|
||||
uint8_t addr; /* 7-bit unshifted I2C device address */
|
||||
|
||||
/* Driver management */
|
||||
|
||||
mutex_t lock; /* file write access serialization */
|
||||
uint8_t refs; /* Nr of times the device has been opened */
|
||||
bool readonly; /* Flags */
|
||||
mutex_t lock; /* file write access serialization */
|
||||
uint8_t refs; /* Nr of times the device has been opened */
|
||||
bool readonly; /* Flags */
|
||||
|
||||
/* Expanded from geometry */
|
||||
|
||||
uint32_t size; /* total bytes in device */
|
||||
uint16_t pgsize; /* write block size, in bytes */
|
||||
uint16_t addrlen; /* number of bytes in data addresses */
|
||||
uint16_t haddrbits; /* Number of bits in high address part */
|
||||
uint16_t haddrshift; /* bit-shift of high address part */
|
||||
uint32_t size; /* total bytes in device */
|
||||
uint16_t pgsize; /* write block size, in bytes */
|
||||
uint16_t addrlen; /* number of bytes in data addresses */
|
||||
uint16_t haddrbits; /* Number of bits in high address part */
|
||||
uint16_t haddrshift; /* bit-shift of high address part */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
@@ -807,6 +803,17 @@ static int ee24xx_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
}
|
||||
break;
|
||||
|
||||
case EEPIOC_SETSPEED:
|
||||
{
|
||||
ret = nxmutex_lock(&eedev->lock);
|
||||
if (ret == OK)
|
||||
{
|
||||
eedev->freq = (uint32_t)arg;
|
||||
nxmutex_unlock(&eedev->lock);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -ENOTTY;
|
||||
}
|
||||
|
||||
@@ -120,10 +120,6 @@
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_EE25XX_SPIMODE
|
||||
# define CONFIG_EE25XX_SPIMODE 0
|
||||
#endif
|
||||
|
||||
/* EEPROM commands
|
||||
* High bit of low nibble used for A8 in 25xx040/at25040 products
|
||||
*/
|
||||
@@ -176,15 +172,18 @@ struct ee25xx_geom_s
|
||||
|
||||
struct ee25xx_dev_s
|
||||
{
|
||||
struct spi_dev_s *spi; /* SPI device where the EEPROM is attached */
|
||||
uint16_t devid; /* SPI device ID to manage CS lines in board */
|
||||
uint32_t size; /* in bytes, expanded from geometry */
|
||||
uint16_t pgsize; /* write block size, in bytes, expanded from geometry */
|
||||
uint32_t secsize; /* write sector size, in bytes, expanded from geometry */
|
||||
uint16_t addrlen; /* number of BITS in data addresses */
|
||||
mutex_t lock; /* file access serialization */
|
||||
uint8_t refs; /* The number of times the device has been opened */
|
||||
uint8_t readonly; /* Flags */
|
||||
FAR struct spi_dev_s *spi; /* SPI device where the EEPROM is attached */
|
||||
uint16_t devid; /* SPI device ID to manage CS lines in board */
|
||||
uint32_t freq; /* SPI bus frequency in Hz */
|
||||
|
||||
uint32_t size; /* in bytes, expanded from geometry */
|
||||
uint16_t pgsize; /* write block size, in bytes, expanded from geometry */
|
||||
uint32_t secsize; /* write sector size, in bytes, expanded from geometry */
|
||||
uint16_t addrlen; /* number of BITS in data addresses */
|
||||
|
||||
mutex_t lock; /* file access serialization */
|
||||
uint8_t refs; /* The number of times the device has been opened */
|
||||
uint8_t readonly; /* Flags */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
@@ -297,9 +296,16 @@ static const struct file_operations g_ee25xx_fops =
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ee25xx_lock
|
||||
*
|
||||
* Description:
|
||||
* Lock the SPI bus associated with the driver, set its mode and frequency
|
||||
*
|
||||
* Input Parameters
|
||||
* priv - Device structure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void ee25xx_lock(FAR struct spi_dev_s *dev)
|
||||
static void ee25xx_lock(FAR struct ee25xx_dev_s *priv)
|
||||
{
|
||||
/* On SPI buses where there are multiple devices, it will be necessary to
|
||||
* lock SPI to have exclusive access to the buses for a sequence of
|
||||
@@ -310,7 +316,7 @@ static void ee25xx_lock(FAR struct spi_dev_s *dev)
|
||||
* bus is unlocked.
|
||||
*/
|
||||
|
||||
SPI_LOCK(dev, true);
|
||||
SPI_LOCK(priv->spi, true);
|
||||
|
||||
/* After locking the SPI bus, the we also need call the setfrequency,
|
||||
* setbits, and setmode methods to make sure that the SPI is properly
|
||||
@@ -318,19 +324,31 @@ static void ee25xx_lock(FAR struct spi_dev_s *dev)
|
||||
* have been left in an incompatible state.
|
||||
*/
|
||||
|
||||
SPI_SETMODE(dev, CONFIG_EE25XX_SPIMODE);
|
||||
SPI_SETBITS(dev, 8);
|
||||
SPI_HWFEATURES(dev, 0);
|
||||
SPI_SETFREQUENCY(dev, CONFIG_EE25XX_FREQUENCY);
|
||||
SPI_SETMODE(priv->spi, CONFIG_EE25XX_SPIMODE);
|
||||
SPI_SETBITS(priv->spi, 8);
|
||||
SPI_HWFEATURES(priv->spi, 0);
|
||||
SPI_SETFREQUENCY(priv->spi, priv->freq);
|
||||
#ifdef CONFIG_SPI_DELAY_CONTROL
|
||||
SPI_SETDELAY(priv->spi, CONFIG_EE25XX_START_DELAY,
|
||||
CONFIG_EE25XX_STOP_DELAY, CONFIG_EE25XX_CS_DELAY,
|
||||
CONFIG_EE25XX_IFDELAY);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ee25xx_unlock
|
||||
*
|
||||
* Description:
|
||||
* Unlock the SPI bus associated with the driver
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - Device structure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void ee25xx_unlock(FAR struct spi_dev_s *dev)
|
||||
static inline void ee25xx_unlock(FAR struct ee25xx_dev_s *priv)
|
||||
{
|
||||
SPI_LOCK(dev, false);
|
||||
SPI_LOCK(priv->spi, false);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -390,7 +408,7 @@ static void ee25xx_waitwritecomplete(struct ee25xx_dev_s *priv)
|
||||
{
|
||||
/* Select this FLASH part */
|
||||
|
||||
ee25xx_lock(priv->spi);
|
||||
ee25xx_lock(priv);
|
||||
SPI_SELECT(priv->spi, SPIDEV_EEPROM(priv->devid), true);
|
||||
|
||||
/* Send "Read Status Register (RDSR)" command */
|
||||
@@ -406,7 +424,7 @@ static void ee25xx_waitwritecomplete(struct ee25xx_dev_s *priv)
|
||||
/* Deselect the FLASH */
|
||||
|
||||
SPI_SELECT(priv->spi, SPIDEV_EEPROM(priv->devid), false);
|
||||
ee25xx_unlock(priv->spi);
|
||||
ee25xx_unlock(priv);
|
||||
|
||||
/* Given that writing could take up to a few milliseconds,
|
||||
* the following short delay in the "busy" case will allow
|
||||
@@ -432,13 +450,13 @@ static void ee25xx_waitwritecomplete(struct ee25xx_dev_s *priv)
|
||||
|
||||
static void ee25xx_writeenable(FAR struct ee25xx_dev_s *eedev, int enable)
|
||||
{
|
||||
ee25xx_lock(eedev->spi);
|
||||
ee25xx_lock(eedev);
|
||||
SPI_SELECT(eedev->spi, SPIDEV_EEPROM(eedev->devid), true);
|
||||
|
||||
SPI_SEND(eedev->spi, enable ? EE25XX_CMD_WREN : EE25XX_CMD_WRDIS);
|
||||
|
||||
SPI_SELECT(eedev->spi, SPIDEV_EEPROM(eedev->devid), false);
|
||||
ee25xx_unlock(eedev->spi);
|
||||
ee25xx_unlock(eedev);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -453,14 +471,14 @@ static void ee25xx_writepage(FAR struct ee25xx_dev_s *eedev,
|
||||
FAR const char *data,
|
||||
size_t len)
|
||||
{
|
||||
ee25xx_lock(eedev->spi);
|
||||
ee25xx_lock(eedev);
|
||||
SPI_SELECT(eedev->spi, SPIDEV_EEPROM(eedev->devid), true);
|
||||
|
||||
ee25xx_sendcmd(eedev->spi, EE25XX_CMD_WRITE, eedev->addrlen, devaddr);
|
||||
SPI_SNDBLOCK(eedev->spi, data, len);
|
||||
|
||||
SPI_SELECT(eedev->spi, SPIDEV_EEPROM(eedev->devid), false);
|
||||
ee25xx_unlock(eedev->spi);
|
||||
ee25xx_unlock(eedev);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -645,7 +663,7 @@ static ssize_t ee25xx_read(FAR struct file *filep, FAR char *buffer,
|
||||
len = eedev->size - filep->f_pos;
|
||||
}
|
||||
|
||||
ee25xx_lock(eedev->spi);
|
||||
ee25xx_lock(eedev);
|
||||
SPI_SELECT(eedev->spi, SPIDEV_EEPROM(eedev->devid), true);
|
||||
|
||||
/* STM32F4Disco: There is a 25 us delay here */
|
||||
@@ -659,7 +677,7 @@ static ssize_t ee25xx_read(FAR struct file *filep, FAR char *buffer,
|
||||
/* STM32F4Disco: There is a 20 us delay here */
|
||||
|
||||
SPI_SELECT(eedev->spi, SPIDEV_EEPROM(eedev->devid), false);
|
||||
ee25xx_unlock(eedev->spi);
|
||||
ee25xx_unlock(eedev);
|
||||
|
||||
/* Update the file position */
|
||||
|
||||
@@ -803,6 +821,17 @@ static int ee25xx_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
}
|
||||
break;
|
||||
|
||||
case EEPIOC_SETSPEED:
|
||||
{
|
||||
ret = nxmutex_lock(&eedev->lock);
|
||||
if (ret == OK)
|
||||
{
|
||||
eedev->freq = (uint32_t)arg;
|
||||
nxmutex_unlock(&eedev->lock);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -ENOTTY;
|
||||
}
|
||||
@@ -858,6 +887,7 @@ int ee25xx_initialize(FAR struct spi_dev_s *dev, uint16_t spi_devid,
|
||||
|
||||
eedev->spi = dev;
|
||||
eedev->devid = spi_devid;
|
||||
eedev->freq = CONFIG_EE25XX_FREQUENCY;
|
||||
eedev->size = 128 << g_ee25xx_devices[devtype].bytes;
|
||||
eedev->pgsize = 8 << g_ee25xx_devices[devtype].pagesize;
|
||||
eedev->secsize = eedev->pgsize << g_ee25xx_devices[devtype].secsize;
|
||||
|
||||
@@ -149,7 +149,7 @@ static int signalfd_file_close(FAR struct file *filep)
|
||||
|
||||
for (signo = MIN_SIGNO; signo <= MAX_SIGNO; signo++)
|
||||
{
|
||||
if (nxsig_ismember(&dev->sigmask, signo))
|
||||
if (nxsig_ismember(&dev->sigmask, signo) == 1)
|
||||
{
|
||||
signal(signo, SIG_DFL);
|
||||
}
|
||||
@@ -379,7 +379,7 @@ int signalfd(int fd, FAR const sigset_t *mask, int flags)
|
||||
dev = filep->f_priv;
|
||||
for (signo = MIN_SIGNO; signo <= MAX_SIGNO; signo++)
|
||||
{
|
||||
if (nxsig_ismember(&dev->sigmask, signo))
|
||||
if (nxsig_ismember(&dev->sigmask, signo) == 1)
|
||||
{
|
||||
signal(signo, SIG_DFL);
|
||||
}
|
||||
@@ -394,7 +394,7 @@ int signalfd(int fd, FAR const sigset_t *mask, int flags)
|
||||
act.sa_user = dev;
|
||||
for (signo = MIN_SIGNO; signo <= MAX_SIGNO; signo++)
|
||||
{
|
||||
if (nxsig_ismember(&dev->sigmask, signo))
|
||||
if (nxsig_ismember(&dev->sigmask, signo) == 1)
|
||||
{
|
||||
nxsig_action(signo, &act, NULL, false);
|
||||
}
|
||||
|
||||
@@ -47,13 +47,20 @@
|
||||
/* EEPROM IOCTL Commands ************************************************************/
|
||||
|
||||
#define EEPIOC_GEOMETRY _EEPIOC(0x000) /* Similar to BIOC_GEOMETRY:
|
||||
* Return the geometry of the EEPROM
|
||||
* device.
|
||||
* IN: Pointer to writable instance of
|
||||
* struct eeprom_geometry_s in which
|
||||
* to return the geometry.
|
||||
* OUT: Data return in user-provided
|
||||
* buffer. */
|
||||
* Return the geometry of the
|
||||
* EEPROM device.
|
||||
* IN: Pointer to writable
|
||||
* instance of struct
|
||||
* eeprom_geometry_s to be
|
||||
* populated
|
||||
* OUT: Data return in user-
|
||||
* provided buffer. */
|
||||
|
||||
#define EEPIOC_SETSPEED _EEPIOC(0x001) /* Overwrite the SPI/I2C bus speed
|
||||
* IN: Bus speed in Hz
|
||||
* OUT: None (ioctl return value
|
||||
* provides success/failure
|
||||
* indication). */
|
||||
|
||||
/************************************************************************************
|
||||
* Type Definitions
|
||||
|
||||
@@ -1817,6 +1817,28 @@ void nxsched_msleep(unsigned int msec);
|
||||
|
||||
void nxsched_sleep(unsigned int sec);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nxsched_nanosleep
|
||||
*
|
||||
* Description:
|
||||
* Internal nanosleep implementation used by the scheduler. This function
|
||||
* converts the requested sleep interval into system ticks, performs a
|
||||
* tick-based blocking sleep, and optionally returns the remaining time if
|
||||
* the sleep is interrupted by a signal.
|
||||
*
|
||||
* Input Parameters:
|
||||
* rqtp - Requested sleep interval (may be NULL)
|
||||
* rmtp - Remaining time returned when interrupted (optional, may be NULL)
|
||||
*
|
||||
* Returned Value:
|
||||
* Returns OK (0) on success. Returns -EINVAL for an invalid timespec
|
||||
* argument and -EAGAIN for a zero-length timeout, as required by POSIX.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int nxsched_nanosleep(FAR const struct timespec *rqtp,
|
||||
FAR struct timespec *rmtp);
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ int nxsig_ismember(FAR const sigset_t *set, int signo)
|
||||
{
|
||||
/* Check if the signal is in the set */
|
||||
|
||||
return ((set->_elem[_SIGSET_NDX(signo)] & _SIGNO2SET(signo)) != 0);
|
||||
return (set->_elem[_SIGSET_NDX(signo)] & _SIGNO2SET(signo)) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -127,7 +127,7 @@ static int group_signal_handler(pid_t pid, FAR void *arg)
|
||||
|
||||
/* Is this signal unblocked on this thread? */
|
||||
|
||||
if (!nxsig_ismember(&tcb->sigprocmask, info->siginfo->si_signo) &&
|
||||
if ((nxsig_ismember(&tcb->sigprocmask, info->siginfo->si_signo) != 1) &&
|
||||
!info->ptcb && tcb != info->atcb)
|
||||
{
|
||||
/* Yes.. remember this TCB if we have not encountered any
|
||||
|
||||
@@ -221,3 +221,76 @@ void nxsched_sleep(unsigned int sec)
|
||||
{
|
||||
nxsched_ticksleep(SEC2TICK(sec));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nxsched_nanosleep
|
||||
*
|
||||
* Description:
|
||||
* Internal nanosleep implementation used by the scheduler. This function
|
||||
* converts the requested sleep interval into system ticks, performs a
|
||||
* tick-based blocking sleep, and optionally returns the remaining time if
|
||||
* the sleep is interrupted by a signal.
|
||||
*
|
||||
* Input Parameters:
|
||||
* rqtp - Requested sleep interval (may be NULL)
|
||||
* rmtp - Remaining time returned when interrupted (optional, may be NULL)
|
||||
*
|
||||
* Returned Value:
|
||||
* Returns OK (0) on success. Returns -EINVAL for an invalid timespec
|
||||
* argument and -EAGAIN for a zero-length timeout, as required by POSIX.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int nxsched_nanosleep(FAR const struct timespec *rqtp,
|
||||
FAR struct timespec *rmtp)
|
||||
{
|
||||
clock_t ticks;
|
||||
clock_t expect = 0;
|
||||
clock_t stop;
|
||||
|
||||
/* Validate the input timespec */
|
||||
|
||||
if (rqtp && (rqtp->tv_nsec < 0 || rqtp->tv_nsec >= 1000000000))
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Zero-length sleep: Yield the processor and return -EAGAIN */
|
||||
|
||||
if (rqtp && rqtp->tv_sec == 0 && rqtp->tv_nsec == 0)
|
||||
{
|
||||
sched_yield();
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
/* Convert the requested interval to system ticks */
|
||||
|
||||
ticks = clock_time2ticks(rqtp);
|
||||
|
||||
/* Compute the absolute tick value when the sleep should expire.
|
||||
* This is used later to determine the remaining time after interruption.
|
||||
*/
|
||||
|
||||
expect = clock_delay2abstick(ticks);
|
||||
|
||||
/* Perform the blocking tick-based sleep */
|
||||
|
||||
nxsched_ticksleep(ticks);
|
||||
|
||||
/* Capture the current tick count after waking up */
|
||||
|
||||
stop = clock_systime_ticks();
|
||||
|
||||
/* If the caller provided a buffer for the remaining time, compute how much
|
||||
* of the original interval is left. If the sleep expired normally,
|
||||
* expect <= stop and the remaining time becomes zero.
|
||||
*/
|
||||
|
||||
if (rmtp)
|
||||
{
|
||||
clock_ticks2time(rmtp,
|
||||
clock_compare(stop, expect) ? expect - stop : 0);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -62,11 +62,6 @@
|
||||
|
||||
static spinlock_t g_sigaction_spin;
|
||||
|
||||
#if CONFIG_SIG_PREALLOC_ACTIONS > 0
|
||||
static sigactq_t g_sigactions[CONFIG_SIG_PREALLOC_ACTIONS];
|
||||
static bool g_sigactions_used = false;
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
@@ -86,23 +81,6 @@ static void nxsig_alloc_actionblock(void)
|
||||
irqstate_t flags;
|
||||
int i;
|
||||
|
||||
/* Use pre-allocated instances only once */
|
||||
|
||||
#if CONFIG_SIG_PREALLOC_ACTIONS > 0
|
||||
flags = spin_lock_irqsave(&g_sigaction_spin);
|
||||
if (!g_sigactions_used)
|
||||
{
|
||||
for (i = 0; i < CONFIG_SIG_PREALLOC_ACTIONS; i++)
|
||||
{
|
||||
sq_addlast((FAR sq_entry_t *)(g_sigactions + i), &g_sigfreeaction);
|
||||
}
|
||||
|
||||
g_sigactions_used = true;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&g_sigaction_spin, flags);
|
||||
#endif
|
||||
|
||||
/* Allocate a block of signal actions */
|
||||
|
||||
sigact = kmm_malloc((sizeof(sigactq_t)) * CONFIG_SIG_ALLOC_ACTIONS);
|
||||
|
||||
@@ -550,7 +550,7 @@ int nxsig_tcbdispatch(FAR struct tcb_s *stcb, siginfo_t *info,
|
||||
|
||||
if (stcb->task_state == TSTATE_WAIT_SIG &&
|
||||
(masked == 0 ||
|
||||
nxsig_ismember(&stcb->sigwaitmask, info->si_signo)))
|
||||
(nxsig_ismember(&stcb->sigwaitmask, info->si_signo) == 1)))
|
||||
{
|
||||
if (stcb->sigunbinfo != NULL)
|
||||
{
|
||||
|
||||
@@ -51,6 +51,12 @@ struct sigpool_s
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/* This is a pool of pre-allocated signal action structures buffers */
|
||||
|
||||
#if CONFIG_SIG_PREALLOC_ACTIONS > 0
|
||||
sigactq_t g_sigactions[CONFIG_SIG_PREALLOC_ACTIONS];
|
||||
#endif
|
||||
|
||||
/* The g_sigfreeaction data structure is a list of available signal
|
||||
* action structures.
|
||||
*/
|
||||
@@ -94,6 +100,22 @@ static struct sigpool_s g_sigpool;
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
#if CONFIG_SIG_PREALLOC_ACTIONS > 0
|
||||
static void nxsig_init_signalactionblock(sq_queue_t *siglist,
|
||||
FAR sigactq_t *sigact,
|
||||
uint16_t nsigs)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nsigs; i++)
|
||||
{
|
||||
sq_addlast((FAR sq_entry_t *)sigact++, siglist);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define nxsig_init_signalactionblock(x, y, z)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nxsig_init_block
|
||||
*
|
||||
@@ -168,6 +190,9 @@ void nxsig_initialize(void)
|
||||
sq_init(&g_sigpendingsignal);
|
||||
sq_init(&g_sigpendingirqsignal);
|
||||
|
||||
nxsig_init_signalactionblock(&g_sigfreeaction,
|
||||
g_sigactions,
|
||||
CONFIG_SIG_PREALLOC_ACTIONS);
|
||||
sigpool = nxsig_init_block(&g_sigpendingaction, sigpool,
|
||||
NUM_PENDING_ACTIONS, SIG_ALLOC_FIXED);
|
||||
sigpool = nxsig_init_block(&g_sigpendingirqaction, sigpool,
|
||||
|
||||
@@ -50,7 +50,7 @@ int nxsig_lowest(sigset_t *set)
|
||||
|
||||
for (signo = MIN_SIGNO; signo <= MAX_SIGNO; signo++)
|
||||
{
|
||||
if (nxsig_ismember(set, signo))
|
||||
if (nxsig_ismember(set, signo) == 1)
|
||||
{
|
||||
return signo;
|
||||
}
|
||||
|
||||
@@ -238,19 +238,25 @@ int nxsig_clockwait(int clockid, int flags,
|
||||
if ((flags & TIMER_ABSTIME) == 0)
|
||||
{
|
||||
expect = clock_delay2abstick(clock_time2ticks(rqtp));
|
||||
wd_start_abstick(&rtcb->waitdog, expect,
|
||||
nxsig_timeout, (uintptr_t)rtcb);
|
||||
}
|
||||
else if (clockid == CLOCK_REALTIME)
|
||||
{
|
||||
wd_start_realtime(&rtcb->waitdog, rqtp,
|
||||
nxsig_timeout, (uintptr_t)rtcb);
|
||||
#ifdef CONFIG_CLOCK_TIMEKEEPING
|
||||
clock_t delay;
|
||||
|
||||
clock_abstime2ticks(CLOCK_REALTIME, rqtp, &delay);
|
||||
expect = clock_delay2abstick(delay);
|
||||
#else
|
||||
clock_realtime2absticks(rqtp, &expect);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
wd_start_abstime(&rtcb->waitdog, rqtp,
|
||||
nxsig_timeout, (uintptr_t)rtcb);
|
||||
expect = clock_time2ticks(rqtp);
|
||||
}
|
||||
|
||||
wd_start_abstick(&rtcb->waitdog, expect,
|
||||
nxsig_timeout, (uintptr_t)rtcb);
|
||||
}
|
||||
|
||||
/* Remove the tcb task from the ready-to-run list. */
|
||||
@@ -270,7 +276,6 @@ int nxsig_clockwait(int clockid, int flags,
|
||||
|
||||
if (rqtp)
|
||||
{
|
||||
wd_cancel(&rtcb->waitdog);
|
||||
stop = clock_systime_ticks();
|
||||
}
|
||||
|
||||
@@ -278,7 +283,8 @@ int nxsig_clockwait(int clockid, int flags,
|
||||
|
||||
if (rqtp && rmtp && expect)
|
||||
{
|
||||
clock_ticks2time(rmtp, expect > stop ? expect - stop : 0);
|
||||
clock_ticks2time(rmtp,
|
||||
clock_compare(stop, expect) ? expect - stop : 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -413,7 +419,7 @@ int nxsig_timedwait(FAR const sigset_t *set, FAR struct siginfo *info,
|
||||
* that we were waiting for?
|
||||
*/
|
||||
|
||||
if (nxsig_ismember(set, rtcb->sigunbinfo->si_signo))
|
||||
if (nxsig_ismember(set, rtcb->sigunbinfo->si_signo) == 1)
|
||||
{
|
||||
/* Yes.. the return value is the number of the signal that
|
||||
* awakened us.
|
||||
|
||||
@@ -116,6 +116,12 @@ typedef struct sigq_s sigq_t;
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/* The g_sigactions data structure a pool of pre-allocated signal action
|
||||
* structures buffers structures.
|
||||
*/
|
||||
|
||||
extern sigactq_t g_sigactions[CONFIG_SIG_PREALLOC_ACTIONS];
|
||||
|
||||
/* The g_sigfreeaction data structure is a list of available signal action
|
||||
* structures.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user