forked from Archive/PX4-Autopilot
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
This commit is contained in:
parent
cfa24e37d6
commit
4070ce05fe
|
@ -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
|
||||
|
||||
|
|
|
@ -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/)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
|
|
@ -129,61 +129,9 @@ struct xcptcontext
|
|||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/* Disable IRQs */
|
||||
|
||||
static inline void irqdisable(void)
|
||||
{
|
||||
__asm__ __volatile__ ("\tcpsid i\n");
|
||||
}
|
||||
|
||||
/* Save the current primask state & disable IRQs */
|
||||
|
||||
static inline irqstate_t irqsave(void)
|
||||
{
|
||||
unsigned short primask;
|
||||
|
||||
/* Return the current value of primask register and set
|
||||
* bit 0 of the primask register to disable interrupts
|
||||
*/
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"\tmrs %0, primask\n"
|
||||
"\tcpsid i\n"
|
||||
: "=r" (primask)
|
||||
:
|
||||
: "memory");
|
||||
return primask;
|
||||
}
|
||||
|
||||
/* Enable IRQs */
|
||||
|
||||
static inline void irqenable(void)
|
||||
{
|
||||
__asm__ __volatile__ ("\tcpsie i\n");
|
||||
}
|
||||
|
||||
/* Restore saved primask state */
|
||||
|
||||
static inline void irqrestore(irqstate_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"
|
||||
:
|
||||
: "r" (primask)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
/* Get/set the primask register */
|
||||
|
||||
static inline uint8_t getprimask(void) __attribute__((always_inline));
|
||||
static inline uint8_t getprimask(void)
|
||||
{
|
||||
uint32_t primask;
|
||||
|
@ -193,9 +141,44 @@ static inline uint8_t getprimask(void)
|
|||
: "=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");
|
||||
}
|
||||
|
||||
/* Save the current primask state & disable IRQs */
|
||||
|
||||
static inline irqstate_t irqsave(void) __attribute__((always_inline));
|
||||
static inline irqstate_t irqsave(void)
|
||||
{
|
||||
/* Return the current value of primask register (before disabling) */
|
||||
|
||||
uint8_t primask = getprimask();
|
||||
|
||||
/* 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");
|
||||
}
|
||||
|
||||
/* Restore saved primask state */
|
||||
|
||||
static inline void setprimask(uint32_t primask) __attribute__((always_inline));
|
||||
static inline void setprimask(uint32_t primask)
|
||||
{
|
||||
__asm__ __volatile__
|
||||
|
@ -206,20 +189,37 @@ static inline void setprimask(uint32_t primask)
|
|||
: "memory");
|
||||
}
|
||||
|
||||
static inline void irqrestore(irqstate_t primask) __attribute__((always_inline));
|
||||
static inline void irqrestore(irqstate_t primask)
|
||||
{
|
||||
/* If bit 0 of the primask is 0, then we need to restore
|
||||
* interrupts.
|
||||
*/
|
||||
|
||||
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__
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) */
|
||||
|
||||
|
|
Loading…
Reference in New Issue