irq_arch.h
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2014-2019 Freie Universität Berlin
3  * SPDX-License-Identifier: LGPL-2.1-only
4  */
5 
6 #pragma once
7 
18 #include <stdbool.h>
19 #include <stdint.h>
20 #include "cpu_conf.h"
21 #include "kernel_defines.h"
22 #include "debug_irq_disable.h"
23 
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27 
31 static inline void _irq_debug_start_count(void)
32 {
33  SysTick->VAL = 0;
34  SysTick->LOAD = SysTick_LOAD_RELOAD_Msk;
35  SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
36 }
37 
41 static inline uint32_t _irq_debug_stop_count(void)
42 {
43  uint32_t ticks = SysTick_LOAD_RELOAD_Msk - SysTick->VAL;
44  SysTick->CTRL = 0;
45  return ticks;
46 }
47 
51 static inline __attribute__((always_inline))
52 unsigned int irq_disable(void)
53 {
54  uint32_t mask = __get_PRIMASK();
55 
56  if ((mask == 0) && IS_USED(MODULE_DEBUG_IRQ_DISABLE)) {
58  }
59 
60  __disable_irq();
61  return mask;
62 }
63 
67 static inline __attribute__((always_inline)) __attribute__((used))
68 unsigned int irq_enable(void)
69 {
70  unsigned result = __get_PRIMASK();
71 
72  __enable_irq();
73  return result;
74 }
75 
79 static inline __attribute__((always_inline))
80 #if !IS_USED(MODULE_DEBUG_IRQ_DISABLE)
81 void irq_restore(unsigned int state)
82 {
83  __set_PRIMASK(state);
84 }
85 #else
86 void _irq_restore(unsigned int state, const char *file, unsigned line)
87 {
88  uint32_t ticks = 0;
89 
90  if (state == 0) {
91  ticks = _irq_debug_stop_count();
92  }
93 
94  __set_PRIMASK(state);
95 
96  if (ticks) {
97  debug_irq_disable_print(file, line, ticks);
98  }
99 }
100 #define irq_restore(state) _irq_restore(state, __FILE__, __LINE__);
101 #endif /* MODULE_DEBUG_IRQ_DISABLE */
102 
106 static inline __attribute__((always_inline))
107 bool irq_is_enabled(void)
108 {
109  /* so far, all existing Cortex-M are only using the least significant bit
110  * in the PRIMARK register. If ever any other bit is used for different
111  * purposes, this function will not work properly anymore. */
112  return (__get_PRIMASK() == 0);
113 }
114 
118 static inline __attribute__((always_inline))
119 bool irq_is_in(void)
120 {
121  return (__get_IPSR() & 0xFF);
122 }
123 
124 #ifdef __cplusplus
125 }
126 #endif
127 
static void irq_restore(unsigned int state)
Restore the state of the IRQ flags.
Definition: irq_arch.h:81
static unsigned int irq_disable(void)
Disable all maskable interrupts.
Definition: irq_arch.h:52
static uint32_t _irq_debug_stop_count(void)
Stop SysTick timer, return time spent with IRQ disabled.
Definition: irq_arch.h:41
static void _irq_debug_start_count(void)
Start SysTick timer to measure time spent with IRQ disabled.
Definition: irq_arch.h:31
static bool irq_is_enabled(void)
See if IRQs are currently enabled.
Definition: irq_arch.h:107
static bool irq_is_in(void)
See if the current context is inside an ISR.
Definition: irq_arch.h:119
static unsigned int irq_enable(void)
Enable all maskable interrupts.
Definition: irq_arch.h:68
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