blob: e6fbb5e97b03d8c23247cb3cc33b46250b32f7cb [file] [log] [blame]
/*
* Copyright (c) 2018 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/ztest.h>
#include <zephyr/interrupt_util.h>
#define DURATION 5
#define HANDLER_TOKEN 0xDEADBEEF
/* Long enough to be guaranteed a tick "should have fired" */
#define TIMER_DELAY_US (128 * 1000000 / CONFIG_SYS_CLOCK_TICKS_PER_SEC)
static struct k_timer irqlock_timer;
volatile uint32_t handler_result;
static void timer_handler(struct k_timer *timer)
{
ARG_UNUSED(timer);
handler_result = HANDLER_TOKEN;
printk("timer fired\n");
}
/**
* @brief Test interrupt prevention
*
* @ingroup kernel_interrupt_tests
*
* This routine tests if the kernel is capable of preventing interruption, by
* locking interrupts and busy-waiting to see if the system timer interrupt is
* serviced while interrupts are locked; in addition, this test also verifies
* that the system timer interrupt is serviced after interrupts are unlocked.
*/
ZTEST(interrupt_feature, test_prevent_interruption)
{
unsigned int key;
printk("locking interrupts\n");
key = irq_lock();
handler_result = 0;
k_timer_init(&irqlock_timer, timer_handler, NULL);
/* Start the timer and busy-wait for a bit with IRQs locked. The
* timer ought to have fired during this time if interrupts weren't
* locked -- but since they are, check_lock_new isn't updated.
*/
k_timer_start(&irqlock_timer, K_MSEC(DURATION), K_NO_WAIT);
k_busy_wait(TIMER_DELAY_US);
zassert_not_equal(handler_result, HANDLER_TOKEN,
"timer interrupt was serviced while interrupts are locked");
printk("unlocking interrupts\n");
irq_unlock(key);
k_busy_wait(TIMER_DELAY_US);
zassert_equal(handler_result, HANDLER_TOKEN,
"timer should have fired");
k_timer_stop(&irqlock_timer);
}
ZTEST_SUITE(interrupt_feature, NULL, NULL, NULL, NULL, NULL);