1 /*
2 * Copyright (c) 2019 Nordic Semiconductor
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /**
8 * @file
9 * @brief Test log immediate
10 *
11 */
12
13
14 #include <zephyr/tc_util.h>
15 #include <stdbool.h>
16 #include <zephyr/kernel.h>
17 #include <zephyr/ztest.h>
18 #include <zephyr/logging/log_backend.h>
19 #include <zephyr/logging/log_ctrl.h>
20 #include <zephyr/logging/log.h>
21
22 #define LOG_MODULE_NAME test
23 LOG_MODULE_REGISTER(LOG_MODULE_NAME);
24
25 #define STACK_SIZE (1024 + CONFIG_TEST_EXTRA_STACK_SIZE)
26
27 #define NUM_THREADS 5
28
29 K_THREAD_STACK_ARRAY_DEFINE(stacks, NUM_THREADS, STACK_SIZE);
30 static struct k_thread threads[NUM_THREADS];
31 static k_tid_t tids[NUM_THREADS];
32
33
34 /* Thread entry point, used for multiple threads. Thread is logging some data
35 * (data length varies for each thread) and sleeps. Threads have different
36 * priorities so on wakeup other thread will be preempted, interrupting logging.
37 */
thread_func(void * p1,void * p2,void * p3)38 static void thread_func(void *p1, void *p2, void *p3)
39 {
40 intptr_t id = (intptr_t)p1;
41 int buf_len = 8*id + 8;
42 uint8_t *buf = alloca(buf_len);
43
44 while (1) {
45 LOG_INF("test string printed %d %d %p", 1, 2, k_current_get());
46 LOG_HEXDUMP_INF(buf, buf_len, "data:");
47 k_msleep(20+id);
48 }
49 }
50
51 /*
52 * Test create number of threads with different priorities. Each thread logs
53 * data and sleeps. This creates environment where multiple threads are
54 * preempted during logging (in immediate mode). Test checks that system does
55 * not hit any assert or other fault during frequent preemptions.
56 */
ZTEST(log_immediate,test_log_immediate_preemption)57 ZTEST(log_immediate, test_log_immediate_preemption)
58 {
59 if (!IS_ENABLED(CONFIG_LOG_IMMEDIATE_CLEAN_OUTPUT)) {
60 LOG_INF("CONFIG_LOG_IMMEDIATE_CLEAN_OUTPUT not enabled."
61 " Text output will be garbled.");
62 }
63 for (intptr_t i = 0; i < NUM_THREADS; i++) {
64 tids[i] = k_thread_create(&threads[i], stacks[i], STACK_SIZE,
65 thread_func, (void *)i, NULL, NULL,
66 k_thread_priority_get(k_current_get()) + i,
67 0, K_MSEC(10));
68 }
69 k_msleep(3000);
70
71 for (int i = 0; i < NUM_THREADS; i++) {
72 k_thread_abort(tids[i]);
73 }
74 zassert_true(true, "");
75 }
76
77 ZTEST_SUITE(log_immediate, NULL, NULL, NULL, NULL, NULL);
78