1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-01-17 05:32:45 +01:00

Merge pull request #11117 from haukepetersen/add_core_irqisen

core: add irq_is_enabled() function to irq interface
This commit is contained in:
Francisco 2021-08-26 18:41:02 +02:00 committed by GitHub
commit 3db378e015
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 114 additions and 10 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2013 Freie Universität Berlin
* Copyright (C) 2013,2019 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
@ -16,6 +16,7 @@
* @brief IRQ driver interface
*
* @author Freie Universität Berlin, Computer Systems & Telematics
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/
#ifndef IRQ_H
@ -67,6 +68,17 @@ MAYBE_INLINE unsigned irq_enable(void);
*/
MAYBE_INLINE void irq_restore(unsigned state);
/**
* @brief Test if IRQs are currently enabled
*
* @warning Use this function from thread context only. When used in interrupt
* context the returned state may be incorrect.
*
* @return 0 (false) if IRQs are currently disabled
* @return != 0 (true) if IRQs are currently enabled
*/
MAYBE_INLINE int irq_is_enabled(void);
/**
* @brief Check whether called from interrupt service routine
* @return true, if in interrupt service routine, false if not

View File

@ -70,6 +70,11 @@ static inline __attribute__((always_inline)) unsigned irq_enable(void)
return _cpsr;
}
static inline __attribute__((always_inline)) int irq_is_enabled(void)
{
return !(__get_cpsr() & IRQ_MASK);
}
#ifdef __cplusplus
}
#endif

View File

@ -103,6 +103,21 @@ __attribute__((always_inline)) static inline int irq_is_in(void)
return (state & AVR8_STATE_FLAG_ISR);
}
/**
* @brief Test if interrupts are currently enabled
*/
__attribute__((always_inline)) static inline int irq_is_enabled(void)
{
uint8_t mask;
__asm__ volatile(
"in %[dest], __SREG__" "\n\t"
: [dest] "=r"(mask)
: /* no inputs */
: "memory"
);
return mask & (1 << 7);
}
#ifdef __cplusplus
}
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2015 Freie Universität Berlin
* Copyright (C) 2014-2019 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
@ -60,6 +60,17 @@ static inline __attribute__((always_inline)) void irq_restore(
__set_PRIMASK(state);
}
/**
* @brief See if IRQs are currently enabled
*/
static inline __attribute__((always_inline)) int irq_is_enabled(void)
{
/* so far, all existing Cortex-M are only using the least significant bit
* in the PRIMARK register. If ever any other bit is used for different
* purposes, this function will not work properly anymore. */
return (__get_PRIMASK() == 0);
}
/**
* @brief See if the current context is inside an ISR
*/

View File

@ -99,3 +99,14 @@ int IRAM irq_is_in(void)
DEBUG("irq_interrupt_nesting = %d\n", irq_interrupt_nesting);
return irq_interrupt_nesting;
}
/**
* @brief Test if IRQs are currently enabled
*/
int IRAM irq_is_enabled(void)
{
uint32_t reg;
RSR(reg, 230);
return (reg & 0xf) == 0;
}

View File

@ -39,3 +39,7 @@ int irq_is_in(void)
{
return (mips32_get_c0(C0_STATUS) & SR_EXL) != 0;
}
int irq_is_enabled(void) {
return mips32_get_c0(C0_STATUS) & SR_IE;
}

View File

@ -23,6 +23,7 @@
#ifndef IRQ_ARCH_H
#define IRQ_ARCH_H
#include <msp430.h>
#include "irq.h"
#ifdef __cplusplus
@ -87,6 +88,19 @@ __attribute__((always_inline)) static inline int irq_is_in(void)
return __irq_is_in;
}
__attribute__((always_inline)) static inline int irq_is_enabled(void)
{
unsigned int state;
__asm__ volatile(
"mov.w r2,%[state]" "\n\t"
: [state] "=r"(state)
: /* no inputs */
: "memory"
);
return (state & GIE);
}
#ifdef __cplusplus
}
#endif

View File

@ -225,6 +225,11 @@ void irq_restore(unsigned state)
return;
}
int irq_is_enabled(void)
{
return native_interrupts_enabled;
}
int irq_is_in(void)
{
DEBUG("irq_is_in: %i\n", _native_in_isr);

View File

@ -97,6 +97,18 @@ static inline __attribute__((always_inline)) int irq_is_in(void)
return riscv_in_isr;
}
static inline __attribute__((always_inline)) int irq_is_enabled(void)
{
unsigned state;
__asm__ volatile (
"csrr %[dest], mstatus"
:[dest] "=r" (state)
: /* no inputs */
: "memory"
);
return (state & MSTATUS_MIE);
}
#ifdef __cplusplus
}
#endif

View File

@ -56,6 +56,21 @@ int main(void)
"======================================\n"
"\n");
/* Short enable-restore sequence to check if the irq_is_enabled() function
* is reporting the correct IRQ state */
print_str("Verifying IRQ state tracking works: ");
int state_a = irq_is_enabled();
unsigned state = irq_disable();
int state_b = irq_is_enabled();
irq_restore(state);
int state_c = irq_is_enabled();
if ((state_a != 0) && (state_b == 0) && (state_c != 0)) {
print_str("[SUCCESS]\n");
}
else {
print_str("[FAILURE]\n");
}
print_str("Verifying test works: ");
xtimer_set(&xt, DELAY / 2);
atomic_store(&a, 1);
@ -64,7 +79,7 @@ int main(void)
/* Timer should have fired in the middle of busy_delay(), thus value of
* a now and during ISR should both be 1, but value of b during ISR should
* still be 0 but not it should be 1 */
* still be 0 but now it should be 1 */
if ((atomic_load(&a) == atomic_load(&a_during_isr)) &&
(atomic_load(&b) != atomic_load(&b_during_isr)))
{
@ -76,7 +91,7 @@ int main(void)
print_str("Test result: ");
xtimer_set(&xt, DELAY / 2);
unsigned state = irq_disable();
state = irq_disable();
atomic_store(&a, 2);
busy_delay();
atomic_store(&b, 2);

View File

@ -32,9 +32,9 @@
static mutex_t _mutex = MUTEX_INIT_LOCKED;
#define N 5
#define REPEAT 5
static uint32_t _times[N];
static uint32_t _times[REPEAT];
static int _count;
#define ZTIMER_CLOCKS { ZTIMER_MSEC, ZTIMER_USEC }
static const char *_names[] = { "ZTIMER_MSEC", "ZTIMER_USEC" };
@ -54,11 +54,11 @@ static int callback(void *arg)
}
#endif
if (_count == N) {
if (_count == REPEAT) {
mutex_unlock(&_mutex);
}
return (_count == N);
return (_count == REPEAT);
}
int main(void)
@ -85,10 +85,10 @@ int main(void)
return 1;
}
/* wait for periodic to trigger N times */
/* wait for periodic to trigger REPEAT times */
mutex_lock(&_mutex);
for (unsigned i = 0; i < N; i++) {
for (unsigned i = 0; i < REPEAT; i++) {
uint32_t offset = labs((int32_t)(_times[i] - _intervals[j] - last));
printf("i: %u time: %" PRIu32 " offset: %" PRIu32 "\n",
i, _times[i], offset);