aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679>2012-09-15 16:02:58 +0000
committerpatacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679>2012-09-15 16:02:58 +0000
commit4070ce05feae09331156c64b882bead55831f5e3 (patch)
treef5f057626312c87f0089041fbc93eeb960dba3cd
parentcfa24e37d6f153dbb5c7e2e0de6484719ea4a9b0 (diff)
downloadpx4-firmware-4070ce05feae09331156c64b882bead55831f5e3.tar.gz
px4-firmware-4070ce05feae09331156c64b882bead55831f5e3.tar.bz2
px4-firmware-4070ce05feae09331156c64b882bead55831f5e3.zip
Fix a ARMv7-M interrupt disable/optimization bug
git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@5155 7fd9a85b-ad96-42d3-883c-3090e2eb8679
-rw-r--r--NxWidgets/UnitTests/README.txt30
-rw-r--r--nuttx/TODO9
-rw-r--r--nuttx/arch/arm/include/armv7-m/irq.h86
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_spi.c26
-rw-r--r--nuttx/configs/fire-stm32v2/src/fire-internal.h7
-rw-r--r--nuttx/drivers/net/enc28j60.c4
6 files changed, 99 insertions, 63 deletions
diff --git a/NxWidgets/UnitTests/README.txt b/NxWidgets/UnitTests/README.txt
index cc01c3855..9952af012 100644
--- a/NxWidgets/UnitTests/README.txt
+++ b/NxWidgets/UnitTests/README.txt
@@ -74,7 +74,7 @@ Installing and Building the Unit Tests
writing *ONLY* the sim/nsh2 and stm321-e-eval configurations have C++ support
pre-enabled).
- c) Enable Debug Options
+ d) Enable Debug Options
If you are running on a simulated target, then you might also want to
enable debug symbols:
@@ -84,12 +84,12 @@ Installing and Building the Unit Tests
Then you can run the simulation using GDB or DDD which is a very powerful
debugging environment!
- d) Special configuration requirements for the nxwm unit test:
+ e) Special configuration requirements for the nxwm unit test:
CONFIG_NXCONSOLE=y
CONFIG_NX_MULTIUSER=y
- e) Other nuttx/.config changes -- NSH configurations only.
+ f) Other nuttx/.config changes -- NSH configurations only.
If the configuration that you are using supports NSH and NSH built-in tasks
then all is well. If it is an NSH configuration, then you will have to define
@@ -101,7 +101,26 @@ Installing and Building the Unit Tests
to change anything further in the nuttx/.config file if you are using either
of these configurations.
- f) Other apps/.config changes -- NON-NSH configurations only.
+ g) Other apps/.config changes -- NON-NSH configurations only.
+
+ Entry Point. You will need to set the entry point in the .config file.
+ For NSH configurations, the entry point will always be "nsh_main" and you
+ will see that setting like:
+
+ CONFIG_USER_ENTRYPOINT="nsh_main"
+
+ If you are not using in NSH, then each unit test has a unique entry point.
+ That entry point is the name of the unit test directory in all lower case
+ plus the suffix "_main". So, for example, the correct entry for the
+ UnitTests/CButton would be:
+
+ CONFIG_USER_ENTRYPOINT="cbutton_main"
+
+ And the correct entry point for UnitTests/nxwm would be:
+
+ CONFIG_USER_ENTRYPOINT="nxwm_main"
+
+ etc.
For non-NSH configurations (such as the sim/touchscreen) you will have to
remove the CONFIGURED_APPS seting that contains the user_start function so
@@ -306,6 +325,9 @@ Example
Do nothing... sim/nsh2 already has C++ support enabled.
+ Since this is an NSH configuration, the entry point does not need to be
+ changed.
+
3. Install the CButton C++ application (for example)
Where: <nxwidgets-directory>/tool
diff --git a/nuttx/TODO b/nuttx/TODO
index 543d15f70..ae42d6c1c 100644
--- a/nuttx/TODO
+++ b/nuttx/TODO
@@ -6,7 +6,7 @@ standards, things that could be improved, and ideas for enhancements.
nuttx/
- (5) Task/Scheduler (sched/)
+ (6) Task/Scheduler (sched/)
(1) On-demand paging (sched/)
(1) Memory Managment (mm/)
(2) Signals (sched/, arch/)
@@ -110,6 +110,13 @@ o Task/Scheduler (sched/)
Status: Open
Priority: Low
+ Title: posix_spawn()
+ Description: This would be a good interface to add to NuttX. It is really
+ just a re-packaging of the existing, non-standard NuttX exec()
+ function.
+ Status: Open
+ Priority: Medium low.
+
o On-demand paging (sched/)
^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/nuttx/arch/arm/include/armv7-m/irq.h b/nuttx/arch/arm/include/armv7-m/irq.h
index 6cef85c02..950ce80ca 100644
--- a/nuttx/arch/arm/include/armv7-m/irq.h
+++ b/nuttx/arch/arm/include/armv7-m/irq.h
@@ -129,8 +129,25 @@ struct xcptcontext
#ifndef __ASSEMBLY__
+/* Get/set the primask register */
+
+static inline uint8_t getprimask(void) __attribute__((always_inline));
+static inline uint8_t getprimask(void)
+{
+ uint32_t primask;
+ __asm__ __volatile__
+ (
+ "\tmrs %0, primask\n"
+ : "=r" (primask)
+ :
+ : "memory");
+
+ return (uint8_t)primask;
+}
+
/* Disable IRQs */
+static inline void irqdisable(void) __attribute__((always_inline));
static inline void irqdisable(void)
{
__asm__ __volatile__ ("\tcpsid i\n");
@@ -138,26 +155,22 @@ static inline void irqdisable(void)
/* Save the current primask state & disable IRQs */
+static inline irqstate_t irqsave(void) __attribute__((always_inline));
static inline irqstate_t irqsave(void)
{
- unsigned short primask;
+ /* Return the current value of primask register (before disabling) */
- /* Return the current value of primask register and set
- * bit 0 of the primask register to disable interrupts
- */
+ uint8_t primask = getprimask();
- __asm__ __volatile__
- (
- "\tmrs %0, primask\n"
- "\tcpsid i\n"
- : "=r" (primask)
- :
- : "memory");
+ /* Then set bit 0 of the primask register to disable interrupts */
+
+ irqdisable();
return primask;
}
/* Enable IRQs */
+static inline void irqenable(void) __attribute__((always_inline));
static inline void irqenable(void)
{
__asm__ __volatile__ ("\tcpsie i\n");
@@ -165,61 +178,48 @@ static inline void irqenable(void)
/* Restore saved primask state */
-static inline void irqrestore(irqstate_t primask)
+static inline void setprimask(uint32_t primask) __attribute__((always_inline));
+static inline void setprimask(uint32_t primask)
{
- /* If bit 0 of the primask is 0, then we need to restore
- * interupts.
- */
-
__asm__ __volatile__
(
- "\ttst %0, #1\n"
- "\tbne 1f\n"
- "\tcpsie i\n"
- "1:\n"
+ "\tmsr primask, %0\n"
:
: "r" (primask)
: "memory");
}
-/* Get/set the primask register */
-
-static inline uint8_t getprimask(void)
+static inline void irqrestore(irqstate_t primask) __attribute__((always_inline));
+static inline void irqrestore(irqstate_t primask)
{
- uint32_t primask;
- __asm__ __volatile__
- (
- "\tmrs %0, primask\n"
- : "=r" (primask)
- :
- : "memory");
- return (uint8_t)primask;
-}
+ /* If bit 0 of the primask is 0, then we need to restore
+ * interrupts.
+ */
-static inline void setprimask(uint32_t primask)
-{
- __asm__ __volatile__
- (
- "\tmsr primask, %0\n"
- :
- : "r" (primask)
- : "memory");
+ if ((primask & 1) == 0)
+ {
+ setprimask(primask);
+ }
}
/* Get/set the basepri register */
+static inline uint8_t getbasepri(void) __attribute__((always_inline));
static inline uint8_t getbasepri(void)
{
uint32_t basepri;
+
__asm__ __volatile__
(
"\tmrs %0, basepri\n"
: "=r" (basepri)
:
: "memory");
+
return (uint8_t)basepri;
}
+static inline void setbasepri(uint32_t basepri) __attribute__((always_inline));
static inline void setbasepri(uint32_t basepri)
{
__asm__ __volatile__
@@ -232,6 +232,7 @@ static inline void setbasepri(uint32_t basepri)
/* Get/set IPSR */
+static inline uint32_t getipsr(void) __attribute__((always_inline));
static inline uint32_t getipsr(void)
{
uint32_t ipsr;
@@ -241,9 +242,11 @@ static inline uint32_t getipsr(void)
: "=r" (ipsr)
:
: "memory");
+
return ipsr;
}
+static inline void setipsr(uint32_t ipsr) __attribute__((always_inline));
static inline void setipsr(uint32_t ipsr)
{
__asm__ __volatile__
@@ -256,6 +259,7 @@ static inline void setipsr(uint32_t ipsr)
/* Get/set CONTROL */
+static inline uint32_t getcontrol(void) __attribute__((always_inline));
static inline uint32_t getcontrol(void)
{
uint32_t control;
@@ -265,9 +269,11 @@ static inline uint32_t getcontrol(void)
: "=r" (control)
:
: "memory");
+
return control;
}
+static inline void setcontrol(uint32_t control) __attribute__((always_inline));
static inline void setcontrol(uint32_t control)
{
__asm__ __volatile__
diff --git a/nuttx/arch/arm/src/stm32/stm32_spi.c b/nuttx/arch/arm/src/stm32/stm32_spi.c
index 40b1a29a0..2d907bfca 100644
--- a/nuttx/arch/arm/src/stm32/stm32_spi.c
+++ b/nuttx/arch/arm/src/stm32/stm32_spi.c
@@ -49,7 +49,7 @@
* 3. Add a calls to up_spiinitialize() in your low level application
* initialization logic
* 4. The handle returned by up_spiinitialize() may then be used to bind the
- * SPI driver to higher level logic (e.g., calling
+ * SPI driver to higher level logic (e.g., calling
* mmcsd_spislotinitialize(), for example, will bind the SPI driver to
* the SPI MMC/SD driver).
*
@@ -881,7 +881,7 @@ static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
else
{
/* Less than fPCLK/128. This is as slow as we can go */
-
+
setbits = SPI_CR1_FPCLCKd256; /* 111: fPCLK/256 */
actual = priv->spiclock >> 8;
}
@@ -941,22 +941,22 @@ static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
setbits = 0;
clrbits = SPI_CR1_CPOL|SPI_CR1_CPHA;
break;
-
+
case SPIDEV_MODE1: /* CPOL=0; CPHA=1 */
setbits = SPI_CR1_CPHA;
clrbits = SPI_CR1_CPOL;
break;
-
+
case SPIDEV_MODE2: /* CPOL=1; CPHA=0 */
setbits = SPI_CR1_CPOL;
clrbits = SPI_CR1_CPHA;
break;
-
+
case SPIDEV_MODE3: /* CPOL=1; CPHA=1 */
setbits = SPI_CR1_CPOL|SPI_CR1_CPHA;
clrbits = 0;
break;
-
+
default:
return;
}
@@ -1008,7 +1008,7 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
setbits = 0;
clrbits = SPI_CR1_DFF;
break;
-
+
case 16:
setbits = SPI_CR1_DFF;
clrbits = 0;
@@ -1111,7 +1111,7 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
}
/* Exchange one word */
-
+
word = spi_send(dev, word);
/* Is there a buffer to receive the return value? */
@@ -1120,7 +1120,7 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
{
*dest++ = word;
}
- }
+ }
}
else
{
@@ -1144,7 +1144,7 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
}
/* Exchange one word */
-
+
word = (uint8_t)spi_send(dev, (uint16_t)word);
/* Is there a buffer to receive the return value? */
@@ -1152,7 +1152,7 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
if (dest)
{
*dest++ = word;
- }
+ }
}
}
}
@@ -1331,7 +1331,7 @@ static void spi_portinitialize(FAR struct stm32_spidev_s *priv)
priv->txdma = stm32_dmachannel(priv->txch);
DEBUGASSERT(priv->rxdma && priv->txdma);
#endif
-
+
/* Enable spi */
spi_modifycr1(priv, SPI_CR1_SPE, 0);
@@ -1360,7 +1360,7 @@ FAR struct spi_dev_s *up_spiinitialize(int port)
FAR struct stm32_spidev_s *priv = NULL;
irqstate_t flags = irqsave();
-
+
#ifdef CONFIG_STM32_SPI1
if (port == 1)
{
diff --git a/nuttx/configs/fire-stm32v2/src/fire-internal.h b/nuttx/configs/fire-stm32v2/src/fire-internal.h
index 801fb127e..0260d8e33 100644
--- a/nuttx/configs/fire-stm32v2/src/fire-internal.h
+++ b/nuttx/configs/fire-stm32v2/src/fire-internal.h
@@ -214,15 +214,16 @@
# warning "TFT LCD and ENCJ2860 shared PE1"
#endif
-/* CS and Reset are active low. Initial states are not selected and not in
- * reset (driver does a soft reset).
+/* CS and Reset are active low. Initial states are not selected and in
+ * reset. The ENC28J60 is taken out of reset when the driver is
+ * initialized (thedriver does a soft reset too).
*/
#ifdef CONFIG_ENC28J60
# define GPIO_ENC28J60_CS (GPIO_OUTPUT|GPIO_CNF_OUTPP|GPIO_MODE_50MHz|\
GPIO_OUTPUT_SET|GPIO_PORTA|GPIO_PIN4)
# define GPIO_ENC28J60_RESET (GPIO_OUTPUT|GPIO_CNF_OUTPP|GPIO_MODE_50MHz|\
- GPIO_OUTPUT_SET|GPIO_PORTE|GPIO_PIN1)
+ GPIO_OUTPUT_CLEAR|GPIO_PORTE|GPIO_PIN1)
# define GPIO_ENC28J60_INTR (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|\
GPIO_EXTI|GPIO_PORTE|GPIO_PIN5)
#endif
diff --git a/nuttx/drivers/net/enc28j60.c b/nuttx/drivers/net/enc28j60.c
index 47a84ec9f..df4353b9d 100644
--- a/nuttx/drivers/net/enc28j60.c
+++ b/nuttx/drivers/net/enc28j60.c
@@ -171,7 +171,7 @@
enum enc_state_e
{
- ENCSTATE_UNIT = 0, /* The interface is in an unknown state */
+ ENCSTATE_UNINIT = 0, /* The interface is in an uninitialized state */
ENCSTATE_DOWN, /* The interface is down */
ENCSTATE_UP /* The interface is up */
};
@@ -2265,7 +2265,7 @@ int enc_initialize(FAR struct spi_dev_s *spi,
* bringing the interface up.
*/
- priv->ifstate = ENCSTATE_UNIT;
+ priv->ifstate = ENCSTATE_UNINIT;
/* Attach the interrupt to the driver (but don't enable it yet) */