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 
9 #pragma once
10 
21 #include <stdbool.h>
22 #include <stdint.h>
23 #include "cpu_conf.h"
24 #include "kernel_defines.h"
25 #include "debug_irq_disable.h"
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 
34 static inline void _irq_debug_start_count(void)
35 {
36  SysTick->VAL = 0;
37  SysTick->LOAD = SysTick_LOAD_RELOAD_Msk;
38  SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
39 }
40 
44 static inline uint32_t _irq_debug_stop_count(void)
45 {
46  uint32_t ticks = SysTick_LOAD_RELOAD_Msk - SysTick->VAL;
47  SysTick->CTRL = 0;
48  return ticks;
49 }
50 
54 static inline __attribute__((always_inline))
55 unsigned int irq_disable(void)
56 {
57  uint32_t mask = __get_PRIMASK();
58 
59  if ((mask == 0) && IS_USED(MODULE_DEBUG_IRQ_DISABLE)) {
61  }
62 
63  __disable_irq();
64  return mask;
65 }
66 
70 static inline __attribute__((always_inline)) __attribute__((used))
71 unsigned int irq_enable(void)
72 {
73  unsigned result = __get_PRIMASK();
74 
75  __enable_irq();
76  return result;
77 }
78 
82 static inline __attribute__((always_inline))
83 #if !IS_USED(MODULE_DEBUG_IRQ_DISABLE)
84 void irq_restore(unsigned int state)
85 {
86  __set_PRIMASK(state);
87 }
88 #else
89 void _irq_restore(unsigned int state, const char *file, unsigned line)
90 {
91  uint32_t ticks = 0;
92 
93  if (state == 0) {
94  ticks = _irq_debug_stop_count();
95  }
96 
97  __set_PRIMASK(state);
98 
99  if (ticks) {
100  debug_irq_disable_print(file, line, ticks);
101  }
102 }
103 #define irq_restore(state) _irq_restore(state, __FILE__, __LINE__);
104 #endif /* MODULE_DEBUG_IRQ_DISABLE */
105 
109 static inline __attribute__((always_inline))
110 bool irq_is_enabled(void)
111 {
112  /* so far, all existing Cortex-M are only using the least significant bit
113  * in the PRIMARK register. If ever any other bit is used for different
114  * purposes, this function will not work properly anymore. */
115  return (__get_PRIMASK() == 0);
116 }
117 
121 static inline __attribute__((always_inline))
122 bool irq_is_in(void)
123 {
124  return (__get_IPSR() & 0xFF);
125 }
126 
127 #ifdef __cplusplus
128 }
129 #endif
130 
static void irq_restore(unsigned int state)
Restore the state of the IRQ flags.
Definition: irq_arch.h:84
static unsigned int irq_disable(void)
Disable all maskable interrupts.
Definition: irq_arch.h:55
static uint32_t _irq_debug_stop_count(void)
Stop SysTick timer, return time spent with IRQ disabled.
Definition: irq_arch.h:44
static void _irq_debug_start_count(void)
Start SysTick timer to measure time spent with IRQ disabled.
Definition: irq_arch.h:34
static bool irq_is_enabled(void)
See if IRQs are currently enabled.
Definition: irq_arch.h:110
static bool irq_is_in(void)
See if the current context is inside an ISR.
Definition: irq_arch.h:122
static unsigned int irq_enable(void)
Enable all maskable interrupts.
Definition: irq_arch.h:71
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:70