Mbed Cloud example program for workshop in W27 2018.

Dependencies:   MMA7660 LM75B

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 = __get_PRIMASK(); // get the current interrupt enabled state
00043     __disable_irq();
00044 
00045     // Save the interrupt enabled state as it was prior to any nested critical section lock use
00046     if (!interruptEnableCounter) {
00047         critical_primask = primask & 0x1;
00048     }
00049 
00050     /* If the interruptEnableCounter overflows or we are in a nested critical section and interrupts
00051        are enabled, then something has gone badly wrong thus assert an error.
00052     */
00053 
00054     /* FIXME: This assertion needs to be commented out for the moment, as it
00055      *        triggers a fault when uVisor is enabled. For more information on
00056      *        the fault please checkout ARMmbed/mbed-drivers#176. */
00057     /* assert(interruptEnableCounter < UINT32_MAX); */
00058     if (interruptEnableCounter > 0) {
00059         /* FIXME: This assertion needs to be commented out for the moment, as it
00060          *        triggers a fault when uVisor is enabled. For more information
00061          *        on the fault please checkout ARMmbed/mbed-drivers#176. */
00062         /* assert(primask & 0x1); */
00063     }
00064     interruptEnableCounter++;
00065 }
00066 
00067 void aq_critical_section_exit()
00068 {
00069     // If critical_section_enter has not previously been called, do nothing
00070     if (interruptEnableCounter) {
00071 
00072         uint32_t primask = __get_PRIMASK(); // get the current interrupt enabled state
00073 
00074         /* FIXME: This assertion needs to be commented out for the moment, as it
00075          *        triggers a fault when uVisor is enabled. For more information
00076          *        on the fault please checkout ARMmbed/mbed-drivers#176. */
00077         /* assert(primask & 0x1); // Interrupts must be disabled on invoking an exit from a critical section */
00078 
00079         interruptEnableCounter--;
00080 
00081         /* Only re-enable interrupts if we are exiting the last of the nested critical sections and
00082            interrupts were enabled on entry to the first critical section.
00083         */
00084         if (!interruptEnableCounter && !critical_primask) {
00085             __enable_irq();
00086         }
00087     }
00088 }
00089 
00090 #endif // defined(TARGET_LIKE_MBED) && !defined(TARGET_NORDIC)