/* * Copyright (c) 2019 Nordic Semiconductor * * SPDX-License-Identifier: Apache-2.0 */ /** * @file * @brief Test log immediate * */ #include #include #include #include #include #include #include #define LOG_MODULE_NAME test LOG_MODULE_REGISTER(LOG_MODULE_NAME); #define STACK_SIZE (1024 + CONFIG_TEST_EXTRA_STACK_SIZE) #define NUM_THREADS 5 K_THREAD_STACK_ARRAY_DEFINE(stacks, NUM_THREADS, STACK_SIZE); static struct k_thread threads[NUM_THREADS]; static k_tid_t tids[NUM_THREADS]; /* Thread entry point, used for multiple threads. Thread is logging some data * (data length varies for each thread) and sleeps. Threads have different * priorities so on wakeup other thread will be preempted, interrupting logging. */ static void thread_func(void *p1, void *p2, void *p3) { intptr_t id = (intptr_t)p1; int buf_len = 8*id + 8; uint8_t *buf = alloca(buf_len); while (1) { LOG_INF("test string printed %d %d %p", 1, 2, k_current_get()); LOG_HEXDUMP_INF(buf, buf_len, "data:"); k_msleep(20+id); } } /* * Test create number of threads with different priorities. Each thread logs * data and sleeps. This creates environment where multiple threads are * preempted during logging (in immediate mode). Test checks that system does * not hit any assert or other fault during frequent preemptions. */ ZTEST(log_immediate, test_log_immediate_preemption) { if (!IS_ENABLED(CONFIG_LOG_IMMEDIATE_CLEAN_OUTPUT)) { LOG_INF("CONFIG_LOG_IMMEDIATE_CLEAN_OUTPUT not enabled." " Text output will be garbled."); } for (intptr_t i = 0; i < NUM_THREADS; i++) { tids[i] = k_thread_create(&threads[i], stacks[i], STACK_SIZE, thread_func, (void *)i, NULL, NULL, k_thread_priority_get(k_current_get()) + i, 0, K_MSEC(10)); } k_msleep(3000); for (int i = 0; i < NUM_THREADS; i++) { k_thread_abort(tids[i]); } zassert_true(true, ""); } ZTEST_SUITE(log_immediate, NULL, NULL, NULL, NULL, NULL);