Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers arm_hal_interrupt.c Source File

arm_hal_interrupt.c

00001 /*
00002  * Copyright (c) 2016 ARM Limited, All Rights Reserved
00003  */
00004 
00005 #include "arm_hal_interrupt.h"
00006 #include "arm_hal_interrupt_private.h"
00007 
00008 #if MBED_CONF_NANOSTACK_HAL_CRITICAL_SECTION_USABLE_FROM_INTERRUPT
00009 #include "platform/mbed_critical.h"
00010 #else
00011 #include "cmsis_os2.h"
00012 #include "mbed_rtos_storage.h"
00013 #endif
00014 
00015 #include <mbed_assert.h>
00016 
00017 
00018 // The critical section has two alternative implementations, the default which uses mutex
00019 // as locking primitive and the optional, which will bluntly disable interrupts
00020 // for the critical section. The mutex version will not cause issues by delaying
00021 // interrupts, but it has a down side that it can not be used from the interrupt
00022 // service routines. The IRQ-safe version will do the mutual exclusion by temporarily
00023 // disabling the interrupts, so it will have effect on interrupt latency.
00024 #if !MBED_CONF_NANOSTACK_HAL_CRITICAL_SECTION_USABLE_FROM_INTERRUPT
00025 
00026 static uint8_t sys_irq_disable_counter;
00027 
00028 static mbed_rtos_storage_mutex_t critical_mutex;
00029 static const osMutexAttr_t critical_mutex_attr = {
00030   .name = "nanostack_critical_mutex",
00031   .attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust,
00032   .cb_mem = &critical_mutex,
00033   .cb_size = sizeof critical_mutex,
00034 };
00035 static osMutexId_t critical_mutex_id;
00036 
00037 #endif
00038 
00039 void platform_critical_init(void)
00040 {
00041 #if MBED_CONF_NANOSTACK_HAL_CRITICAL_SECTION_USABLE_FROM_INTERRUPT
00042     // nothing to do here
00043 #else
00044     critical_mutex_id = osMutexNew(&critical_mutex_attr);
00045     MBED_ASSERT(critical_mutex_id);
00046 #endif
00047 }
00048 
00049 void platform_enter_critical(void)
00050 {
00051 #if MBED_CONF_NANOSTACK_HAL_CRITICAL_SECTION_USABLE_FROM_INTERRUPT
00052     core_util_critical_section_enter();
00053 #else
00054     osMutexAcquire(critical_mutex_id, osWaitForever);
00055     sys_irq_disable_counter++;
00056 #endif
00057 }
00058 
00059 void platform_exit_critical(void)
00060 {
00061 #if MBED_CONF_NANOSTACK_HAL_CRITICAL_SECTION_USABLE_FROM_INTERRUPT
00062     core_util_critical_section_exit();
00063 #else
00064     --sys_irq_disable_counter;
00065     osMutexRelease(critical_mutex_id);
00066 #endif
00067 }