Mayank Gupta / Mbed OS pelion-example-frdm

Dependencies:   FXAS21002 FXOS8700Q

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers critical.c Source File

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)