mbed-os for GR-LYCHEE

Dependents:   mbed-os-example-blinky-gr-lychee GR-Boads_Camera_sample GR-Boards_Audio_Recoder GR-Boads_Camera_DisplayApp ... more

Committer:
dkato
Date:
Fri Feb 02 05:42:23 2018 +0000
Revision:
0:f782d9c66c49
mbed-os for GR-LYCHEE

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dkato 0:f782d9c66c49 1 /*
dkato 0:f782d9c66c49 2 * Copyright (c) 2015-2016, ARM Limited, All Rights Reserved
dkato 0:f782d9c66c49 3 * SPDX-License-Identifier: Apache-2.0
dkato 0:f782d9c66c49 4 *
dkato 0:f782d9c66c49 5 * Licensed under the Apache License, Version 2.0 (the "License"); you may
dkato 0:f782d9c66c49 6 * not use this file except in compliance with the License.
dkato 0:f782d9c66c49 7 * You may obtain a copy of the License at
dkato 0:f782d9c66c49 8 *
dkato 0:f782d9c66c49 9 * http://www.apache.org/licenses/LICENSE-2.0
dkato 0:f782d9c66c49 10 *
dkato 0:f782d9c66c49 11 * Unless required by applicable law or agreed to in writing, software
dkato 0:f782d9c66c49 12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
dkato 0:f782d9c66c49 13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
dkato 0:f782d9c66c49 14 * See the License for the specific language governing permissions and
dkato 0:f782d9c66c49 15 * limitations under the License.
dkato 0:f782d9c66c49 16 */
dkato 0:f782d9c66c49 17
dkato 0:f782d9c66c49 18 /* Declare __STDC_LIMIT_MACROS so stdint.h defines UINT32_MAX when using C++ */
dkato 0:f782d9c66c49 19 #define __STDC_LIMIT_MACROS
dkato 0:f782d9c66c49 20 #include "platform/mbed_critical.h"
dkato 0:f782d9c66c49 21
dkato 0:f782d9c66c49 22 #include "cmsis.h"
dkato 0:f782d9c66c49 23 #include "platform/mbed_assert.h"
dkato 0:f782d9c66c49 24 #include "platform/mbed_toolchain.h"
dkato 0:f782d9c66c49 25
dkato 0:f782d9c66c49 26 #define EXCLUSIVE_ACCESS (!defined (__CORTEX_M0) && !defined (__CORTEX_M0PLUS))
dkato 0:f782d9c66c49 27
dkato 0:f782d9c66c49 28 static volatile uint32_t interrupt_enable_counter = 0;
dkato 0:f782d9c66c49 29 static volatile bool critical_interrupts_disabled = false;
dkato 0:f782d9c66c49 30
dkato 0:f782d9c66c49 31 bool core_util_are_interrupts_enabled(void)
dkato 0:f782d9c66c49 32 {
dkato 0:f782d9c66c49 33 #if defined(__CORTEX_A9)
dkato 0:f782d9c66c49 34 return ((__get_CPSR() & 0x80) == 0);
dkato 0:f782d9c66c49 35 #else
dkato 0:f782d9c66c49 36 return ((__get_PRIMASK() & 0x1) == 0);
dkato 0:f782d9c66c49 37 #endif
dkato 0:f782d9c66c49 38 }
dkato 0:f782d9c66c49 39
dkato 0:f782d9c66c49 40 MBED_WEAK void core_util_critical_section_enter(void)
dkato 0:f782d9c66c49 41 {
dkato 0:f782d9c66c49 42 bool interrupts_disabled = !core_util_are_interrupts_enabled();
dkato 0:f782d9c66c49 43 __disable_irq();
dkato 0:f782d9c66c49 44
dkato 0:f782d9c66c49 45 /* Save the interrupt disabled state as it was prior to any nested critical section lock use */
dkato 0:f782d9c66c49 46 if (!interrupt_enable_counter) {
dkato 0:f782d9c66c49 47 critical_interrupts_disabled = interrupts_disabled;
dkato 0:f782d9c66c49 48 }
dkato 0:f782d9c66c49 49
dkato 0:f782d9c66c49 50 /* If the interrupt_enable_counter overflows or we are in a nested critical section and interrupts
dkato 0:f782d9c66c49 51 are enabled, then something has gone badly wrong thus assert an error.
dkato 0:f782d9c66c49 52 */
dkato 0:f782d9c66c49 53 MBED_ASSERT(interrupt_enable_counter < UINT32_MAX);
dkato 0:f782d9c66c49 54 // FIXME
dkato 0:f782d9c66c49 55 #ifndef FEATURE_UVISOR
dkato 0:f782d9c66c49 56 if (interrupt_enable_counter > 0) {
dkato 0:f782d9c66c49 57 MBED_ASSERT(interrupts_disabled);
dkato 0:f782d9c66c49 58 }
dkato 0:f782d9c66c49 59 #else
dkato 0:f782d9c66c49 60 #warning "core_util_critical_section_enter needs fixing to work from unprivileged code"
dkato 0:f782d9c66c49 61 #endif /* FEATURE_UVISOR */
dkato 0:f782d9c66c49 62 interrupt_enable_counter++;
dkato 0:f782d9c66c49 63 }
dkato 0:f782d9c66c49 64
dkato 0:f782d9c66c49 65 MBED_WEAK void core_util_critical_section_exit(void)
dkato 0:f782d9c66c49 66 {
dkato 0:f782d9c66c49 67 /* If critical_section_enter has not previously been called, do nothing */
dkato 0:f782d9c66c49 68 if (interrupt_enable_counter) {
dkato 0:f782d9c66c49 69
dkato 0:f782d9c66c49 70 // FIXME
dkato 0:f782d9c66c49 71 #ifndef FEATURE_UVISOR
dkato 0:f782d9c66c49 72 bool interrupts_disabled = !core_util_are_interrupts_enabled(); /* get the current interrupt disabled state */
dkato 0:f782d9c66c49 73
dkato 0:f782d9c66c49 74 MBED_ASSERT(interrupts_disabled); /* Interrupts must be disabled on invoking an exit from a critical section */
dkato 0:f782d9c66c49 75 #else
dkato 0:f782d9c66c49 76 #warning "core_util_critical_section_exit needs fixing to work from unprivileged code"
dkato 0:f782d9c66c49 77 #endif /* FEATURE_UVISOR */
dkato 0:f782d9c66c49 78
dkato 0:f782d9c66c49 79 interrupt_enable_counter--;
dkato 0:f782d9c66c49 80
dkato 0:f782d9c66c49 81 /* Only re-enable interrupts if we are exiting the last of the nested critical sections and
dkato 0:f782d9c66c49 82 interrupts were enabled on entry to the first critical section.
dkato 0:f782d9c66c49 83 */
dkato 0:f782d9c66c49 84 if (!interrupt_enable_counter && !critical_interrupts_disabled) {
dkato 0:f782d9c66c49 85 __enable_irq();
dkato 0:f782d9c66c49 86 }
dkato 0:f782d9c66c49 87 }
dkato 0:f782d9c66c49 88 }
dkato 0:f782d9c66c49 89
dkato 0:f782d9c66c49 90 #if EXCLUSIVE_ACCESS
dkato 0:f782d9c66c49 91
dkato 0:f782d9c66c49 92 /* Supress __ldrex and __strex deprecated warnings - "#3731-D: intrinsic is deprecated" */
dkato 0:f782d9c66c49 93 #if defined (__CC_ARM)
dkato 0:f782d9c66c49 94 #pragma diag_suppress 3731
dkato 0:f782d9c66c49 95 #endif
dkato 0:f782d9c66c49 96
dkato 0:f782d9c66c49 97 bool core_util_atomic_cas_u8(uint8_t *ptr, uint8_t *expectedCurrentValue, uint8_t desiredValue)
dkato 0:f782d9c66c49 98 {
dkato 0:f782d9c66c49 99 uint8_t currentValue = __LDREXB((volatile uint8_t*)ptr);
dkato 0:f782d9c66c49 100 if (currentValue != *expectedCurrentValue) {
dkato 0:f782d9c66c49 101 *expectedCurrentValue = currentValue;
dkato 0:f782d9c66c49 102 __CLREX();
dkato 0:f782d9c66c49 103 return false;
dkato 0:f782d9c66c49 104 }
dkato 0:f782d9c66c49 105
dkato 0:f782d9c66c49 106 return !__STREXB(desiredValue, (volatile uint8_t*)ptr);
dkato 0:f782d9c66c49 107 }
dkato 0:f782d9c66c49 108
dkato 0:f782d9c66c49 109 bool core_util_atomic_cas_u16(uint16_t *ptr, uint16_t *expectedCurrentValue, uint16_t desiredValue)
dkato 0:f782d9c66c49 110 {
dkato 0:f782d9c66c49 111 uint16_t currentValue = __LDREXH((volatile uint16_t*)ptr);
dkato 0:f782d9c66c49 112 if (currentValue != *expectedCurrentValue) {
dkato 0:f782d9c66c49 113 *expectedCurrentValue = currentValue;
dkato 0:f782d9c66c49 114 __CLREX();
dkato 0:f782d9c66c49 115 return false;
dkato 0:f782d9c66c49 116 }
dkato 0:f782d9c66c49 117
dkato 0:f782d9c66c49 118 return !__STREXH(desiredValue, (volatile uint16_t*)ptr);
dkato 0:f782d9c66c49 119 }
dkato 0:f782d9c66c49 120
dkato 0:f782d9c66c49 121
dkato 0:f782d9c66c49 122 bool core_util_atomic_cas_u32(uint32_t *ptr, uint32_t *expectedCurrentValue, uint32_t desiredValue)
dkato 0:f782d9c66c49 123 {
dkato 0:f782d9c66c49 124 uint32_t currentValue = __LDREXW((volatile uint32_t*)ptr);
dkato 0:f782d9c66c49 125 if (currentValue != *expectedCurrentValue) {
dkato 0:f782d9c66c49 126 *expectedCurrentValue = currentValue;
dkato 0:f782d9c66c49 127 __CLREX();
dkato 0:f782d9c66c49 128 return false;
dkato 0:f782d9c66c49 129 }
dkato 0:f782d9c66c49 130
dkato 0:f782d9c66c49 131 return !__STREXW(desiredValue, (volatile uint32_t*)ptr);
dkato 0:f782d9c66c49 132 }
dkato 0:f782d9c66c49 133
dkato 0:f782d9c66c49 134 uint8_t core_util_atomic_incr_u8(uint8_t *valuePtr, uint8_t delta)
dkato 0:f782d9c66c49 135 {
dkato 0:f782d9c66c49 136 uint8_t newValue;
dkato 0:f782d9c66c49 137 do {
dkato 0:f782d9c66c49 138 newValue = __LDREXB((volatile uint8_t*)valuePtr) + delta;
dkato 0:f782d9c66c49 139 } while (__STREXB(newValue, (volatile uint8_t*)valuePtr));
dkato 0:f782d9c66c49 140 return newValue;
dkato 0:f782d9c66c49 141 }
dkato 0:f782d9c66c49 142
dkato 0:f782d9c66c49 143 uint16_t core_util_atomic_incr_u16(uint16_t *valuePtr, uint16_t delta)
dkato 0:f782d9c66c49 144 {
dkato 0:f782d9c66c49 145 uint16_t newValue;
dkato 0:f782d9c66c49 146 do {
dkato 0:f782d9c66c49 147 newValue = __LDREXH((volatile uint16_t*)valuePtr) + delta;
dkato 0:f782d9c66c49 148 } while (__STREXH(newValue, (volatile uint16_t*)valuePtr));
dkato 0:f782d9c66c49 149 return newValue;
dkato 0:f782d9c66c49 150 }
dkato 0:f782d9c66c49 151
dkato 0:f782d9c66c49 152 uint32_t core_util_atomic_incr_u32(uint32_t *valuePtr, uint32_t delta)
dkato 0:f782d9c66c49 153 {
dkato 0:f782d9c66c49 154 uint32_t newValue;
dkato 0:f782d9c66c49 155 do {
dkato 0:f782d9c66c49 156 newValue = __LDREXW((volatile uint32_t*)valuePtr) + delta;
dkato 0:f782d9c66c49 157 } while (__STREXW(newValue, (volatile uint32_t*)valuePtr));
dkato 0:f782d9c66c49 158 return newValue;
dkato 0:f782d9c66c49 159 }
dkato 0:f782d9c66c49 160
dkato 0:f782d9c66c49 161
dkato 0:f782d9c66c49 162 uint8_t core_util_atomic_decr_u8(uint8_t *valuePtr, uint8_t delta)
dkato 0:f782d9c66c49 163 {
dkato 0:f782d9c66c49 164 uint8_t newValue;
dkato 0:f782d9c66c49 165 do {
dkato 0:f782d9c66c49 166 newValue = __LDREXB((volatile uint8_t*)valuePtr) - delta;
dkato 0:f782d9c66c49 167 } while (__STREXB(newValue, (volatile uint8_t*)valuePtr));
dkato 0:f782d9c66c49 168 return newValue;
dkato 0:f782d9c66c49 169 }
dkato 0:f782d9c66c49 170
dkato 0:f782d9c66c49 171 uint16_t core_util_atomic_decr_u16(uint16_t *valuePtr, uint16_t delta)
dkato 0:f782d9c66c49 172 {
dkato 0:f782d9c66c49 173 uint16_t newValue;
dkato 0:f782d9c66c49 174 do {
dkato 0:f782d9c66c49 175 newValue = __LDREXH((volatile uint16_t*)valuePtr) - delta;
dkato 0:f782d9c66c49 176 } while (__STREXH(newValue, (volatile uint16_t*)valuePtr));
dkato 0:f782d9c66c49 177 return newValue;
dkato 0:f782d9c66c49 178 }
dkato 0:f782d9c66c49 179
dkato 0:f782d9c66c49 180 uint32_t core_util_atomic_decr_u32(uint32_t *valuePtr, uint32_t delta)
dkato 0:f782d9c66c49 181 {
dkato 0:f782d9c66c49 182 uint32_t newValue;
dkato 0:f782d9c66c49 183 do {
dkato 0:f782d9c66c49 184 newValue = __LDREXW((volatile uint32_t*)valuePtr) - delta;
dkato 0:f782d9c66c49 185 } while (__STREXW(newValue, (volatile uint32_t*)valuePtr));
dkato 0:f782d9c66c49 186 return newValue;
dkato 0:f782d9c66c49 187 }
dkato 0:f782d9c66c49 188
dkato 0:f782d9c66c49 189 #else
dkato 0:f782d9c66c49 190
dkato 0:f782d9c66c49 191 bool core_util_atomic_cas_u8(uint8_t *ptr, uint8_t *expectedCurrentValue, uint8_t desiredValue)
dkato 0:f782d9c66c49 192 {
dkato 0:f782d9c66c49 193 bool success;
dkato 0:f782d9c66c49 194 uint8_t currentValue;
dkato 0:f782d9c66c49 195 core_util_critical_section_enter();
dkato 0:f782d9c66c49 196 currentValue = *ptr;
dkato 0:f782d9c66c49 197 if (currentValue == *expectedCurrentValue) {
dkato 0:f782d9c66c49 198 *ptr = desiredValue;
dkato 0:f782d9c66c49 199 success = true;
dkato 0:f782d9c66c49 200 } else {
dkato 0:f782d9c66c49 201 *expectedCurrentValue = currentValue;
dkato 0:f782d9c66c49 202 success = false;
dkato 0:f782d9c66c49 203 }
dkato 0:f782d9c66c49 204 core_util_critical_section_exit();
dkato 0:f782d9c66c49 205 return success;
dkato 0:f782d9c66c49 206 }
dkato 0:f782d9c66c49 207
dkato 0:f782d9c66c49 208 bool core_util_atomic_cas_u16(uint16_t *ptr, uint16_t *expectedCurrentValue, uint16_t desiredValue)
dkato 0:f782d9c66c49 209 {
dkato 0:f782d9c66c49 210 bool success;
dkato 0:f782d9c66c49 211 uint16_t currentValue;
dkato 0:f782d9c66c49 212 core_util_critical_section_enter();
dkato 0:f782d9c66c49 213 currentValue = *ptr;
dkato 0:f782d9c66c49 214 if (currentValue == *expectedCurrentValue) {
dkato 0:f782d9c66c49 215 *ptr = desiredValue;
dkato 0:f782d9c66c49 216 success = true;
dkato 0:f782d9c66c49 217 } else {
dkato 0:f782d9c66c49 218 *expectedCurrentValue = currentValue;
dkato 0:f782d9c66c49 219 success = false;
dkato 0:f782d9c66c49 220 }
dkato 0:f782d9c66c49 221 core_util_critical_section_exit();
dkato 0:f782d9c66c49 222 return success;
dkato 0:f782d9c66c49 223 }
dkato 0:f782d9c66c49 224
dkato 0:f782d9c66c49 225
dkato 0:f782d9c66c49 226 bool core_util_atomic_cas_u32(uint32_t *ptr, uint32_t *expectedCurrentValue, uint32_t desiredValue)
dkato 0:f782d9c66c49 227 {
dkato 0:f782d9c66c49 228 bool success;
dkato 0:f782d9c66c49 229 uint32_t currentValue;
dkato 0:f782d9c66c49 230 core_util_critical_section_enter();
dkato 0:f782d9c66c49 231 currentValue = *ptr;
dkato 0:f782d9c66c49 232 if (currentValue == *expectedCurrentValue) {
dkato 0:f782d9c66c49 233 *ptr = desiredValue;
dkato 0:f782d9c66c49 234 success = true;
dkato 0:f782d9c66c49 235 } else {
dkato 0:f782d9c66c49 236 *expectedCurrentValue = currentValue;
dkato 0:f782d9c66c49 237 success = false;
dkato 0:f782d9c66c49 238 }
dkato 0:f782d9c66c49 239 core_util_critical_section_exit();
dkato 0:f782d9c66c49 240 return success;
dkato 0:f782d9c66c49 241 }
dkato 0:f782d9c66c49 242
dkato 0:f782d9c66c49 243
dkato 0:f782d9c66c49 244 uint8_t core_util_atomic_incr_u8(uint8_t *valuePtr, uint8_t delta)
dkato 0:f782d9c66c49 245 {
dkato 0:f782d9c66c49 246 uint8_t newValue;
dkato 0:f782d9c66c49 247 core_util_critical_section_enter();
dkato 0:f782d9c66c49 248 newValue = *valuePtr + delta;
dkato 0:f782d9c66c49 249 *valuePtr = newValue;
dkato 0:f782d9c66c49 250 core_util_critical_section_exit();
dkato 0:f782d9c66c49 251 return newValue;
dkato 0:f782d9c66c49 252 }
dkato 0:f782d9c66c49 253
dkato 0:f782d9c66c49 254 uint16_t core_util_atomic_incr_u16(uint16_t *valuePtr, uint16_t delta)
dkato 0:f782d9c66c49 255 {
dkato 0:f782d9c66c49 256 uint16_t newValue;
dkato 0:f782d9c66c49 257 core_util_critical_section_enter();
dkato 0:f782d9c66c49 258 newValue = *valuePtr + delta;
dkato 0:f782d9c66c49 259 *valuePtr = newValue;
dkato 0:f782d9c66c49 260 core_util_critical_section_exit();
dkato 0:f782d9c66c49 261 return newValue;
dkato 0:f782d9c66c49 262 }
dkato 0:f782d9c66c49 263
dkato 0:f782d9c66c49 264 uint32_t core_util_atomic_incr_u32(uint32_t *valuePtr, uint32_t delta)
dkato 0:f782d9c66c49 265 {
dkato 0:f782d9c66c49 266 uint32_t newValue;
dkato 0:f782d9c66c49 267 core_util_critical_section_enter();
dkato 0:f782d9c66c49 268 newValue = *valuePtr + delta;
dkato 0:f782d9c66c49 269 *valuePtr = newValue;
dkato 0:f782d9c66c49 270 core_util_critical_section_exit();
dkato 0:f782d9c66c49 271 return newValue;
dkato 0:f782d9c66c49 272 }
dkato 0:f782d9c66c49 273
dkato 0:f782d9c66c49 274
dkato 0:f782d9c66c49 275 uint8_t core_util_atomic_decr_u8(uint8_t *valuePtr, uint8_t delta)
dkato 0:f782d9c66c49 276 {
dkato 0:f782d9c66c49 277 uint8_t newValue;
dkato 0:f782d9c66c49 278 core_util_critical_section_enter();
dkato 0:f782d9c66c49 279 newValue = *valuePtr - delta;
dkato 0:f782d9c66c49 280 *valuePtr = newValue;
dkato 0:f782d9c66c49 281 core_util_critical_section_exit();
dkato 0:f782d9c66c49 282 return newValue;
dkato 0:f782d9c66c49 283 }
dkato 0:f782d9c66c49 284
dkato 0:f782d9c66c49 285 uint16_t core_util_atomic_decr_u16(uint16_t *valuePtr, uint16_t delta)
dkato 0:f782d9c66c49 286 {
dkato 0:f782d9c66c49 287 uint16_t newValue;
dkato 0:f782d9c66c49 288 core_util_critical_section_enter();
dkato 0:f782d9c66c49 289 newValue = *valuePtr - delta;
dkato 0:f782d9c66c49 290 *valuePtr = newValue;
dkato 0:f782d9c66c49 291 core_util_critical_section_exit();
dkato 0:f782d9c66c49 292 return newValue;
dkato 0:f782d9c66c49 293 }
dkato 0:f782d9c66c49 294
dkato 0:f782d9c66c49 295 uint32_t core_util_atomic_decr_u32(uint32_t *valuePtr, uint32_t delta)
dkato 0:f782d9c66c49 296 {
dkato 0:f782d9c66c49 297 uint32_t newValue;
dkato 0:f782d9c66c49 298 core_util_critical_section_enter();
dkato 0:f782d9c66c49 299 newValue = *valuePtr - delta;
dkato 0:f782d9c66c49 300 *valuePtr = newValue;
dkato 0:f782d9c66c49 301 core_util_critical_section_exit();
dkato 0:f782d9c66c49 302 return newValue;
dkato 0:f782d9c66c49 303 }
dkato 0:f782d9c66c49 304
dkato 0:f782d9c66c49 305 #endif
dkato 0:f782d9c66c49 306
dkato 0:f782d9c66c49 307
dkato 0:f782d9c66c49 308 bool core_util_atomic_cas_ptr(void **ptr, void **expectedCurrentValue, void *desiredValue) {
dkato 0:f782d9c66c49 309 return core_util_atomic_cas_u32(
dkato 0:f782d9c66c49 310 (uint32_t *)ptr,
dkato 0:f782d9c66c49 311 (uint32_t *)expectedCurrentValue,
dkato 0:f782d9c66c49 312 (uint32_t)desiredValue);
dkato 0:f782d9c66c49 313 }
dkato 0:f782d9c66c49 314
dkato 0:f782d9c66c49 315 void *core_util_atomic_incr_ptr(void **valuePtr, ptrdiff_t delta) {
dkato 0:f782d9c66c49 316 return (void *)core_util_atomic_incr_u32((uint32_t *)valuePtr, (uint32_t)delta);
dkato 0:f782d9c66c49 317 }
dkato 0:f782d9c66c49 318
dkato 0:f782d9c66c49 319 void *core_util_atomic_decr_ptr(void **valuePtr, ptrdiff_t delta) {
dkato 0:f782d9c66c49 320 return (void *)core_util_atomic_decr_u32((uint32_t *)valuePtr, (uint32_t)delta);
dkato 0:f782d9c66c49 321 }
dkato 0:f782d9c66c49 322