Loading...
Searching...
No Matches
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
17
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
25extern "C" {
26#endif
27
31static 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
41static 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
51static inline __attribute__((always_inline))
52unsigned 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
67static inline __attribute__((always_inline)) __attribute__((used))
68unsigned int irq_enable(void)
69{
70 unsigned result = __get_PRIMASK();
71
72 __enable_irq();
73 return result;
74}
75
79static inline __attribute__((always_inline))
80#if !IS_USED(MODULE_DEBUG_IRQ_DISABLE)
81void irq_restore(unsigned int state)
82{
83 __set_PRIMASK(state);
84}
85#else
86void _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
106static inline __attribute__((always_inline))
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
118static inline __attribute__((always_inline))
119bool irq_is_in(void)
120{
121 return (__get_IPSR() & 0xFF);
122}
123
124#ifdef __cplusplus
125}
126#endif
127
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
MAYBE_INLINE void irq_restore(unsigned state)
This function restores the IRQ disable bit in the status register to the value contained within passe...
MAYBE_INLINE unsigned irq_disable(void)
This function sets the IRQ disable bit in the status register.
MAYBE_INLINE bool irq_is_enabled(void)
Test if IRQs are currently enabled.
MAYBE_INLINE unsigned irq_enable(void)
This function clears the IRQ disable bit in the status register.
MAYBE_INLINE bool irq_is_in(void)
Check whether called from interrupt service routine.
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