mbed library sources. Supersedes mbed-src.
Dependents: Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more
mbed_critical.c
00001 /* 00002 * Copyright (c) 2015-2016, ARM Limited, All Rights Reserved 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00006 * not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00013 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 /* Declare __STDC_LIMIT_MACROS so stdint.h defines UINT32_MAX when using C++ */ 00019 #define __STDC_LIMIT_MACROS 00020 #include "hal/critical_section_api.h" 00021 00022 #include "cmsis.h" 00023 #include "platform/mbed_assert.h" 00024 #include "platform/mbed_critical.h" 00025 #include "platform/mbed_toolchain.h" 00026 00027 // if __EXCLUSIVE_ACCESS rtx macro not defined, we need to get this via own-set architecture macros 00028 #ifndef MBED_EXCLUSIVE_ACCESS 00029 #ifndef __EXCLUSIVE_ACCESS 00030 #if ((__ARM_ARCH_7M__ == 1U) || \ 00031 (__ARM_ARCH_7EM__ == 1U) || \ 00032 (__ARM_ARCH_8M_BASE__ == 1U) || \ 00033 (__ARM_ARCH_8M_MAIN__ == 1U)) || \ 00034 (__ARM_ARCH_7A__ == 1U) 00035 #define MBED_EXCLUSIVE_ACCESS 1U 00036 #elif (__ARM_ARCH_6M__ == 1U) 00037 #define MBED_EXCLUSIVE_ACCESS 0U 00038 #else 00039 #error "Unknown architecture for exclusive access" 00040 #endif 00041 #else 00042 #define MBED_EXCLUSIVE_ACCESS __EXCLUSIVE_ACCESS 00043 #endif 00044 #endif 00045 00046 static volatile uint32_t critical_section_reentrancy_counter = 0; 00047 00048 bool core_util_are_interrupts_enabled(void) 00049 { 00050 #if defined(__CORTEX_A9) 00051 return ((__get_CPSR() & 0x80) == 0); 00052 #else 00053 return ((__get_PRIMASK() & 0x1) == 0); 00054 #endif 00055 } 00056 00057 bool core_util_is_isr_active(void) 00058 { 00059 #if defined(__CORTEX_A9) 00060 switch (__get_CPSR() & 0x1FU) { 00061 case CPSR_M_USR: 00062 case CPSR_M_SYS: 00063 return false; 00064 case CPSR_M_SVC: 00065 default: 00066 return true; 00067 } 00068 #else 00069 return (__get_IPSR() != 0U); 00070 #endif 00071 } 00072 00073 bool core_util_in_critical_section(void) 00074 { 00075 return hal_in_critical_section(); 00076 } 00077 00078 void core_util_critical_section_enter(void) 00079 { 00080 // If the reentrancy counter overflows something has gone badly wrong. 00081 MBED_ASSERT(critical_section_reentrancy_counter < UINT32_MAX); 00082 00083 hal_critical_section_enter(); 00084 00085 ++critical_section_reentrancy_counter; 00086 } 00087 00088 void core_util_critical_section_exit(void) 00089 { 00090 00091 // If critical_section_enter has not previously been called, do nothing 00092 if (critical_section_reentrancy_counter == 0) { 00093 return; 00094 } 00095 00096 --critical_section_reentrancy_counter; 00097 00098 if (critical_section_reentrancy_counter == 0) { 00099 hal_critical_section_exit(); 00100 } 00101 } 00102 00103 void core_util_atomic_flag_clear(volatile core_util_atomic_flag *flagPtr) 00104 { 00105 flagPtr->_flag = false; 00106 } 00107 00108 #if MBED_EXCLUSIVE_ACCESS 00109 00110 /* Supress __ldrex and __strex deprecated warnings - "#3731-D: intrinsic is deprecated" */ 00111 #if defined (__CC_ARM) 00112 #pragma diag_suppress 3731 00113 #endif 00114 00115 bool core_util_atomic_flag_test_and_set(volatile core_util_atomic_flag *flagPtr) 00116 { 00117 uint8_t currentValue; 00118 do { 00119 currentValue = __LDREXB(&flagPtr->_flag); 00120 } while (__STREXB(true, &flagPtr->_flag)); 00121 return currentValue; 00122 } 00123 00124 bool core_util_atomic_cas_u8(volatile uint8_t *ptr, uint8_t *expectedCurrentValue, uint8_t desiredValue) 00125 { 00126 do { 00127 uint8_t currentValue = __LDREXB(ptr); 00128 if (currentValue != *expectedCurrentValue) { 00129 *expectedCurrentValue = currentValue; 00130 __CLREX(); 00131 return false; 00132 } 00133 } while (__STREXB(desiredValue, ptr)); 00134 return true; 00135 } 00136 00137 bool core_util_atomic_cas_u16(volatile uint16_t *ptr, uint16_t *expectedCurrentValue, uint16_t desiredValue) 00138 { 00139 do { 00140 uint16_t currentValue = __LDREXH(ptr); 00141 if (currentValue != *expectedCurrentValue) { 00142 *expectedCurrentValue = currentValue; 00143 __CLREX(); 00144 return false; 00145 } 00146 } while (__STREXH(desiredValue, ptr)); 00147 return true; 00148 } 00149 00150 00151 bool core_util_atomic_cas_u32(volatile uint32_t *ptr, uint32_t *expectedCurrentValue, uint32_t desiredValue) 00152 { 00153 do { 00154 uint32_t currentValue = __LDREXW(ptr); 00155 if (currentValue != *expectedCurrentValue) { 00156 *expectedCurrentValue = currentValue; 00157 __CLREX(); 00158 return false; 00159 } 00160 } while (__STREXW(desiredValue, ptr)); 00161 return true; 00162 } 00163 00164 uint8_t core_util_atomic_incr_u8(volatile uint8_t *valuePtr, uint8_t delta) 00165 { 00166 uint8_t newValue; 00167 do { 00168 newValue = __LDREXB(valuePtr) + delta; 00169 } while (__STREXB(newValue, valuePtr)); 00170 return newValue; 00171 } 00172 00173 uint16_t core_util_atomic_incr_u16(volatile uint16_t *valuePtr, uint16_t delta) 00174 { 00175 uint16_t newValue; 00176 do { 00177 newValue = __LDREXH(valuePtr) + delta; 00178 } while (__STREXH(newValue, valuePtr)); 00179 return newValue; 00180 } 00181 00182 uint32_t core_util_atomic_incr_u32(volatile uint32_t *valuePtr, uint32_t delta) 00183 { 00184 uint32_t newValue; 00185 do { 00186 newValue = __LDREXW(valuePtr) + delta; 00187 } while (__STREXW(newValue, valuePtr)); 00188 return newValue; 00189 } 00190 00191 00192 uint8_t core_util_atomic_decr_u8(volatile uint8_t *valuePtr, uint8_t delta) 00193 { 00194 uint8_t newValue; 00195 do { 00196 newValue = __LDREXB(valuePtr) - delta; 00197 } while (__STREXB(newValue, valuePtr)); 00198 return newValue; 00199 } 00200 00201 uint16_t core_util_atomic_decr_u16(volatile uint16_t *valuePtr, uint16_t delta) 00202 { 00203 uint16_t newValue; 00204 do { 00205 newValue = __LDREXH(valuePtr) - delta; 00206 } while (__STREXH(newValue, valuePtr)); 00207 return newValue; 00208 } 00209 00210 uint32_t core_util_atomic_decr_u32(volatile uint32_t *valuePtr, uint32_t delta) 00211 { 00212 uint32_t newValue; 00213 do { 00214 newValue = __LDREXW(valuePtr) - delta; 00215 } while (__STREXW(newValue, valuePtr)); 00216 return newValue; 00217 } 00218 00219 #else 00220 00221 bool core_util_atomic_flag_test_and_set(volatile core_util_atomic_flag *flagPtr) 00222 { 00223 core_util_critical_section_enter(); 00224 uint8_t currentValue = flagPtr->_flag; 00225 flagPtr->_flag = true; 00226 core_util_critical_section_exit(); 00227 return currentValue; 00228 } 00229 00230 bool core_util_atomic_cas_u8(volatile uint8_t *ptr, uint8_t *expectedCurrentValue, uint8_t desiredValue) 00231 { 00232 bool success; 00233 uint8_t currentValue; 00234 core_util_critical_section_enter(); 00235 currentValue = *ptr; 00236 if (currentValue == *expectedCurrentValue) { 00237 *ptr = desiredValue; 00238 success = true; 00239 } else { 00240 *expectedCurrentValue = currentValue; 00241 success = false; 00242 } 00243 core_util_critical_section_exit(); 00244 return success; 00245 } 00246 00247 bool core_util_atomic_cas_u16(volatile uint16_t *ptr, uint16_t *expectedCurrentValue, uint16_t desiredValue) 00248 { 00249 bool success; 00250 uint16_t currentValue; 00251 core_util_critical_section_enter(); 00252 currentValue = *ptr; 00253 if (currentValue == *expectedCurrentValue) { 00254 *ptr = desiredValue; 00255 success = true; 00256 } else { 00257 *expectedCurrentValue = currentValue; 00258 success = false; 00259 } 00260 core_util_critical_section_exit(); 00261 return success; 00262 } 00263 00264 00265 bool core_util_atomic_cas_u32(volatile uint32_t *ptr, uint32_t *expectedCurrentValue, uint32_t desiredValue) 00266 { 00267 bool success; 00268 uint32_t currentValue; 00269 core_util_critical_section_enter(); 00270 currentValue = *ptr; 00271 if (currentValue == *expectedCurrentValue) { 00272 *ptr = desiredValue; 00273 success = true; 00274 } else { 00275 *expectedCurrentValue = currentValue; 00276 success = false; 00277 } 00278 core_util_critical_section_exit(); 00279 return success; 00280 } 00281 00282 00283 uint8_t core_util_atomic_incr_u8(volatile uint8_t *valuePtr, uint8_t delta) 00284 { 00285 uint8_t newValue; 00286 core_util_critical_section_enter(); 00287 newValue = *valuePtr + delta; 00288 *valuePtr = newValue; 00289 core_util_critical_section_exit(); 00290 return newValue; 00291 } 00292 00293 uint16_t core_util_atomic_incr_u16(volatile uint16_t *valuePtr, uint16_t delta) 00294 { 00295 uint16_t newValue; 00296 core_util_critical_section_enter(); 00297 newValue = *valuePtr + delta; 00298 *valuePtr = newValue; 00299 core_util_critical_section_exit(); 00300 return newValue; 00301 } 00302 00303 uint32_t core_util_atomic_incr_u32(volatile uint32_t *valuePtr, uint32_t delta) 00304 { 00305 uint32_t newValue; 00306 core_util_critical_section_enter(); 00307 newValue = *valuePtr + delta; 00308 *valuePtr = newValue; 00309 core_util_critical_section_exit(); 00310 return newValue; 00311 } 00312 00313 00314 uint8_t core_util_atomic_decr_u8(volatile uint8_t *valuePtr, uint8_t delta) 00315 { 00316 uint8_t newValue; 00317 core_util_critical_section_enter(); 00318 newValue = *valuePtr - delta; 00319 *valuePtr = newValue; 00320 core_util_critical_section_exit(); 00321 return newValue; 00322 } 00323 00324 uint16_t core_util_atomic_decr_u16(volatile uint16_t *valuePtr, uint16_t delta) 00325 { 00326 uint16_t newValue; 00327 core_util_critical_section_enter(); 00328 newValue = *valuePtr - delta; 00329 *valuePtr = newValue; 00330 core_util_critical_section_exit(); 00331 return newValue; 00332 } 00333 00334 uint32_t core_util_atomic_decr_u32(volatile uint32_t *valuePtr, uint32_t delta) 00335 { 00336 uint32_t newValue; 00337 core_util_critical_section_enter(); 00338 newValue = *valuePtr - delta; 00339 *valuePtr = newValue; 00340 core_util_critical_section_exit(); 00341 return newValue; 00342 } 00343 00344 #endif 00345 00346 00347 bool core_util_atomic_cas_ptr(void *volatile *ptr, void **expectedCurrentValue, void *desiredValue) 00348 { 00349 return core_util_atomic_cas_u32( 00350 (volatile uint32_t *)ptr, 00351 (uint32_t *)expectedCurrentValue, 00352 (uint32_t)desiredValue); 00353 } 00354 00355 void *core_util_atomic_incr_ptr(void *volatile *valuePtr, ptrdiff_t delta) 00356 { 00357 return (void *)core_util_atomic_incr_u32((volatile uint32_t *)valuePtr, (uint32_t)delta); 00358 } 00359 00360 void *core_util_atomic_decr_ptr(void *volatile *valuePtr, ptrdiff_t delta) 00361 { 00362 return (void *)core_util_atomic_decr_u32((volatile uint32_t *)valuePtr, (uint32_t)delta); 00363 } 00364
Generated on Tue Jul 12 2022 20:41:15 by 1.7.2