irq_arch.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014-2019 Freie Universität Berlin
3  *
4  * This file is subject to the terms and conditions of the GNU Lesser General
5  * Public License v2.1. See the file LICENSE in the top level directory for more
6  * details.
7  */
8 
19 #ifndef IRQ_ARCH_H
20 #define IRQ_ARCH_H
21 
22 #include <stdbool.h>
23 #include <stdint.h>
24 #include "cpu_conf.h"
25 #include "kernel_defines.h"
26 #include "debug_irq_disable.h"
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
35 static inline void _irq_debug_start_count(void)
36 {
37  SysTick->VAL = 0;
38  SysTick->LOAD = SysTick_LOAD_RELOAD_Msk;
39  SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
40 }
41 
45 static inline uint32_t _irq_debug_stop_count(void)
46 {
47  uint32_t ticks = SysTick_LOAD_RELOAD_Msk - SysTick->VAL;
48  SysTick->CTRL = 0;
49  return ticks;
50 }
51 
55 static inline __attribute__((always_inline))
56 unsigned int irq_disable(void)
57 {
58  uint32_t mask = __get_PRIMASK();
59 
60  if ((mask == 0) && IS_USED(MODULE_DEBUG_IRQ_DISABLE)) {
62  }
63 
64  __disable_irq();
65  return mask;
66 }
67 
71 static inline __attribute__((always_inline)) __attribute__((used))
72 unsigned int irq_enable(void)
73 {
74  unsigned result = __get_PRIMASK();
75 
76  __enable_irq();
77  return result;
78 }
79 
83 static inline __attribute__((always_inline))
84 #if !IS_USED(MODULE_DEBUG_IRQ_DISABLE)
85 void irq_restore(unsigned int state)
86 {
87  __set_PRIMASK(state);
88 }
89 #else
90 void _irq_restore(unsigned int state, const char *file, unsigned line)
91 {
92  uint32_t ticks = 0;
93 
94  if (state == 0) {
95  ticks = _irq_debug_stop_count();
96  }
97 
98  __set_PRIMASK(state);
99 
100  if (ticks) {
101  debug_irq_disable_print(file, line, ticks);
102  }
103 }
104 #define irq_restore(state) _irq_restore(state, __FILE__, __LINE__);
105 #endif /* MODULE_DEBUG_IRQ_DISABLE */
106 
110 static inline __attribute__((always_inline))
111 bool irq_is_enabled(void)
112 {
113  /* so far, all existing Cortex-M are only using the least significant bit
114  * in the PRIMARK register. If ever any other bit is used for different
115  * purposes, this function will not work properly anymore. */
116  return (__get_PRIMASK() == 0);
117 }
118 
122 static inline __attribute__((always_inline))
123 bool irq_is_in(void)
124 {
125  return (__get_IPSR() & 0xFF);
126 }
127 
128 #ifdef __cplusplus
129 }
130 #endif
131 
132 #endif /* IRQ_ARCH_H */
static void irq_restore(unsigned int state)
Restore the state of the IRQ flags.
Definition: irq_arch.h:85
static unsigned int irq_disable(void)
Disable all maskable interrupts.
Definition: irq_arch.h:56
static uint32_t _irq_debug_stop_count(void)
Stop SysTick timer, return time spent with IRQ disabled.
Definition: irq_arch.h:45
static void _irq_debug_start_count(void)
Start SysTick timer to measure time spent with IRQ disabled.
Definition: irq_arch.h:35
static bool irq_is_enabled(void)
See if IRQs are currently enabled.
Definition: irq_arch.h:111
static bool irq_is_in(void)
See if the current context is inside an ISR.
Definition: irq_arch.h:123
static unsigned int irq_enable(void)
Enable all maskable interrupts.
Definition: irq_arch.h:72
void debug_irq_disable_print(const char *file, unsigned line, uint32_t ticks)
Print time spent with IRQ disabled.
Common macros and compiler attributes/pragmas configuration.
#define IS_USED(module)
Checks whether a module is being used or not.
Definition: modules.h:71