Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
critical.c
00001 // ---------------------------------------------------------------------------- 00002 // Copyright 2015-2017 ARM Ltd. 00003 // 00004 // SPDX-License-Identifier: Apache-2.0 00005 // 00006 // Licensed under the Apache License, Version 2.0 (the "License"); 00007 // you may 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, 00014 // WITHOUT 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 // This critical section implementation is generic for mbed OS targets, 00020 // except Nordic ones 00021 #if defined(TARGET_LIKE_MBED) && !defined(TARGET_NORDIC) 00022 00023 #include <stdint.h> // uint32_t, UINT32_MAX 00024 #include <stddef.h> // NULL 00025 00026 #if defined(YOTTA_CFG_MBED_OS) 00027 #include "cmsis-core/core_generic.h" //__disable_irq, __enable_irq 00028 #else 00029 #include "cmsis.h" 00030 #endif 00031 00032 #include <assert.h> 00033 00034 // Module include 00035 #include "aq_critical.h" 00036 00037 static volatile uint32_t interruptEnableCounter = 0; 00038 static volatile uint32_t critical_primask = 0; 00039 00040 void aq_critical_section_enter() 00041 { 00042 uint32_t primask; 00043 #if defined(__CORTEX_A9) 00044 primask = __get_CPSR(); // get the current interrupt enabled state 00045 #else 00046 primask = __get_PRIMASK(); // get the current interrupt enabled state 00047 #endif 00048 __disable_irq(); 00049 00050 // Save the interrupt enabled state as it was prior to any nested critical section lock use 00051 if (!interruptEnableCounter) { 00052 #if defined(__CORTEX_A9) 00053 critical_primask = primask & 0x80; 00054 #else 00055 critical_primask = primask & 0x1; 00056 #endif 00057 } 00058 #if 0 00059 /* If the interruptEnableCounter overflows or we are in a nested critical section and interrupts 00060 are enabled, then something has gone badly wrong thus assert an error. 00061 */ 00062 00063 /* FIXME: This assertion needs to be commented out for the moment, as it 00064 * triggers a fault when uVisor is enabled. For more information on 00065 * the fault please checkout ARMmbed/mbed-drivers#176. */ 00066 00067 assert(interruptEnableCounter < UINT32_MAX); 00068 if (interruptEnableCounter > 0) { 00069 assert(primask & 0x1); 00070 } 00071 #endif 00072 00073 if (interruptEnableCounter < UINT32_MAX) { 00074 interruptEnableCounter++; 00075 } 00076 } 00077 00078 void aq_critical_section_exit(void) 00079 { 00080 // If critical_section_enter has not previously been called, do nothing 00081 if (interruptEnableCounter) { 00082 #if 0 00083 /* FIXME: This assertion needs to be commented out for the moment, as it 00084 * triggers a fault when uVisor is enabled. For more information 00085 * on the fault please checkout ARMmbed/mbed-drivers#176. */ 00086 00087 uint32_t primask; 00088 #if defined(__CORTEX_A9) 00089 primask = __get_CPSR(); // get the current interrupt enabled state 00090 #else 00091 primask = __get_PRIMASK(); // get the current interrupt enabled state 00092 #endif 00093 assert(primask & 0x1); // Interrupts must be disabled on invoking an exit from a critical section 00094 #endif 00095 00096 interruptEnableCounter--; 00097 00098 00099 /* Only re-enable interrupts if we are exiting the last of the nested critical sections and 00100 interrupts were enabled on entry to the first critical section. 00101 */ 00102 if (!interruptEnableCounter && !critical_primask) { 00103 __enable_irq(); 00104 } 00105 } 00106 } 00107 00108 #endif // defined(TARGET_LIKE_MBED) && !defined(TARGET_NORDIC)
Generated on Mon Aug 29 2022 19:53:38 by
