Marco Zecchini
/
Example_RTOS
Rtos API example
Embed:
(wiki syntax)
Show/hide line numbers
mbed_critical.h
00001 00002 /* 00003 * Copyright (c) 2015-2016, ARM Limited, All Rights Reserved 00004 * SPDX-License-Identifier: Apache-2.0 00005 * 00006 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00007 * not use this file except in compliance with the License. 00008 * You may obtain a copy of the License at 00009 * 00010 * http://www.apache.org/licenses/LICENSE-2.0 00011 * 00012 * Unless required by applicable law or agreed to in writing, software 00013 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00014 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00015 * See the License for the specific language governing permissions and 00016 * limitations under the License. 00017 */ 00018 00019 #ifndef __MBED_UTIL_CRITICAL_H__ 00020 #define __MBED_UTIL_CRITICAL_H__ 00021 00022 #include <stdbool.h> 00023 #include <stdint.h> 00024 #include <stddef.h> 00025 00026 #ifdef __cplusplus 00027 extern "C" { 00028 #endif 00029 00030 /** \addtogroup platform */ 00031 /** @{*/ 00032 /** 00033 * \defgroup platform_critical critical section function 00034 * @{ 00035 */ 00036 00037 /** Determine the current interrupts enabled state 00038 * 00039 * This function can be called to determine whether or not interrupts are currently enabled. 00040 * @note 00041 * NOTE: 00042 * This function works for both cortex-A and cortex-M, although the underlyng implementation 00043 * differs. 00044 * @return true if interrupts are enabled, false otherwise 00045 */ 00046 bool core_util_are_interrupts_enabled(void); 00047 00048 /** Determine if this code is executing from an interrupt 00049 * 00050 * This function can be called to determine if the code is running on interrupt context. 00051 * @note 00052 * NOTE: 00053 * This function works for both cortex-A and cortex-M, although the underlyng implementation 00054 * differs. 00055 * @return true if in an isr, false otherwise 00056 */ 00057 bool core_util_is_isr_active(void); 00058 00059 /** Mark the start of a critical section 00060 * 00061 * This function should be called to mark the start of a critical section of code. 00062 * @note 00063 * NOTES: 00064 * 1) The use of this style of critical section is targetted at C based implementations. 00065 * 2) These critical sections can be nested. 00066 * 3) The interrupt enable state on entry to the first critical section (of a nested set, or single 00067 * section) will be preserved on exit from the section. 00068 * 4) This implementation will currently only work on code running in privileged mode. 00069 */ 00070 void core_util_critical_section_enter(void); 00071 00072 /** Mark the end of a critical section 00073 * 00074 * This function should be called to mark the end of a critical section of code. 00075 * @note 00076 * NOTES: 00077 * 1) The use of this style of critical section is targetted at C based implementations. 00078 * 2) These critical sections can be nested. 00079 * 3) The interrupt enable state on entry to the first critical section (of a nested set, or single 00080 * section) will be preserved on exit from the section. 00081 * 4) This implementation will currently only work on code running in privileged mode. 00082 */ 00083 void core_util_critical_section_exit(void); 00084 00085 /** 00086 * Atomic compare and set. It compares the contents of a memory location to a 00087 * given value and, only if they are the same, modifies the contents of that 00088 * memory location to a given new value. This is done as a single atomic 00089 * operation. The atomicity guarantees that the new value is calculated based on 00090 * up-to-date information; if the value had been updated by another thread in 00091 * the meantime, the write would fail due to a mismatched expectedCurrentValue. 00092 * 00093 * Refer to https://en.wikipedia.org/wiki/Compare-and-set [which may redirect 00094 * you to the article on compare-and swap]. 00095 * 00096 * @param ptr The target memory location. 00097 * @param[in,out] expectedCurrentValue A pointer to some location holding the 00098 * expected current value of the data being set atomically. 00099 * The computed 'desiredValue' should be a function of this current value. 00100 * @note: This is an in-out parameter. In the 00101 * failure case of atomic_cas (where the 00102 * destination isn't set), the pointee of expectedCurrentValue is 00103 * updated with the current value. 00104 * @param[in] desiredValue The new value computed based on '*expectedCurrentValue'. 00105 * 00106 * @return true if the memory location was atomically 00107 * updated with the desired value (after verifying 00108 * that it contained the expectedCurrentValue), 00109 * false otherwise. In the failure case, 00110 * exepctedCurrentValue is updated with the new 00111 * value of the target memory location. 00112 * 00113 * pseudocode: 00114 * function cas(p : pointer to int, old : pointer to int, new : int) returns bool { 00115 * if *p != *old { 00116 * *old = *p 00117 * return false 00118 * } 00119 * *p = new 00120 * return true 00121 * } 00122 * 00123 * @note: In the failure case (where the destination isn't set), the value 00124 * pointed to by expectedCurrentValue is still updated with the current value. 00125 * This property helps writing concise code for the following incr: 00126 * 00127 * function incr(p : pointer to int, a : int) returns int { 00128 * done = false 00129 * value = *p // This fetch operation need not be atomic. 00130 * while not done { 00131 * done = atomic_cas(p, &value, value + a) // *value gets updated automatically until success 00132 * } 00133 * return value + a 00134 * } 00135 */ 00136 bool core_util_atomic_cas_u8(uint8_t *ptr, uint8_t *expectedCurrentValue, uint8_t desiredValue); 00137 00138 /** 00139 * Atomic compare and set. It compares the contents of a memory location to a 00140 * given value and, only if they are the same, modifies the contents of that 00141 * memory location to a given new value. This is done as a single atomic 00142 * operation. The atomicity guarantees that the new value is calculated based on 00143 * up-to-date information; if the value had been updated by another thread in 00144 * the meantime, the write would fail due to a mismatched expectedCurrentValue. 00145 * 00146 * Refer to https://en.wikipedia.org/wiki/Compare-and-set [which may redirect 00147 * you to the article on compare-and swap]. 00148 * 00149 * @param ptr The target memory location. 00150 * @param[in,out] expectedCurrentValue A pointer to some location holding the 00151 * expected current value of the data being set atomically. 00152 * The computed 'desiredValue' should be a function of this current value. 00153 * @note: This is an in-out parameter. In the 00154 * failure case of atomic_cas (where the 00155 * destination isn't set), the pointee of expectedCurrentValue is 00156 * updated with the current value. 00157 * @param[in] desiredValue The new value computed based on '*expectedCurrentValue'. 00158 * 00159 * @return true if the memory location was atomically 00160 * updated with the desired value (after verifying 00161 * that it contained the expectedCurrentValue), 00162 * false otherwise. In the failure case, 00163 * exepctedCurrentValue is updated with the new 00164 * value of the target memory location. 00165 * 00166 * pseudocode: 00167 * function cas(p : pointer to int, old : pointer to int, new : int) returns bool { 00168 * if *p != *old { 00169 * *old = *p 00170 * return false 00171 * } 00172 * *p = new 00173 * return true 00174 * } 00175 * 00176 * @note: In the failure case (where the destination isn't set), the value 00177 * pointed to by expectedCurrentValue is still updated with the current value. 00178 * This property helps writing concise code for the following incr: 00179 * 00180 * function incr(p : pointer to int, a : int) returns int { 00181 * done = false 00182 * value = *p // This fetch operation need not be atomic. 00183 * while not done { 00184 * done = atomic_cas(p, &value, value + a) // *value gets updated automatically until success 00185 * } 00186 * return value + a 00187 * } 00188 */ 00189 bool core_util_atomic_cas_u16(uint16_t *ptr, uint16_t *expectedCurrentValue, uint16_t desiredValue); 00190 00191 /** 00192 * Atomic compare and set. It compares the contents of a memory location to a 00193 * given value and, only if they are the same, modifies the contents of that 00194 * memory location to a given new value. This is done as a single atomic 00195 * operation. The atomicity guarantees that the new value is calculated based on 00196 * up-to-date information; if the value had been updated by another thread in 00197 * the meantime, the write would fail due to a mismatched expectedCurrentValue. 00198 * 00199 * Refer to https://en.wikipedia.org/wiki/Compare-and-set [which may redirect 00200 * you to the article on compare-and swap]. 00201 * 00202 * @param ptr The target memory location. 00203 * @param[in,out] expectedCurrentValue A pointer to some location holding the 00204 * expected current value of the data being set atomically. 00205 * The computed 'desiredValue' should be a function of this current value. 00206 * @note: This is an in-out parameter. In the 00207 * failure case of atomic_cas (where the 00208 * destination isn't set), the pointee of expectedCurrentValue is 00209 * updated with the current value. 00210 * @param[in] desiredValue The new value computed based on '*expectedCurrentValue'. 00211 * 00212 * @return true if the memory location was atomically 00213 * updated with the desired value (after verifying 00214 * that it contained the expectedCurrentValue), 00215 * false otherwise. In the failure case, 00216 * exepctedCurrentValue is updated with the new 00217 * value of the target memory location. 00218 * 00219 * pseudocode: 00220 * function cas(p : pointer to int, old : pointer to int, new : int) returns bool { 00221 * if *p != *old { 00222 * *old = *p 00223 * return false 00224 * } 00225 * *p = new 00226 * return true 00227 * } 00228 * 00229 * @note: In the failure case (where the destination isn't set), the value 00230 * pointed to by expectedCurrentValue is still updated with the current value. 00231 * This property helps writing concise code for the following incr: 00232 * 00233 * function incr(p : pointer to int, a : int) returns int { 00234 * done = false 00235 * value = *p // This fetch operation need not be atomic. 00236 * while not done { 00237 * done = atomic_cas(p, &value, value + a) // *value gets updated automatically until success 00238 * } 00239 * return value + a 00240 * } 00241 */ 00242 bool core_util_atomic_cas_u32(uint32_t *ptr, uint32_t *expectedCurrentValue, uint32_t desiredValue); 00243 00244 /** 00245 * Atomic compare and set. It compares the contents of a memory location to a 00246 * given value and, only if they are the same, modifies the contents of that 00247 * memory location to a given new value. This is done as a single atomic 00248 * operation. The atomicity guarantees that the new value is calculated based on 00249 * up-to-date information; if the value had been updated by another thread in 00250 * the meantime, the write would fail due to a mismatched expectedCurrentValue. 00251 * 00252 * Refer to https://en.wikipedia.org/wiki/Compare-and-set [which may redirect 00253 * you to the article on compare-and swap]. 00254 * 00255 * @param ptr The target memory location. 00256 * @param[in,out] expectedCurrentValue A pointer to some location holding the 00257 * expected current value of the data being set atomically. 00258 * The computed 'desiredValue' should be a function of this current value. 00259 * @note: This is an in-out parameter. In the 00260 * failure case of atomic_cas (where the 00261 * destination isn't set), the pointee of expectedCurrentValue is 00262 * updated with the current value. 00263 * @param[in] desiredValue The new value computed based on '*expectedCurrentValue'. 00264 * 00265 * @return true if the memory location was atomically 00266 * updated with the desired value (after verifying 00267 * that it contained the expectedCurrentValue), 00268 * false otherwise. In the failure case, 00269 * exepctedCurrentValue is updated with the new 00270 * value of the target memory location. 00271 * 00272 * pseudocode: 00273 * function cas(p : pointer to int, old : pointer to int, new : int) returns bool { 00274 * if *p != *old { 00275 * *old = *p 00276 * return false 00277 * } 00278 * *p = new 00279 * return true 00280 * } 00281 * 00282 * @note: In the failure case (where the destination isn't set), the value 00283 * pointed to by expectedCurrentValue is still updated with the current value. 00284 * This property helps writing concise code for the following incr: 00285 * 00286 * function incr(p : pointer to int, a : int) returns int { 00287 * done = false 00288 * value = *p // This fetch operation need not be atomic. 00289 * while not done { 00290 * done = atomic_cas(p, &value, value + a) // *value gets updated automatically until success 00291 * } 00292 * return value + a 00293 * } 00294 */ 00295 bool core_util_atomic_cas_ptr(void **ptr, void **expectedCurrentValue, void *desiredValue); 00296 00297 /** 00298 * Atomic increment. 00299 * @param valuePtr Target memory location being incremented. 00300 * @param delta The amount being incremented. 00301 * @return The new incremented value. 00302 */ 00303 uint8_t core_util_atomic_incr_u8(uint8_t *valuePtr, uint8_t delta); 00304 00305 /** 00306 * Atomic increment. 00307 * @param valuePtr Target memory location being incremented. 00308 * @param delta The amount being incremented. 00309 * @return The new incremented value. 00310 */ 00311 uint16_t core_util_atomic_incr_u16(uint16_t *valuePtr, uint16_t delta); 00312 00313 /** 00314 * Atomic increment. 00315 * @param valuePtr Target memory location being incremented. 00316 * @param delta The amount being incremented. 00317 * @return The new incremented value. 00318 */ 00319 uint32_t core_util_atomic_incr_u32(uint32_t *valuePtr, uint32_t delta); 00320 00321 /** 00322 * Atomic increment. 00323 * @param valuePtr Target memory location being incremented. 00324 * @param delta The amount being incremented in bytes. 00325 * @return The new incremented value. 00326 * 00327 * @note The type of the pointer argument is not taken into account 00328 * and the pointer is incremented by bytes. 00329 */ 00330 void *core_util_atomic_incr_ptr(void **valuePtr, ptrdiff_t delta); 00331 00332 /** 00333 * Atomic decrement. 00334 * @param valuePtr Target memory location being decremented. 00335 * @param delta The amount being decremented. 00336 * @return The new decremented value. 00337 */ 00338 uint8_t core_util_atomic_decr_u8(uint8_t *valuePtr, uint8_t delta); 00339 00340 /** 00341 * Atomic decrement. 00342 * @param valuePtr Target memory location being decremented. 00343 * @param delta The amount being decremented. 00344 * @return The new decremented value. 00345 */ 00346 uint16_t core_util_atomic_decr_u16(uint16_t *valuePtr, uint16_t delta); 00347 00348 /** 00349 * Atomic decrement. 00350 * @param valuePtr Target memory location being decremented. 00351 * @param delta The amount being decremented. 00352 * @return The new decremented value. 00353 */ 00354 uint32_t core_util_atomic_decr_u32(uint32_t *valuePtr, uint32_t delta); 00355 00356 /** 00357 * Atomic decrement. 00358 * @param valuePtr Target memory location being decremented. 00359 * @param delta The amount being decremented in bytes. 00360 * @return The new decremented value. 00361 * 00362 * @note The type of the pointer argument is not taken into account 00363 * and the pointer is decremented by bytes 00364 */ 00365 void *core_util_atomic_decr_ptr(void **valuePtr, ptrdiff_t delta); 00366 00367 #ifdef __cplusplus 00368 } // extern "C" 00369 #endif 00370 /**@}*/ 00371 00372 /**@}*/ 00373 00374 #endif // __MBED_UTIL_CRITICAL_H__ 00375 00376 00377
Generated on Sun Jul 17 2022 08:25:27 by 1.7.2