/* * Copyright (c) 2018 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ /* * @file * @brief Test early sleep functionality * * @defgroup kernel_earlysleep_tests Early Sleep Tests * * @ingroup all_tests * * This test verifies that k_sleep() can be used to put the calling thread to * sleep for a specified number of ticks during system initialization. In this * test we are calling k_sleep() at POST_KERNEL and APPLICATION level * initialization sequence. * * Note: We can not call k_sleep() during PRE_KERNEL1 or PRE_KERNEL2 level * because the core kernel objects and devices initialization happens at these * levels. * @{ * @} */ #include #include #include #include #include #include #define THREAD_STACK (384 + CONFIG_TEST_EXTRA_STACK_SIZE) #define TEST_TICKS_TO_SLEEP (CONFIG_SYS_CLOCK_TICKS_PER_SEC / 2) /* Helper thread data */ static K_THREAD_STACK_DEFINE(helper_tstack, THREAD_STACK); static struct k_thread helper_tdata; static k_tid_t helper_ttid; /* time that the thread was actually sleeping */ static int actual_sleep_ticks; static int actual_post_kernel_sleep_ticks; static int actual_app_sleep_ticks; static bool test_failure = true; static void helper_thread(void *p1, void *p2, void *p3) { test_failure = false; } static int ticks_to_sleep(int ticks) { uint32_t start_time; uint32_t stop_time; start_time = k_cycle_get_32(); k_sleep(K_MSEC(k_ticks_to_ms_floor64(ticks))); stop_time = k_cycle_get_32(); return (stop_time - start_time) / k_ticks_to_cyc_floor32(1); } static int test_early_sleep_post_kernel(void) { actual_post_kernel_sleep_ticks = ticks_to_sleep(TEST_TICKS_TO_SLEEP); return 0; } SYS_INIT(test_early_sleep_post_kernel, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); static int test_early_sleep_app(void) { actual_app_sleep_ticks = ticks_to_sleep(TEST_TICKS_TO_SLEEP); return 0; } SYS_INIT(test_early_sleep_app, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); /** * @brief Test early sleep * * @ingroup kernel_earlysleep_tests * * @see k_sleep() */ ZTEST(earlysleep, test_early_sleep) { TC_PRINT("Testing early sleeping\n"); /* * Main thread(test_main) priority is 0 but ztest thread runs at * priority -1. To run the test smoothly make both main and ztest * threads run at same priority level. */ k_thread_priority_set(k_current_get(), 0); TC_PRINT("msec per tick: %" PRId64 ".%03" PRId64 ", ticks to sleep: %d\n", k_ticks_to_ms_floor64(1000) / 1000U, k_ticks_to_ms_floor64(1000) % 1000, TEST_TICKS_TO_SLEEP); /* Create a lower priority thread */ helper_ttid = k_thread_create(&helper_tdata, helper_tstack, THREAD_STACK, helper_thread, NULL, NULL, NULL, k_thread_priority_get(k_current_get()) + 1, K_INHERIT_PERMS, K_NO_WAIT); TC_PRINT("k_sleep() ticks at POST_KERNEL level: %d\n", actual_post_kernel_sleep_ticks); zassert_true((actual_post_kernel_sleep_ticks + 1) > TEST_TICKS_TO_SLEEP, NULL); TC_PRINT("k_sleep() ticks at APPLICATION level: %d\n", actual_app_sleep_ticks); zassert_true((actual_app_sleep_ticks + 1) > TEST_TICKS_TO_SLEEP, NULL); actual_sleep_ticks = ticks_to_sleep(TEST_TICKS_TO_SLEEP); TC_PRINT("k_sleep() ticks on running system: %d\n", actual_sleep_ticks); zassert_true((actual_sleep_ticks + 1) > TEST_TICKS_TO_SLEEP, NULL); zassert_false(test_failure, "Lower priority thread not ran!!"); } ZTEST_SUITE(earlysleep, NULL, NULL, ztest_simple_1cpu_before, ztest_simple_1cpu_after, NULL);