From 5179fa9a643b65428947daff25da79e9fbd58679 Mon Sep 17 00:00:00 2001 From: Dave Marples Date: Thu, 13 Jun 2019 16:22:41 -0600 Subject: [PATCH] drivers/serial/serial.c: Limit the number of times that the poll semaphore is incrmented. --- configs/nucleo-l432kc/src/stm32_ina219.c | 135 +++++++++++++++++++++++ drivers/serial/serial.c | 21 +++- fs/vfs/fs_poll.c | 11 +- include/poll.h | 13 ++- 4 files changed, 173 insertions(+), 7 deletions(-) create mode 100644 configs/nucleo-l432kc/src/stm32_ina219.c diff --git a/configs/nucleo-l432kc/src/stm32_ina219.c b/configs/nucleo-l432kc/src/stm32_ina219.c new file mode 100644 index 00000000000..b9b0912a5d3 --- /dev/null +++ b/configs/nucleo-l432kc/src/stm32_ina219.c @@ -0,0 +1,135 @@ +/******************************************************************************* + * configs/nucleo-l432kc/src/stm32_ina219.c + * + * Copyright (C) 2018 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include +#include +#include + +#include +#include +#include + +#include "chip.h" +#include + +#if defined(CONFIG_I2C) && defined(CONFIG_STM32L4_I2C1) && \ + defined(CONFIG_SENSORS_INA219) + +/******************************************************************************* + * Preprocessor definitions + ******************************************************************************/ + +#if !defined(CONFIG_INA219_ADDR) +# define CONFIG_INA219_ADDR 0x40 /* A0 and A1 tied to ground */ +#endif + +#if !defined(CONFIG_INA219_SHUNTVAL) +# define CONFIG_INA219_SHUNTVAL 2000 +#endif + +/******************************************************************************* + * Private Data + ******************************************************************************/ + +/******************************************************************************* + * Public Functions + ******************************************************************************/ + +/******************************************************************************* + * Name: stm32_ina219initialize + * + * Description: + * Initialize and register the INA219 driver. + * + * Input Parameters: + * devpath - The full path to the driver to register. E.g., "/dev/ina219" + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int stm32_ina219initialize(FAR const char *devpath) +{ + FAR struct i2c_master_s *i2c; + int ret; + + sninfo("Initializing INA219\n"); + + /* Configure D4(PA5) and D5(PA6) as input floating */ + + stm32l4_configgpio(GPIO_I2C1_D4); + stm32l4_configgpio(GPIO_I2C1_D5); + + /* Get an instance of the I2C1 interface */ + + i2c = stm32l4_i2cbus_initialize(1); + if (!i2c) + { + return -ENODEV; + } + + /* Then initialize and register INA219 */ + + int config = INA219_CONFIG_PGA_X1 | + INA219_CONFIG_RANGE_16V | + INA219_CONFIG_SADC_AVG16 | + INA219_CONFIG_BADC_AVG16 ; + + ret = ina219_register(devpath, i2c, CONFIG_INA219_ADDR, + CONFIG_INA219_SHUNTVAL, config); + + if (ret < 0) + { + snerr("ERROR: ina219_register failed: %d\n", ret); + goto error; + } + + return OK; + +error: + (void)stm32l4_i2cbus_uninitialize(i2c); + return ret; +} + +#endif /* defined(CONFIG_I2C) && defined(CONFIG_STM32_I2C1) && + defined(CONFIG_SENSORS_INA219) */ diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c index 15789ebf44d..234f7252247 100644 --- a/drivers/serial/serial.c +++ b/drivers/serial/serial.c @@ -1,7 +1,8 @@ /************************************************************************************ * drivers/serial/serial.c * - * Copyright (C) 2007-2009, 2011-2013, 2016-2018 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011-2013, 2016-2019 Gregory Nutt. All rights + * reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -195,8 +196,24 @@ static void uart_pollnotify(FAR uart_dev_t *dev, pollevent_t eventset) #endif if (fds->revents != 0) { + irqstate_t flags; + int semcount; + finfo("Report events: %02x\n", fds->revents); - nxsem_post(fds->sem); + + /* Limit the number of times that the semaphore is posted. + * The critical section is needed to make the following + * operation atomic. + */ + + flags = enter_critical_section(); + nxsem_getvalue(fds->sem, &semcount); + if (semcount < 1) + { + nxsem_post(fds->sem); + } + + leave_critical_section(flags); } } } diff --git a/fs/vfs/fs_poll.c b/fs/vfs/fs_poll.c index 0e59edf53b4..a4a96fa73cd 100644 --- a/fs/vfs/fs_poll.c +++ b/fs/vfs/fs_poll.c @@ -1,7 +1,7 @@ /**************************************************************************** * fs/vfs/fs_poll.c * - * Copyright (C) 2008-2009, 2012-2018 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2009, 2012-2019 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -139,7 +139,14 @@ static inline int poll_setup(FAR struct pollfd *fds, nfds_t nfds, for (i = 0; i < nfds; i++) { - /* Setup the poll descriptor */ + /* Setup the poll descriptor + * + * REVISIT: In a multi-threaded environment, one use case might be to + * share a single, array of struct pollfd in poll() calls on different + * threads. That use case is not supportable here because the non- + * standard internal fields get reset here on each call to poll() + * on each thread. + */ fds[i].sem = sem; fds[i].revents = 0; diff --git a/include/poll.h b/include/poll.h index ed97a8f23b1..d5325c321d0 100644 --- a/include/poll.h +++ b/include/poll.h @@ -1,7 +1,7 @@ /**************************************************************************** * include/poll.h * - * Copyright (C) 2008-2009, 2018 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2009, 2018-2019 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -110,7 +110,14 @@ typedef unsigned int nfds_t; typedef uint8_t pollevent_t; -/* This is the Nuttx variant of the standard pollfd structure. */ +/* This is the Nuttx variant of the standard pollfd structure. The poll() + * interfaces receive a variable length array of such structures. + * + * REVISIT: In a multi-threaded environment, one use case might be to share + * a single, array of struct pollfd in poll calls on different threads. + * That use case is not supportable with this variant due way in which the + * non-standard internal fields are used in the implementation of poll(). + */ struct pollfd { @@ -120,7 +127,7 @@ struct pollfd pollevent_t events; /* The input event flags */ pollevent_t revents; /* The output event flags */ - /* Non-standard fields used internally by NuttX */ + /* Non-standard fields used internally by NuttX. */ FAR void *ptr; /* The psock or file being polled */ FAR sem_t *sem; /* Pointer to semaphore used to post output event */