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 | /* * Copyright (c) 2018 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ /* * @file * @brief Test early sleeping * * 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 50 /* 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) { u32_t start_time; u32_t stop_time; start_time = k_cycle_get_32(); k_sleep(__ticks_to_ms(ticks)); stop_time = k_cycle_get_32(); return (stop_time - start_time) / sys_clock_hw_cycles_per_tick; } static int test_early_sleep_post_kernel(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(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); static void verify_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: %d, ticks to sleep: %d\n", _ms_per_tick, 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, 0); 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_unit_test(verify_early_sleep)); ztest_run_test_suite(test_earlysleep); } |