Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | /* * 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 <init.h> #include <arch/cpu.h> #include <sys_clock.h> #include <stdbool.h> #include <tc_util.h> #include <ztest.h> #define THREAD_STACK (384 + CONFIG_TEST_EXTRA_STACKSIZE) #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(const struct device *unused) { ARG_UNUSED(unused); 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(const struct device *unused) { ARG_UNUSED(unused); 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() */ static void test_early_sleep(void) { 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!!"); } /*test case main entry*/ void test_main(void) { ztest_test_suite(test_earlysleep, ztest_1cpu_unit_test(test_early_sleep)); ztest_run_test_suite(test_earlysleep); } |