mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-11-06 10:31:37 +08:00
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:
@@ -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__
|
||||
|
||||
Reference in New Issue
Block a user