All stack sizes should end with STACK_SIZE. Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
84 lines
2.1 KiB
C
84 lines
2.1 KiB
C
/*
|
|
* Copyright (c) 2019 Nordic Semiconductor
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
/**
|
|
* @file
|
|
* @brief Test log immediate
|
|
*
|
|
*/
|
|
|
|
|
|
#include <tc_util.h>
|
|
#include <stdbool.h>
|
|
#include <zephyr.h>
|
|
#include <ztest.h>
|
|
#include <logging/log_backend.h>
|
|
#include <logging/log_ctrl.h>
|
|
#include <logging/log.h>
|
|
|
|
#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.
|
|
*/
|
|
static void test_log_immediate_preemption(void)
|
|
{
|
|
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, "");
|
|
}
|
|
|
|
/*test case main entry*/
|
|
void test_main(void)
|
|
{
|
|
ztest_test_suite(test_log_immediate,
|
|
ztest_unit_test(test_log_immediate_preemption));
|
|
ztest_run_test_suite(test_log_immediate);
|
|
}
|