Skip to content

Commit cb24e38

Browse files
committed
Merge pull request #1856 from 0xc0170/fix_critical_cortexa
Critical section - fix for cortex-a
2 parents 859ae4c + b5c4faf commit cb24e38

File tree

1 file changed

+18
-8
lines changed

1 file changed

+18
-8
lines changed

hal/common/critical.c

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,24 +27,34 @@
2727
#define EXCLUSIVE_ACCESS (!defined (__CORTEX_M0) && !defined (__CORTEX_M0PLUS))
2828

2929
static volatile uint32_t interrupt_enable_counter = 0;
30-
static volatile uint32_t critical_primask = 0;
30+
static volatile uint32_t critical_interrupts_disabled = 0;
31+
32+
static inline uint32_t get_interrupts_disabled(void)
33+
{
34+
#if defined(__CORTEX_A9)
35+
uint32_t interrupts_disabled = (__get_CPSR() & 0x80) >> 7;
36+
#else
37+
uint32_t interrupts_disabled = __get_PRIMASK();
38+
#endif
39+
return interrupts_disabled;
40+
}
3141

3242
void core_util_critical_section_enter()
3343
{
34-
uint32_t primask = __get_PRIMASK(); /* get the current interrupt enabled state */
44+
uint32_t interrupts_disabled = get_interrupts_disabled();
3545
__disable_irq();
3646

37-
/* Save the interrupt enabled state as it was prior to any nested critical section lock use */
47+
/* Save the interrupt disabled state as it was prior to any nested critical section lock use */
3848
if (!interrupt_enable_counter) {
39-
critical_primask = primask & 0x1;
49+
critical_interrupts_disabled = interrupts_disabled & 0x1;
4050
}
4151

4252
/* If the interrupt_enable_counter overflows or we are in a nested critical section and interrupts
4353
are enabled, then something has gone badly wrong thus assert an error.
4454
*/
4555
MBED_ASSERT(interrupt_enable_counter < UINT32_MAX);
4656
if (interrupt_enable_counter > 0) {
47-
MBED_ASSERT(primask & 0x1);
57+
MBED_ASSERT(interrupts_disabled & 0x1);
4858
}
4959
interrupt_enable_counter++;
5060
}
@@ -54,16 +64,16 @@ void core_util_critical_section_exit()
5464
/* If critical_section_enter has not previously been called, do nothing */
5565
if (interrupt_enable_counter) {
5666

57-
uint32_t primask = __get_PRIMASK(); /* get the current interrupt enabled state */
67+
uint32_t interrupts_disabled = get_interrupts_disabled(); /* get the current interrupt disabled state */
5868

59-
MBED_ASSERT(primask & 0x1); /* Interrupts must be disabled on invoking an exit from a critical section */
69+
MBED_ASSERT(interrupts_disabled & 0x1); /* Interrupts must be disabled on invoking an exit from a critical section */
6070

6171
interrupt_enable_counter--;
6272

6373
/* Only re-enable interrupts if we are exiting the last of the nested critical sections and
6474
interrupts were enabled on entry to the first critical section.
6575
*/
66-
if (!interrupt_enable_counter && !critical_primask) {
76+
if (!interrupt_enable_counter && !critical_interrupts_disabled) {
6777
__enable_irq();
6878
}
6979
}

0 commit comments

Comments
 (0)