mbed library sources. Supersedes mbed-src.
Fork of mbed-dev by
Diff: platform/mbed_critical.c
- Revision:
- 184:08ed48f1de7f
- Parent:
- 180:96ed750bd169
--- a/platform/mbed_critical.c Tue Mar 20 17:01:51 2018 +0000 +++ b/platform/mbed_critical.c Thu Apr 19 17:12:19 2018 +0100 @@ -17,14 +17,33 @@ /* Declare __STDC_LIMIT_MACROS so stdint.h defines UINT32_MAX when using C++ */ #define __STDC_LIMIT_MACROS -#include "platform/mbed_critical.h" +#include "hal/critical_section_api.h" #include "cmsis.h" #include "platform/mbed_assert.h" +#include "platform/mbed_critical.h" #include "platform/mbed_toolchain.h" -static volatile uint32_t interrupt_enable_counter = 0; -static volatile bool critical_interrupts_disabled = false; +// if __EXCLUSIVE_ACCESS rtx macro not defined, we need to get this via own-set architecture macros +#ifndef MBED_EXCLUSIVE_ACCESS +#ifndef __EXCLUSIVE_ACCESS +#if ((__ARM_ARCH_7M__ == 1U) || \ + (__ARM_ARCH_7EM__ == 1U) || \ + (__ARM_ARCH_8M_BASE__ == 1U) || \ + (__ARM_ARCH_8M_MAIN__ == 1U)) || \ + (__ARM_ARCH_7A__ == 1U) +#define MBED_EXCLUSIVE_ACCESS 1U +#elif (__ARM_ARCH_6M__ == 1U) +#define MBED_EXCLUSIVE_ACCESS 0U +#else +#error "Unknown architecture for exclusive access" +#endif +#else +#define MBED_EXCLUSIVE_ACCESS __EXCLUSIVE_ACCESS +#endif +#endif + +static volatile uint32_t critical_section_reentrancy_counter = 0; bool core_util_are_interrupts_enabled(void) { @@ -51,161 +70,150 @@ #endif } -MBED_WEAK void core_util_critical_section_enter(void) +bool core_util_in_critical_section(void) +{ + return hal_in_critical_section(); +} + +void core_util_critical_section_enter(void) { - bool interrupts_disabled = !core_util_are_interrupts_enabled(); - __disable_irq(); +// FIXME +#ifdef FEATURE_UVISOR + #warning "core_util_critical_section_enter needs fixing to work from unprivileged code" +#else + // If the reentrancy counter overflows something has gone badly wrong. + MBED_ASSERT(critical_section_reentrancy_counter < UINT32_MAX); +#endif /* FEATURE_UVISOR */ + + hal_critical_section_enter(); - /* Save the interrupt disabled state as it was prior to any nested critical section lock use */ - if (!interrupt_enable_counter) { - critical_interrupts_disabled = interrupts_disabled; + ++critical_section_reentrancy_counter; +} + +void core_util_critical_section_exit(void) +{ +// FIXME +#ifdef FEATURE_UVISOR + #warning "core_util_critical_section_exit needs fixing to work from unprivileged code" +#endif /* FEATURE_UVISOR */ + + // If critical_section_enter has not previously been called, do nothing + if (critical_section_reentrancy_counter == 0) { + return; } - /* If the interrupt_enable_counter overflows or we are in a nested critical section and interrupts - are enabled, then something has gone badly wrong thus assert an error. - */ - MBED_ASSERT(interrupt_enable_counter < UINT32_MAX); -// FIXME -#ifndef FEATURE_UVISOR - if (interrupt_enable_counter > 0) { - MBED_ASSERT(interrupts_disabled); - } -#else -#warning "core_util_critical_section_enter needs fixing to work from unprivileged code" -#endif /* FEATURE_UVISOR */ - interrupt_enable_counter++; -} + --critical_section_reentrancy_counter; -MBED_WEAK void core_util_critical_section_exit(void) -{ - /* If critical_section_enter has not previously been called, do nothing */ - if (interrupt_enable_counter) { - -// FIXME -#ifndef FEATURE_UVISOR - bool interrupts_disabled = !core_util_are_interrupts_enabled(); /* get the current interrupt disabled state */ - - MBED_ASSERT(interrupts_disabled); /* Interrupts must be disabled on invoking an exit from a critical section */ -#else -#warning "core_util_critical_section_exit needs fixing to work from unprivileged code" -#endif /* FEATURE_UVISOR */ - - interrupt_enable_counter--; - - /* Only re-enable interrupts if we are exiting the last of the nested critical sections and - interrupts were enabled on entry to the first critical section. - */ - if (!interrupt_enable_counter && !critical_interrupts_disabled) { - __enable_irq(); - } + if (critical_section_reentrancy_counter == 0) { + hal_critical_section_exit(); } } -#if __EXCLUSIVE_ACCESS +#if MBED_EXCLUSIVE_ACCESS /* Supress __ldrex and __strex deprecated warnings - "#3731-D: intrinsic is deprecated" */ #if defined (__CC_ARM) #pragma diag_suppress 3731 #endif -bool core_util_atomic_cas_u8(uint8_t *ptr, uint8_t *expectedCurrentValue, uint8_t desiredValue) +bool core_util_atomic_cas_u8(volatile uint8_t *ptr, uint8_t *expectedCurrentValue, uint8_t desiredValue) { do { - uint8_t currentValue = __LDREXB((volatile uint8_t*)ptr); + uint8_t currentValue = __LDREXB(ptr); if (currentValue != *expectedCurrentValue) { *expectedCurrentValue = currentValue; __CLREX(); return false; } - } while (__STREXB(desiredValue, (volatile uint8_t*)ptr)); + } while (__STREXB(desiredValue, ptr)); return true; } -bool core_util_atomic_cas_u16(uint16_t *ptr, uint16_t *expectedCurrentValue, uint16_t desiredValue) +bool core_util_atomic_cas_u16(volatile uint16_t *ptr, uint16_t *expectedCurrentValue, uint16_t desiredValue) { do { - uint16_t currentValue = __LDREXH((volatile uint16_t*)ptr); + uint16_t currentValue = __LDREXH(ptr); if (currentValue != *expectedCurrentValue) { *expectedCurrentValue = currentValue; __CLREX(); return false; } - } while (__STREXH(desiredValue, (volatile uint16_t*)ptr)); + } while (__STREXH(desiredValue, ptr)); return true; } -bool core_util_atomic_cas_u32(uint32_t *ptr, uint32_t *expectedCurrentValue, uint32_t desiredValue) +bool core_util_atomic_cas_u32(volatile uint32_t *ptr, uint32_t *expectedCurrentValue, uint32_t desiredValue) { do { - uint32_t currentValue = __LDREXW((volatile uint32_t*)ptr); + uint32_t currentValue = __LDREXW(ptr); if (currentValue != *expectedCurrentValue) { *expectedCurrentValue = currentValue; __CLREX(); return false; } - } while (__STREXW(desiredValue, (volatile uint32_t*)ptr)); + } while (__STREXW(desiredValue, ptr)); return true; } -uint8_t core_util_atomic_incr_u8(uint8_t *valuePtr, uint8_t delta) +uint8_t core_util_atomic_incr_u8(volatile uint8_t *valuePtr, uint8_t delta) { uint8_t newValue; do { - newValue = __LDREXB((volatile uint8_t*)valuePtr) + delta; - } while (__STREXB(newValue, (volatile uint8_t*)valuePtr)); + newValue = __LDREXB(valuePtr) + delta; + } while (__STREXB(newValue, valuePtr)); return newValue; } -uint16_t core_util_atomic_incr_u16(uint16_t *valuePtr, uint16_t delta) +uint16_t core_util_atomic_incr_u16(volatile uint16_t *valuePtr, uint16_t delta) { uint16_t newValue; do { - newValue = __LDREXH((volatile uint16_t*)valuePtr) + delta; - } while (__STREXH(newValue, (volatile uint16_t*)valuePtr)); + newValue = __LDREXH(valuePtr) + delta; + } while (__STREXH(newValue, valuePtr)); return newValue; } -uint32_t core_util_atomic_incr_u32(uint32_t *valuePtr, uint32_t delta) +uint32_t core_util_atomic_incr_u32(volatile uint32_t *valuePtr, uint32_t delta) { uint32_t newValue; do { - newValue = __LDREXW((volatile uint32_t*)valuePtr) + delta; - } while (__STREXW(newValue, (volatile uint32_t*)valuePtr)); + newValue = __LDREXW(valuePtr) + delta; + } while (__STREXW(newValue, valuePtr)); return newValue; } -uint8_t core_util_atomic_decr_u8(uint8_t *valuePtr, uint8_t delta) +uint8_t core_util_atomic_decr_u8(volatile uint8_t *valuePtr, uint8_t delta) { uint8_t newValue; do { - newValue = __LDREXB((volatile uint8_t*)valuePtr) - delta; - } while (__STREXB(newValue, (volatile uint8_t*)valuePtr)); + newValue = __LDREXB(valuePtr) - delta; + } while (__STREXB(newValue, valuePtr)); return newValue; } -uint16_t core_util_atomic_decr_u16(uint16_t *valuePtr, uint16_t delta) +uint16_t core_util_atomic_decr_u16(volatile uint16_t *valuePtr, uint16_t delta) { uint16_t newValue; do { - newValue = __LDREXH((volatile uint16_t*)valuePtr) - delta; - } while (__STREXH(newValue, (volatile uint16_t*)valuePtr)); + newValue = __LDREXH(valuePtr) - delta; + } while (__STREXH(newValue, valuePtr)); return newValue; } -uint32_t core_util_atomic_decr_u32(uint32_t *valuePtr, uint32_t delta) +uint32_t core_util_atomic_decr_u32(volatile uint32_t *valuePtr, uint32_t delta) { uint32_t newValue; do { - newValue = __LDREXW((volatile uint32_t*)valuePtr) - delta; - } while (__STREXW(newValue, (volatile uint32_t*)valuePtr)); + newValue = __LDREXW(valuePtr) - delta; + } while (__STREXW(newValue, valuePtr)); return newValue; } #else -bool core_util_atomic_cas_u8(uint8_t *ptr, uint8_t *expectedCurrentValue, uint8_t desiredValue) +bool core_util_atomic_cas_u8(volatile uint8_t *ptr, uint8_t *expectedCurrentValue, uint8_t desiredValue) { bool success; uint8_t currentValue; @@ -222,7 +230,7 @@ return success; } -bool core_util_atomic_cas_u16(uint16_t *ptr, uint16_t *expectedCurrentValue, uint16_t desiredValue) +bool core_util_atomic_cas_u16(volatile uint16_t *ptr, uint16_t *expectedCurrentValue, uint16_t desiredValue) { bool success; uint16_t currentValue; @@ -240,7 +248,7 @@ } -bool core_util_atomic_cas_u32(uint32_t *ptr, uint32_t *expectedCurrentValue, uint32_t desiredValue) +bool core_util_atomic_cas_u32(volatile uint32_t *ptr, uint32_t *expectedCurrentValue, uint32_t desiredValue) { bool success; uint32_t currentValue; @@ -258,7 +266,7 @@ } -uint8_t core_util_atomic_incr_u8(uint8_t *valuePtr, uint8_t delta) +uint8_t core_util_atomic_incr_u8(volatile uint8_t *valuePtr, uint8_t delta) { uint8_t newValue; core_util_critical_section_enter(); @@ -268,7 +276,7 @@ return newValue; } -uint16_t core_util_atomic_incr_u16(uint16_t *valuePtr, uint16_t delta) +uint16_t core_util_atomic_incr_u16(volatile uint16_t *valuePtr, uint16_t delta) { uint16_t newValue; core_util_critical_section_enter(); @@ -278,7 +286,7 @@ return newValue; } -uint32_t core_util_atomic_incr_u32(uint32_t *valuePtr, uint32_t delta) +uint32_t core_util_atomic_incr_u32(volatile uint32_t *valuePtr, uint32_t delta) { uint32_t newValue; core_util_critical_section_enter(); @@ -289,7 +297,7 @@ } -uint8_t core_util_atomic_decr_u8(uint8_t *valuePtr, uint8_t delta) +uint8_t core_util_atomic_decr_u8(volatile uint8_t *valuePtr, uint8_t delta) { uint8_t newValue; core_util_critical_section_enter(); @@ -299,7 +307,7 @@ return newValue; } -uint16_t core_util_atomic_decr_u16(uint16_t *valuePtr, uint16_t delta) +uint16_t core_util_atomic_decr_u16(volatile uint16_t *valuePtr, uint16_t delta) { uint16_t newValue; core_util_critical_section_enter(); @@ -309,7 +317,7 @@ return newValue; } -uint32_t core_util_atomic_decr_u32(uint32_t *valuePtr, uint32_t delta) +uint32_t core_util_atomic_decr_u32(volatile uint32_t *valuePtr, uint32_t delta) { uint32_t newValue; core_util_critical_section_enter(); @@ -322,18 +330,18 @@ #endif -bool core_util_atomic_cas_ptr(void **ptr, void **expectedCurrentValue, void *desiredValue) { +bool core_util_atomic_cas_ptr(void * volatile *ptr, void **expectedCurrentValue, void *desiredValue) { return core_util_atomic_cas_u32( - (uint32_t *)ptr, + (volatile uint32_t *)ptr, (uint32_t *)expectedCurrentValue, (uint32_t)desiredValue); } -void *core_util_atomic_incr_ptr(void **valuePtr, ptrdiff_t delta) { - return (void *)core_util_atomic_incr_u32((uint32_t *)valuePtr, (uint32_t)delta); +void *core_util_atomic_incr_ptr(void * volatile *valuePtr, ptrdiff_t delta) { + return (void *)core_util_atomic_incr_u32((volatile uint32_t *)valuePtr, (uint32_t)delta); } -void *core_util_atomic_decr_ptr(void **valuePtr, ptrdiff_t delta) { - return (void *)core_util_atomic_decr_u32((uint32_t *)valuePtr, (uint32_t)delta); +void *core_util_atomic_decr_ptr(void * volatile *valuePtr, ptrdiff_t delta) { + return (void *)core_util_atomic_decr_u32((volatile uint32_t *)valuePtr, (uint32_t)delta); }