- Timestamp:
- Apr 5, 2019, 9:26:53 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
asp3_tinet_ecnl_arm/trunk/asp3_dcre/mbed/platform/mbed_critical.c
r352 r374 18 18 /* Declare __STDC_LIMIT_MACROS so stdint.h defines UINT32_MAX when using C++ */ 19 19 #define __STDC_LIMIT_MACROS 20 #include " platform/mbed_critical.h"20 #include "hal/critical_section_api.h" 21 21 22 22 #include "cmsis.h" 23 23 #include "platform/mbed_assert.h" 24 #include "platform/mbed_critical.h" 24 25 #include "platform/mbed_toolchain.h" 25 26 26 #define EXCLUSIVE_ACCESS (!defined (__CORTEX_M0) && !defined (__CORTEX_M0PLUS)) 27 28 static volatile uint32_t interrupt_enable_counter = 0; 29 static volatile bool critical_interrupts_disabled = false; 27 // if __EXCLUSIVE_ACCESS rtx macro not defined, we need to get this via own-set architecture macros 28 #ifndef MBED_EXCLUSIVE_ACCESS 29 #ifndef __EXCLUSIVE_ACCESS 30 #if ((__ARM_ARCH_7M__ == 1U) || \ 31 (__ARM_ARCH_7EM__ == 1U) || \ 32 (__ARM_ARCH_8M_BASE__ == 1U) || \ 33 (__ARM_ARCH_8M_MAIN__ == 1U)) || \ 34 (__ARM_ARCH_7A__ == 1U) 35 #define MBED_EXCLUSIVE_ACCESS 1U 36 #elif (__ARM_ARCH_6M__ == 1U) 37 #define MBED_EXCLUSIVE_ACCESS 0U 38 #else 39 #error "Unknown architecture for exclusive access" 40 #endif 41 #else 42 #define MBED_EXCLUSIVE_ACCESS __EXCLUSIVE_ACCESS 43 #endif 44 #endif 45 46 static volatile uint32_t critical_section_reentrancy_counter = 0; 30 47 31 48 bool core_util_are_interrupts_enabled(void) … … 38 55 } 39 56 40 MBED_WEAK void core_util_critical_section_enter(void) 41 { 42 bool interrupts_disabled = !core_util_are_interrupts_enabled(); 43 __disable_irq(); 44 45 /* Save the interrupt disabled state as it was prior to any nested critical section lock use */ 46 if (!interrupt_enable_counter) { 47 critical_interrupts_disabled = interrupts_disabled; 48 } 49 50 /* If the interrupt_enable_counter overflows or we are in a nested critical section and interrupts 51 are enabled, then something has gone badly wrong thus assert an error. 52 */ 53 MBED_ASSERT(interrupt_enable_counter < UINT32_MAX); 54 // FIXME 55 #ifndef FEATURE_UVISOR 56 if (interrupt_enable_counter > 0) { 57 MBED_ASSERT(interrupts_disabled); 58 } 59 #else 60 #warning "core_util_critical_section_enter needs fixing to work from unprivileged code" 61 #endif /* FEATURE_UVISOR */ 62 interrupt_enable_counter++; 63 } 64 65 MBED_WEAK void core_util_critical_section_exit(void) 66 { 67 /* If critical_section_enter has not previously been called, do nothing */ 68 if (interrupt_enable_counter) { 69 70 // FIXME 71 #ifndef FEATURE_UVISOR 72 bool interrupts_disabled = !core_util_are_interrupts_enabled(); /* get the current interrupt disabled state */ 73 74 MBED_ASSERT(interrupts_disabled); /* Interrupts must be disabled on invoking an exit from a critical section */ 75 #else 76 #warning "core_util_critical_section_exit needs fixing to work from unprivileged code" 77 #endif /* FEATURE_UVISOR */ 78 79 interrupt_enable_counter--; 80 81 /* Only re-enable interrupts if we are exiting the last of the nested critical sections and 82 interrupts were enabled on entry to the first critical section. 83 */ 84 if (!interrupt_enable_counter && !critical_interrupts_disabled) { 85 __enable_irq(); 57 bool core_util_is_isr_active(void) 58 { 59 #if defined(__CORTEX_A9) 60 switch (__get_CPSR() & 0x1FU) { 61 case CPSR_M_USR: 62 case CPSR_M_SYS: 63 return false; 64 case CPSR_M_SVC: 65 default: 66 return true; 67 } 68 #else 69 return (__get_IPSR() != 0U); 70 #endif 71 } 72 73 bool core_util_in_critical_section(void) 74 { 75 return hal_in_critical_section(); 76 } 77 78 void core_util_critical_section_enter(void) 79 { 80 // If the reentrancy counter overflows something has gone badly wrong. 81 MBED_ASSERT(critical_section_reentrancy_counter < UINT32_MAX); 82 83 hal_critical_section_enter(); 84 85 ++critical_section_reentrancy_counter; 86 } 87 88 void core_util_critical_section_exit(void) 89 { 90 91 // If critical_section_enter has not previously been called, do nothing 92 if (critical_section_reentrancy_counter == 0) { 93 return; 94 } 95 96 --critical_section_reentrancy_counter; 97 98 if (critical_section_reentrancy_counter == 0) { 99 hal_critical_section_exit(); 100 } 101 } 102 103 #if MBED_EXCLUSIVE_ACCESS 104 105 /* Supress __ldrex and __strex deprecated warnings - "#3731-D: intrinsic is deprecated" */ 106 #if defined (__CC_ARM) 107 #pragma diag_suppress 3731 108 #endif 109 110 bool core_util_atomic_cas_u8(volatile uint8_t *ptr, uint8_t *expectedCurrentValue, uint8_t desiredValue) 111 { 112 do { 113 uint8_t currentValue = __LDREXB(ptr); 114 if (currentValue != *expectedCurrentValue) { 115 *expectedCurrentValue = currentValue; 116 __CLREX(); 117 return false; 86 118 } 87 } 88 } 89 90 #if EXCLUSIVE_ACCESS 91 92 /* Supress __ldrex and __strex deprecated warnings - "#3731-D: intrinsic is deprecated" */ 93 #if defined (__CC_ARM) 94 #pragma diag_suppress 3731 95 #endif 96 97 bool core_util_atomic_cas_u8(uint8_t *ptr, uint8_t *expectedCurrentValue, uint8_t desiredValue) 98 { 99 uint8_t currentValue = __LDREXB((volatile uint8_t*)ptr); 100 if (currentValue != *expectedCurrentValue) { 101 *expectedCurrentValue = currentValue; 102 __CLREX(); 103 return false; 104 } 105 106 return !__STREXB(desiredValue, (volatile uint8_t*)ptr); 107 } 108 109 bool core_util_atomic_cas_u16(uint16_t *ptr, uint16_t *expectedCurrentValue, uint16_t desiredValue) 110 { 111 uint16_t currentValue = __LDREXH((volatile uint16_t*)ptr); 112 if (currentValue != *expectedCurrentValue) { 113 *expectedCurrentValue = currentValue; 114 __CLREX(); 115 return false; 116 } 117 118 return !__STREXH(desiredValue, (volatile uint16_t*)ptr); 119 } 120 121 122 bool core_util_atomic_cas_u32(uint32_t *ptr, uint32_t *expectedCurrentValue, uint32_t desiredValue) 123 { 124 uint32_t currentValue = __LDREXW((volatile uint32_t*)ptr); 125 if (currentValue != *expectedCurrentValue) { 126 *expectedCurrentValue = currentValue; 127 __CLREX(); 128 return false; 129 } 130 131 return !__STREXW(desiredValue, (volatile uint32_t*)ptr); 132 } 133 134 uint8_t core_util_atomic_incr_u8(uint8_t *valuePtr, uint8_t delta) 119 } while (__STREXB(desiredValue, ptr)); 120 return true; 121 } 122 123 bool core_util_atomic_cas_u16(volatile uint16_t *ptr, uint16_t *expectedCurrentValue, uint16_t desiredValue) 124 { 125 do { 126 uint16_t currentValue = __LDREXH(ptr); 127 if (currentValue != *expectedCurrentValue) { 128 *expectedCurrentValue = currentValue; 129 __CLREX(); 130 return false; 131 } 132 } while (__STREXH(desiredValue, ptr)); 133 return true; 134 } 135 136 137 bool core_util_atomic_cas_u32(volatile uint32_t *ptr, uint32_t *expectedCurrentValue, uint32_t desiredValue) 138 { 139 do { 140 uint32_t currentValue = __LDREXW(ptr); 141 if (currentValue != *expectedCurrentValue) { 142 *expectedCurrentValue = currentValue; 143 __CLREX(); 144 return false; 145 } 146 } while (__STREXW(desiredValue, ptr)); 147 return true; 148 } 149 150 uint8_t core_util_atomic_incr_u8(volatile uint8_t *valuePtr, uint8_t delta) 135 151 { 136 152 uint8_t newValue; 137 153 do { 138 newValue = __LDREXB( (volatile uint8_t*)valuePtr) + delta;139 } while (__STREXB(newValue, (volatile uint8_t*)valuePtr));140 return newValue; 141 } 142 143 uint16_t core_util_atomic_incr_u16( uint16_t *valuePtr, uint16_t delta)154 newValue = __LDREXB(valuePtr) + delta; 155 } while (__STREXB(newValue, valuePtr)); 156 return newValue; 157 } 158 159 uint16_t core_util_atomic_incr_u16(volatile uint16_t *valuePtr, uint16_t delta) 144 160 { 145 161 uint16_t newValue; 146 162 do { 147 newValue = __LDREXH( (volatile uint16_t*)valuePtr) + delta;148 } while (__STREXH(newValue, (volatile uint16_t*)valuePtr));149 return newValue; 150 } 151 152 uint32_t core_util_atomic_incr_u32( uint32_t *valuePtr, uint32_t delta)163 newValue = __LDREXH(valuePtr) + delta; 164 } while (__STREXH(newValue, valuePtr)); 165 return newValue; 166 } 167 168 uint32_t core_util_atomic_incr_u32(volatile uint32_t *valuePtr, uint32_t delta) 153 169 { 154 170 uint32_t newValue; 155 171 do { 156 newValue = __LDREXW( (volatile uint32_t*)valuePtr) + delta;157 } while (__STREXW(newValue, (volatile uint32_t*)valuePtr));158 return newValue; 159 } 160 161 162 uint8_t core_util_atomic_decr_u8( uint8_t *valuePtr, uint8_t delta)172 newValue = __LDREXW(valuePtr) + delta; 173 } while (__STREXW(newValue, valuePtr)); 174 return newValue; 175 } 176 177 178 uint8_t core_util_atomic_decr_u8(volatile uint8_t *valuePtr, uint8_t delta) 163 179 { 164 180 uint8_t newValue; 165 181 do { 166 newValue = __LDREXB( (volatile uint8_t*)valuePtr) - delta;167 } while (__STREXB(newValue, (volatile uint8_t*)valuePtr));168 return newValue; 169 } 170 171 uint16_t core_util_atomic_decr_u16( uint16_t *valuePtr, uint16_t delta)182 newValue = __LDREXB(valuePtr) - delta; 183 } while (__STREXB(newValue, valuePtr)); 184 return newValue; 185 } 186 187 uint16_t core_util_atomic_decr_u16(volatile uint16_t *valuePtr, uint16_t delta) 172 188 { 173 189 uint16_t newValue; 174 190 do { 175 newValue = __LDREXH( (volatile uint16_t*)valuePtr) - delta;176 } while (__STREXH(newValue, (volatile uint16_t*)valuePtr));177 return newValue; 178 } 179 180 uint32_t core_util_atomic_decr_u32( uint32_t *valuePtr, uint32_t delta)191 newValue = __LDREXH(valuePtr) - delta; 192 } while (__STREXH(newValue, valuePtr)); 193 return newValue; 194 } 195 196 uint32_t core_util_atomic_decr_u32(volatile uint32_t *valuePtr, uint32_t delta) 181 197 { 182 198 uint32_t newValue; 183 199 do { 184 newValue = __LDREXW( (volatile uint32_t*)valuePtr) - delta;185 } while (__STREXW(newValue, (volatile uint32_t*)valuePtr));186 return newValue; 187 } 188 189 #else 190 191 bool core_util_atomic_cas_u8( uint8_t *ptr, uint8_t *expectedCurrentValue, uint8_t desiredValue)200 newValue = __LDREXW(valuePtr) - delta; 201 } while (__STREXW(newValue, valuePtr)); 202 return newValue; 203 } 204 205 #else 206 207 bool core_util_atomic_cas_u8(volatile uint8_t *ptr, uint8_t *expectedCurrentValue, uint8_t desiredValue) 192 208 { 193 209 bool success; … … 206 222 } 207 223 208 bool core_util_atomic_cas_u16( uint16_t *ptr, uint16_t *expectedCurrentValue, uint16_t desiredValue)224 bool core_util_atomic_cas_u16(volatile uint16_t *ptr, uint16_t *expectedCurrentValue, uint16_t desiredValue) 209 225 { 210 226 bool success; … … 224 240 225 241 226 bool core_util_atomic_cas_u32( uint32_t *ptr, uint32_t *expectedCurrentValue, uint32_t desiredValue)242 bool core_util_atomic_cas_u32(volatile uint32_t *ptr, uint32_t *expectedCurrentValue, uint32_t desiredValue) 227 243 { 228 244 bool success; … … 242 258 243 259 244 uint8_t core_util_atomic_incr_u8( uint8_t *valuePtr, uint8_t delta)260 uint8_t core_util_atomic_incr_u8(volatile uint8_t *valuePtr, uint8_t delta) 245 261 { 246 262 uint8_t newValue; … … 252 268 } 253 269 254 uint16_t core_util_atomic_incr_u16( uint16_t *valuePtr, uint16_t delta)270 uint16_t core_util_atomic_incr_u16(volatile uint16_t *valuePtr, uint16_t delta) 255 271 { 256 272 uint16_t newValue; … … 262 278 } 263 279 264 uint32_t core_util_atomic_incr_u32( uint32_t *valuePtr, uint32_t delta)280 uint32_t core_util_atomic_incr_u32(volatile uint32_t *valuePtr, uint32_t delta) 265 281 { 266 282 uint32_t newValue; … … 273 289 274 290 275 uint8_t core_util_atomic_decr_u8( uint8_t *valuePtr, uint8_t delta)291 uint8_t core_util_atomic_decr_u8(volatile uint8_t *valuePtr, uint8_t delta) 276 292 { 277 293 uint8_t newValue; … … 283 299 } 284 300 285 uint16_t core_util_atomic_decr_u16( uint16_t *valuePtr, uint16_t delta)301 uint16_t core_util_atomic_decr_u16(volatile uint16_t *valuePtr, uint16_t delta) 286 302 { 287 303 uint16_t newValue; … … 293 309 } 294 310 295 uint32_t core_util_atomic_decr_u32( uint32_t *valuePtr, uint32_t delta)311 uint32_t core_util_atomic_decr_u32(volatile uint32_t *valuePtr, uint32_t delta) 296 312 { 297 313 uint32_t newValue; … … 306 322 307 323 308 bool core_util_atomic_cas_ptr(void **ptr, void **expectedCurrentValue, void *desiredValue) { 324 bool core_util_atomic_cas_ptr(void *volatile *ptr, void **expectedCurrentValue, void *desiredValue) 325 { 309 326 return core_util_atomic_cas_u32( 310 (uint32_t *)ptr, 311 (uint32_t *)expectedCurrentValue, 312 (uint32_t)desiredValue); 313 } 314 315 void *core_util_atomic_incr_ptr(void **valuePtr, ptrdiff_t delta) { 316 return (void *)core_util_atomic_incr_u32((uint32_t *)valuePtr, (uint32_t)delta); 317 } 318 319 void *core_util_atomic_decr_ptr(void **valuePtr, ptrdiff_t delta) { 320 return (void *)core_util_atomic_decr_u32((uint32_t *)valuePtr, (uint32_t)delta); 321 } 322 327 (volatile uint32_t *)ptr, 328 (uint32_t *)expectedCurrentValue, 329 (uint32_t)desiredValue); 330 } 331 332 void *core_util_atomic_incr_ptr(void *volatile *valuePtr, ptrdiff_t delta) 333 { 334 return (void *)core_util_atomic_incr_u32((volatile uint32_t *)valuePtr, (uint32_t)delta); 335 } 336 337 void *core_util_atomic_decr_ptr(void *volatile *valuePtr, ptrdiff_t delta) 338 { 339 return (void *)core_util_atomic_decr_u32((volatile uint32_t *)valuePtr, (uint32_t)delta); 340 } 341
Note:
See TracChangeset
for help on using the changeset viewer.