tests: add event test code
Adds both kernel and user space test code for the events API. Signed-off-by: Peter Mitsis <peter.mitsis@intel.com>
This commit is contained in:
parent
ae394bff7c
commit
10637afc00
9 changed files with 883 additions and 0 deletions
8
tests/kernel/events/event_api/CMakeLists.txt
Normal file
8
tests/kernel/events/event_api/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
||||||
|
project(events_api)
|
||||||
|
|
||||||
|
FILE(GLOB app_sources src/*.c)
|
||||||
|
target_sources(app PRIVATE ${app_sources})
|
3
tests/kernel/events/event_api/prj.conf
Normal file
3
tests/kernel/events/event_api/prj.conf
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
CONFIG_ZTEST=y
|
||||||
|
CONFIG_IRQ_OFFLOAD=y
|
||||||
|
CONFIG_EVENTS=y
|
40
tests/kernel/events/event_api/src/main.c
Normal file
40
tests/kernel/events/event_api/src/main.c
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021 Intel Corporation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Tests for the events kernel object
|
||||||
|
*
|
||||||
|
* Verify zephyr event apis under different context
|
||||||
|
*
|
||||||
|
* - API coverage
|
||||||
|
* -# k_event_init K_EVENT_DEFINE
|
||||||
|
* -# k_event_post
|
||||||
|
* -# k_event_set
|
||||||
|
* -# k_event_wait
|
||||||
|
* -# k_event_wait_all
|
||||||
|
*
|
||||||
|
* @defgroup kernel_event_tests events
|
||||||
|
* @ingroup all_tests
|
||||||
|
* @{
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ztest.h>
|
||||||
|
|
||||||
|
extern void test_k_event_init(void);
|
||||||
|
extern void test_event_deliver(void);
|
||||||
|
extern void test_event_receive(void);
|
||||||
|
|
||||||
|
/*test case main entry*/
|
||||||
|
|
||||||
|
void test_main(void)
|
||||||
|
{
|
||||||
|
ztest_test_suite(events_api,
|
||||||
|
ztest_1cpu_unit_test(test_k_event_init),
|
||||||
|
ztest_1cpu_unit_test(test_event_deliver),
|
||||||
|
ztest_1cpu_unit_test(test_event_receive));
|
||||||
|
ztest_run_test_suite(events_api);
|
||||||
|
}
|
398
tests/kernel/events/event_api/src/test_event_apis.c
Normal file
398
tests/kernel/events/event_api/src/test_event_apis.c
Normal file
|
@ -0,0 +1,398 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021 Intel Corporation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ztest.h>
|
||||||
|
#include <wait_q.h>
|
||||||
|
|
||||||
|
#define DELAY K_MSEC(50)
|
||||||
|
#define SHORT_TIMEOUT K_MSEC(100)
|
||||||
|
#define LONG_TIMEOUT K_MSEC(1000)
|
||||||
|
|
||||||
|
#define STACK_SIZE (512 + CONFIG_TEST_EXTRA_STACKSIZE)
|
||||||
|
|
||||||
|
static struct k_thread treceiver;
|
||||||
|
static struct k_thread textra1;
|
||||||
|
static struct k_thread textra2;
|
||||||
|
|
||||||
|
static K_THREAD_STACK_DEFINE(sreceiver, STACK_SIZE);
|
||||||
|
static K_THREAD_STACK_DEFINE(sextra1, STACK_SIZE);
|
||||||
|
static K_THREAD_STACK_DEFINE(sextra2, STACK_SIZE);
|
||||||
|
|
||||||
|
static K_EVENT_DEFINE(test_event);
|
||||||
|
static K_EVENT_DEFINE(sync_event);
|
||||||
|
|
||||||
|
static K_SEM_DEFINE(receiver_sem, 0, 1);
|
||||||
|
static K_SEM_DEFINE(sync_sem, 0, 1);
|
||||||
|
|
||||||
|
volatile static uint32_t test_events;
|
||||||
|
|
||||||
|
static void entry_extra1(void *p1, void *p2, void *p3)
|
||||||
|
{
|
||||||
|
uint32_t events;
|
||||||
|
|
||||||
|
events = k_event_wait_all(&sync_event, 0x33, true, K_FOREVER);
|
||||||
|
|
||||||
|
k_event_post(&test_event, events);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void entry_extra2(void *p1, void *p2, void *p3)
|
||||||
|
{
|
||||||
|
uint32_t events;
|
||||||
|
|
||||||
|
events = k_event_wait(&sync_event, 0x3300, true, K_FOREVER);
|
||||||
|
|
||||||
|
k_event_post(&test_event, events);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test the k_event_init() API.
|
||||||
|
*
|
||||||
|
* This is a white-box test to verify that the k_event_init() API initializes
|
||||||
|
* the fields of a k_event structure as expected.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void test_k_event_init(void)
|
||||||
|
{
|
||||||
|
struct k_event event;
|
||||||
|
struct k_thread *thread;
|
||||||
|
|
||||||
|
k_event_init(&event);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The type of wait queue used by the event may vary depending upon
|
||||||
|
* which kernel features have been enabled. As such, the most flexible
|
||||||
|
* useful check is to verify that the waitq is empty.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
thread = z_waitq_head(&event.wait_q);
|
||||||
|
|
||||||
|
zassert_is_null(thread, NULL);
|
||||||
|
zassert_true(event.events == 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void receive_existing_events(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Sync point 1-1 : test_event contains events 0x1234.
|
||||||
|
* Test for events 0x2448 (no waiting)--expect an error
|
||||||
|
*/
|
||||||
|
|
||||||
|
k_sem_take(&sync_sem, K_FOREVER);
|
||||||
|
test_events = k_event_wait(&test_event, 0x2448, false, K_NO_WAIT);
|
||||||
|
k_sem_give(&receiver_sem);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sync point 1-2 : test_event still contains event 0x1234.
|
||||||
|
* Test for events 0x2448 (with waiting)--expect an error
|
||||||
|
*/
|
||||||
|
|
||||||
|
k_sem_take(&sync_sem, K_FOREVER);
|
||||||
|
test_events = k_event_wait(&test_event, 0x2448, false, SHORT_TIMEOUT);
|
||||||
|
k_sem_give(&receiver_sem);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sync point 1-3: test_event still contains event 0x1234.
|
||||||
|
* Test for events 0x1235 (no waiting)--expect an error
|
||||||
|
*/
|
||||||
|
|
||||||
|
k_sem_take(&sync_sem, K_FOREVER);
|
||||||
|
test_events = k_event_wait_all(&test_event, 0x1235, false, K_NO_WAIT);
|
||||||
|
k_sem_give(&receiver_sem);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sync point 1-4: test_event still contains event 0x1234.
|
||||||
|
* Test for events 0x1235 (no waiting)--expect an error
|
||||||
|
*/
|
||||||
|
|
||||||
|
k_sem_take(&sync_sem, K_FOREVER);
|
||||||
|
test_events = k_event_wait_all(&test_event, 0x1235, false, K_NO_WAIT);
|
||||||
|
k_sem_give(&receiver_sem);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sync point 1-5: test_event still contains event 0x1234.
|
||||||
|
* Test for events 0x0235. Expect 0x0234 to be returned.
|
||||||
|
*/
|
||||||
|
|
||||||
|
k_sem_take(&sync_sem, K_FOREVER);
|
||||||
|
test_events = k_event_wait(&test_event, 0x0235, false, K_NO_WAIT);
|
||||||
|
k_sem_give(&receiver_sem);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sync point 1-6: test_event still contains event 0x1234.
|
||||||
|
* Test for events 0x1234. Expect 0x1234 to be returned.
|
||||||
|
*/
|
||||||
|
|
||||||
|
k_sem_take(&sync_sem, K_FOREVER);
|
||||||
|
test_events = k_event_wait_all(&test_event, 0x1234, false, K_NO_WAIT);
|
||||||
|
k_sem_give(&receiver_sem);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void reset_on_wait(void)
|
||||||
|
{
|
||||||
|
/* Sync point 2-1 */
|
||||||
|
|
||||||
|
k_sem_take(&sync_sem, K_FOREVER);
|
||||||
|
test_events = k_event_wait_all(&test_event, 0x1234, true,
|
||||||
|
SHORT_TIMEOUT);
|
||||||
|
k_sem_give(&receiver_sem);
|
||||||
|
|
||||||
|
/* Sync point 2-2 */
|
||||||
|
|
||||||
|
k_sem_take(&sync_sem, K_FOREVER);
|
||||||
|
test_events = k_event_wait(&test_event, 0x120000, true,
|
||||||
|
SHORT_TIMEOUT);
|
||||||
|
k_sem_give(&receiver_sem);
|
||||||
|
|
||||||
|
/* Sync point 2-3 */
|
||||||
|
|
||||||
|
k_sem_take(&sync_sem, K_FOREVER);
|
||||||
|
test_events = k_event_wait_all(&test_event, 0x248001, true,
|
||||||
|
SHORT_TIMEOUT);
|
||||||
|
k_sem_give(&receiver_sem);
|
||||||
|
|
||||||
|
/* Sync point 2-4 */
|
||||||
|
|
||||||
|
k_sem_take(&sync_sem, K_FOREVER);
|
||||||
|
test_events = k_event_wait(&test_event, 0x123458, true,
|
||||||
|
SHORT_TIMEOUT);
|
||||||
|
k_sem_give(&receiver_sem);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* receiver helper task
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void receiver(void *p1, void *p2, void *p3)
|
||||||
|
{
|
||||||
|
receive_existing_events();
|
||||||
|
|
||||||
|
reset_on_wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Works with receive_existing_events() to test the waiting for events
|
||||||
|
* when some events have already been sent. No additional events are sent
|
||||||
|
* to the event object during this block of testing.
|
||||||
|
*/
|
||||||
|
static void test_receive_existing_events(void)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sync point 1-1.
|
||||||
|
* K_NO_WAIT, k_event_wait(), no matches
|
||||||
|
*/
|
||||||
|
|
||||||
|
k_sem_give(&sync_sem);
|
||||||
|
rv = k_sem_take(&receiver_sem, LONG_TIMEOUT);
|
||||||
|
zassert_true(rv == 0, NULL);
|
||||||
|
zassert_true(test_events == 0, NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sync point 1-2.
|
||||||
|
* Short timeout, k_event_wait(), no expected matches
|
||||||
|
*/
|
||||||
|
|
||||||
|
k_sem_give(&sync_sem);
|
||||||
|
rv = k_sem_take(&receiver_sem, LONG_TIMEOUT);
|
||||||
|
zassert_true(rv == 0, NULL);
|
||||||
|
zassert_true(test_events == 0, NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sync point 1-3.
|
||||||
|
* K_NO_WAIT, k_event_wait_all(), incomplete match
|
||||||
|
*/
|
||||||
|
|
||||||
|
k_sem_give(&sync_sem);
|
||||||
|
rv = k_sem_take(&receiver_sem, LONG_TIMEOUT);
|
||||||
|
zassert_true(rv == 0, NULL);
|
||||||
|
zassert_true(test_events == 0, NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sync point 1-4.
|
||||||
|
* Short timeout, k_event_wait_all(), incomplete match
|
||||||
|
*/
|
||||||
|
|
||||||
|
k_sem_give(&sync_sem);
|
||||||
|
rv = k_sem_take(&receiver_sem, LONG_TIMEOUT);
|
||||||
|
zassert_true(rv == 0, NULL);
|
||||||
|
zassert_true(test_events == 0, NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sync point 1-5.
|
||||||
|
* Short timeout, k_event_wait_all(), incomplete match
|
||||||
|
*/
|
||||||
|
|
||||||
|
k_sem_give(&sync_sem);
|
||||||
|
rv = k_sem_take(&receiver_sem, LONG_TIMEOUT);
|
||||||
|
zassert_true(rv == 0, NULL);
|
||||||
|
zassert_true(test_events == 0x234, NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sync point 1-6.
|
||||||
|
* Short timeout, k_event_wait_all(), incomplete match
|
||||||
|
*/
|
||||||
|
|
||||||
|
k_sem_give(&sync_sem);
|
||||||
|
rv = k_sem_take(&receiver_sem, LONG_TIMEOUT);
|
||||||
|
zassert_true(rv == 0, NULL);
|
||||||
|
zassert_true(test_events == 0x1234, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Works with reset_on_wait() to verify that the events stored in the
|
||||||
|
* event object are reset at the appropriate time.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void test_reset_on_wait(void)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sync point 2-1. Reset events before receive.
|
||||||
|
* Short timeout, k_event_wait_all(), incomplete match
|
||||||
|
*/
|
||||||
|
|
||||||
|
k_sem_give(&sync_sem);
|
||||||
|
k_sleep(DELAY); /* Give receiver thread time to run */
|
||||||
|
k_event_post(&test_event, 0x123);
|
||||||
|
rv = k_sem_take(&receiver_sem, LONG_TIMEOUT);
|
||||||
|
zassert_true(rv == 0, NULL);
|
||||||
|
zassert_true(test_events == 0, NULL);
|
||||||
|
zassert_true(test_event.events == 0x123, NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sync point 2-2. Reset events before receive.
|
||||||
|
* Short timeout, k_event_wait(), no matches
|
||||||
|
*/
|
||||||
|
|
||||||
|
k_sem_give(&sync_sem);
|
||||||
|
k_sleep(DELAY);
|
||||||
|
k_event_post(&test_event, 0x248);
|
||||||
|
rv = k_sem_take(&receiver_sem, LONG_TIMEOUT);
|
||||||
|
zassert_true(rv == 0, NULL);
|
||||||
|
zassert_true(test_events == 0, NULL);
|
||||||
|
zassert_true(test_event.events == 0x248, NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sync point 2-3. Reset events before receive.
|
||||||
|
* Short timeout, k_event_wait_all(), complete match
|
||||||
|
*/
|
||||||
|
|
||||||
|
k_sem_give(&sync_sem);
|
||||||
|
k_sleep(DELAY);
|
||||||
|
k_event_post(&test_event, 0x248021);
|
||||||
|
rv = k_sem_take(&receiver_sem, LONG_TIMEOUT);
|
||||||
|
zassert_true(rv == 0, NULL);
|
||||||
|
zassert_true(test_events == 0x248001, NULL);
|
||||||
|
zassert_true(test_event.events == 0x248021, NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sync point 2-4. Reset events before receive.
|
||||||
|
* Short timeout, k_event_wait(), partial match
|
||||||
|
*/
|
||||||
|
|
||||||
|
k_sem_give(&sync_sem);
|
||||||
|
k_sleep(DELAY);
|
||||||
|
k_event_post(&test_event, 0x123456);
|
||||||
|
rv = k_sem_take(&receiver_sem, LONG_TIMEOUT);
|
||||||
|
zassert_true(rv == 0, NULL);
|
||||||
|
zassert_true(test_events == 0x123450, NULL);
|
||||||
|
zassert_true(test_event.events == 0x123456, NULL);
|
||||||
|
|
||||||
|
k_event_set(&test_event, 0x0); /* Reset events */
|
||||||
|
k_sem_give(&sync_sem);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_wake_multiple_threads(void)
|
||||||
|
{
|
||||||
|
uint32_t events;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The extra threads are expected to be waiting on <sync_event>
|
||||||
|
* Wake them both up.
|
||||||
|
*/
|
||||||
|
|
||||||
|
k_event_set(&sync_event, 0xfff);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The extra threads send back the events they received. Wait
|
||||||
|
* for all of them.
|
||||||
|
*/
|
||||||
|
|
||||||
|
events = k_event_wait_all(&test_event, 0x333, false, SHORT_TIMEOUT);
|
||||||
|
|
||||||
|
zassert_true(events == 0x333, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test basic k_event_post() and k_event_set() APIs.
|
||||||
|
*
|
||||||
|
* Tests the basic k_event_post() and k_event_set() APIs. This does not
|
||||||
|
* involve waking or receiving events.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void test_event_deliver(void)
|
||||||
|
{
|
||||||
|
struct k_event event;
|
||||||
|
uint32_t events;
|
||||||
|
|
||||||
|
k_event_init(&event);
|
||||||
|
|
||||||
|
zassert_true(event.events == 0, NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Verify k_event_post() and k_event_set() update the
|
||||||
|
* events stored in the event object as expected.
|
||||||
|
*/
|
||||||
|
|
||||||
|
events = 0xAAAA;
|
||||||
|
k_event_post(&event, events);
|
||||||
|
zassert_true(event.events == events, NULL);
|
||||||
|
|
||||||
|
events |= 0x55555ABC;
|
||||||
|
k_event_post(&event, events);
|
||||||
|
zassert_true(event.events == events, NULL);
|
||||||
|
|
||||||
|
events = 0xAAAA0000;
|
||||||
|
k_event_set(&event, events);
|
||||||
|
zassert_true(event.events == events, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test delivery and reception of events.
|
||||||
|
*
|
||||||
|
* Testing both the delivery and reception of events involves the use of
|
||||||
|
* multiple threads and uses the following event related APIs:
|
||||||
|
* k_event_post(), k_event_set(), k_event_wait() and k_event_wait_all().
|
||||||
|
*/
|
||||||
|
|
||||||
|
void test_event_receive(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Create helper threads */
|
||||||
|
|
||||||
|
k_event_set(&test_event, 0x1234);
|
||||||
|
|
||||||
|
(void) k_thread_create(&treceiver, sreceiver, STACK_SIZE,
|
||||||
|
receiver, NULL, NULL, NULL,
|
||||||
|
K_PRIO_PREEMPT(0), 0, K_NO_WAIT);
|
||||||
|
|
||||||
|
(void) k_thread_create(&textra1, sextra1, STACK_SIZE,
|
||||||
|
entry_extra1, NULL, NULL, NULL,
|
||||||
|
K_PRIO_PREEMPT(0), 0, K_NO_WAIT);
|
||||||
|
|
||||||
|
(void) k_thread_create(&textra2, sextra2, STACK_SIZE,
|
||||||
|
entry_extra2, NULL, NULL, NULL,
|
||||||
|
K_PRIO_PREEMPT(0), 0, K_NO_WAIT);
|
||||||
|
|
||||||
|
test_receive_existing_events();
|
||||||
|
|
||||||
|
test_reset_on_wait();
|
||||||
|
|
||||||
|
test_wake_multiple_threads();
|
||||||
|
}
|
8
tests/kernel/events/event_api/testcase.yaml
Normal file
8
tests/kernel/events/event_api/testcase.yaml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
tests:
|
||||||
|
kernel.events:
|
||||||
|
tags: kernel
|
||||||
|
kernel.events.linker_generator:
|
||||||
|
platform_allow: qemu_x86
|
||||||
|
tags: kernel linker_generator
|
||||||
|
extra_configs:
|
||||||
|
- CONFIG_CMAKE_LINKER_GENERATOR=y
|
8
tests/kernel/events/sys_event/CMakeLists.txt
Normal file
8
tests/kernel/events/sys_event/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
||||||
|
project(events)
|
||||||
|
|
||||||
|
FILE(GLOB app_sources src/*.c)
|
||||||
|
target_sources(app PRIVATE ${app_sources})
|
4
tests/kernel/events/sys_event/prj.conf
Normal file
4
tests/kernel/events/sys_event/prj.conf
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
CONFIG_ZTEST=y
|
||||||
|
CONFIG_TEST_USERSPACE=y
|
||||||
|
CONFIG_ZTEST_FATAL_HOOK=y
|
||||||
|
CONFIG_EVENTS=y
|
410
tests/kernel/events/sys_event/src/main.c
Normal file
410
tests/kernel/events/sys_event/src/main.c
Normal file
|
@ -0,0 +1,410 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021 Intel Corporation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ztest.h>
|
||||||
|
#include <ztest_error_hook.h>
|
||||||
|
|
||||||
|
/* Macro declarations */
|
||||||
|
|
||||||
|
#define DELAY K_MSEC(50)
|
||||||
|
#define SHORT_TIMEOUT K_MSEC(100)
|
||||||
|
#define LONG_TIMEOUT K_MSEC(1000)
|
||||||
|
|
||||||
|
#define STACK_SIZE (512 + CONFIG_TEST_EXTRA_STACKSIZE)
|
||||||
|
|
||||||
|
static struct k_thread treceiver;
|
||||||
|
static struct k_thread textra1;
|
||||||
|
static struct k_thread textra2;
|
||||||
|
|
||||||
|
static K_THREAD_STACK_DEFINE(sreceiver, STACK_SIZE);
|
||||||
|
static K_THREAD_STACK_DEFINE(sextra1, STACK_SIZE);
|
||||||
|
static K_THREAD_STACK_DEFINE(sextra2, STACK_SIZE);
|
||||||
|
|
||||||
|
static K_EVENT_DEFINE(test_event);
|
||||||
|
static K_EVENT_DEFINE(sync_event);
|
||||||
|
static struct k_event init_event;
|
||||||
|
static struct k_event deliver_event;
|
||||||
|
|
||||||
|
static K_SEM_DEFINE(receiver_sem, 0, 1);
|
||||||
|
static K_SEM_DEFINE(sync_sem, 0, 1);
|
||||||
|
|
||||||
|
volatile static uint32_t test_events;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup kernel_sys_events_tests Semaphore
|
||||||
|
* @ingroup all_tests
|
||||||
|
* @{
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void entry_extra1(void *p1, void *p2, void *p3)
|
||||||
|
{
|
||||||
|
uint32_t events;
|
||||||
|
|
||||||
|
events = k_event_wait_all(&sync_event, 0x33, true, K_FOREVER);
|
||||||
|
|
||||||
|
k_event_post(&test_event, events);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void entry_extra2(void *p1, void *p2, void *p3)
|
||||||
|
{
|
||||||
|
uint32_t events;
|
||||||
|
|
||||||
|
events = k_event_wait(&sync_event, 0x3300, true, K_FOREVER);
|
||||||
|
|
||||||
|
k_event_post(&test_event, events);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test the k_event_init() API.
|
||||||
|
*
|
||||||
|
* This is a white-box test to verify that the k_event_init() API initializes
|
||||||
|
* the fields of a k_event structure as expected.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void test_k_event_init(void)
|
||||||
|
{
|
||||||
|
k_event_init(&init_event);
|
||||||
|
|
||||||
|
zassert_true(init_event.events == 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void receive_existing_events(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Sync point 1-1 : test_event contains events 0x1234.
|
||||||
|
* Test for events 0x2448 (no waiting)--expect an error
|
||||||
|
*/
|
||||||
|
|
||||||
|
k_sem_take(&sync_sem, K_FOREVER);
|
||||||
|
test_events = k_event_wait(&test_event, 0x2448, false, K_NO_WAIT);
|
||||||
|
k_sem_give(&receiver_sem);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sync point 1-2 : test_event still contains event 0x1234.
|
||||||
|
* Test for events 0x2448 (with waiting)--expect an error
|
||||||
|
*/
|
||||||
|
|
||||||
|
k_sem_take(&sync_sem, K_FOREVER);
|
||||||
|
test_events = k_event_wait(&test_event, 0x2448, false, SHORT_TIMEOUT);
|
||||||
|
k_sem_give(&receiver_sem);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sync point 1-3: test_event still contains event 0x1234.
|
||||||
|
* Test for events 0x1235 (no waiting)--expect an error
|
||||||
|
*/
|
||||||
|
|
||||||
|
k_sem_take(&sync_sem, K_FOREVER);
|
||||||
|
test_events = k_event_wait_all(&test_event, 0x1235, false, K_NO_WAIT);
|
||||||
|
k_sem_give(&receiver_sem);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sync point 1-4: test_event still contains event 0x1234.
|
||||||
|
* Test for events 0x1235 (no waiting)--expect an error
|
||||||
|
*/
|
||||||
|
|
||||||
|
k_sem_take(&sync_sem, K_FOREVER);
|
||||||
|
test_events = k_event_wait_all(&test_event, 0x1235, false, K_NO_WAIT);
|
||||||
|
k_sem_give(&receiver_sem);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sync point 1-5: test_event still contains event 0x1234.
|
||||||
|
* Test for events 0x0235. Expect 0x0234 to be returned.
|
||||||
|
*/
|
||||||
|
|
||||||
|
k_sem_take(&sync_sem, K_FOREVER);
|
||||||
|
test_events = k_event_wait(&test_event, 0x0235, false, K_NO_WAIT);
|
||||||
|
k_sem_give(&receiver_sem);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sync point 1-6: test_event still contains event 0x1234.
|
||||||
|
* Test for events 0x1234. Expect 0x1234 to be returned.
|
||||||
|
*/
|
||||||
|
|
||||||
|
k_sem_take(&sync_sem, K_FOREVER);
|
||||||
|
test_events = k_event_wait_all(&test_event, 0x1234, false, K_NO_WAIT);
|
||||||
|
k_sem_give(&receiver_sem);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void reset_on_receive(void)
|
||||||
|
{
|
||||||
|
/* Sync point 2-1 - with reset */
|
||||||
|
|
||||||
|
k_sem_take(&sync_sem, K_FOREVER);
|
||||||
|
test_events = k_event_wait_all(&test_event, 0x1234, true,
|
||||||
|
SHORT_TIMEOUT);
|
||||||
|
k_sem_give(&receiver_sem);
|
||||||
|
|
||||||
|
/* Sync point 2-2 - with reset */
|
||||||
|
|
||||||
|
k_sem_take(&sync_sem, K_FOREVER);
|
||||||
|
test_events = k_event_wait(&test_event, 0x120000, true, SHORT_TIMEOUT);
|
||||||
|
k_sem_give(&receiver_sem);
|
||||||
|
|
||||||
|
/* Sync point 2-3 - with reset */
|
||||||
|
|
||||||
|
k_sem_take(&sync_sem, K_FOREVER);
|
||||||
|
test_events = k_event_wait_all(&test_event, 0x248001, true,
|
||||||
|
SHORT_TIMEOUT);
|
||||||
|
k_sem_give(&receiver_sem);
|
||||||
|
|
||||||
|
/* Sync point 2-4 - with reset */
|
||||||
|
|
||||||
|
k_sem_take(&sync_sem, K_FOREVER);
|
||||||
|
test_events = k_event_wait(&test_event, 0x123458, true,
|
||||||
|
SHORT_TIMEOUT);
|
||||||
|
k_sem_give(&receiver_sem);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* receiver helper task
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void receiver(void *p1, void *p2, void *p3)
|
||||||
|
{
|
||||||
|
receive_existing_events();
|
||||||
|
|
||||||
|
reset_on_receive();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Works with receive_existing_events() to test the waiting for events
|
||||||
|
* when some events have already been sent. No additional events are sent
|
||||||
|
* to the event object during this block of testing.
|
||||||
|
*/
|
||||||
|
static void test_receive_existing_events(void)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sync point 1-1.
|
||||||
|
* K_NO_WAIT, k_event_wait(), no matches
|
||||||
|
*/
|
||||||
|
|
||||||
|
k_sem_give(&sync_sem);
|
||||||
|
rv = k_sem_take(&receiver_sem, LONG_TIMEOUT);
|
||||||
|
zassert_true(rv == 0, NULL);
|
||||||
|
zassert_true(test_events == 0, NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sync point 1-2.
|
||||||
|
* Short timeout, k_event_wait(), no expected matches
|
||||||
|
*/
|
||||||
|
|
||||||
|
k_sem_give(&sync_sem);
|
||||||
|
rv = k_sem_take(&receiver_sem, LONG_TIMEOUT);
|
||||||
|
zassert_true(rv == 0, NULL);
|
||||||
|
zassert_true(test_events == 0, NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sync point 1-3.
|
||||||
|
* K_NO_WAIT, k_event_wait_all(), incomplete match
|
||||||
|
*/
|
||||||
|
|
||||||
|
k_sem_give(&sync_sem);
|
||||||
|
rv = k_sem_take(&receiver_sem, LONG_TIMEOUT);
|
||||||
|
zassert_true(rv == 0, NULL);
|
||||||
|
zassert_true(test_events == 0, NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sync point 1-4.
|
||||||
|
* Short timeout, k_event_wait_all(), incomplete match
|
||||||
|
*/
|
||||||
|
|
||||||
|
k_sem_give(&sync_sem);
|
||||||
|
rv = k_sem_take(&receiver_sem, LONG_TIMEOUT);
|
||||||
|
zassert_true(rv == 0, NULL);
|
||||||
|
zassert_true(test_events == 0, NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sync point 1-5.
|
||||||
|
* Short timeout, k_event_wait_all(), incomplete match
|
||||||
|
*/
|
||||||
|
|
||||||
|
k_sem_give(&sync_sem);
|
||||||
|
rv = k_sem_take(&receiver_sem, LONG_TIMEOUT);
|
||||||
|
zassert_true(rv == 0, NULL);
|
||||||
|
zassert_true(test_events == 0x234, NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sync point 1-6.
|
||||||
|
* Short timeout, k_event_wait_all(), incomplete match
|
||||||
|
*/
|
||||||
|
|
||||||
|
k_sem_give(&sync_sem);
|
||||||
|
rv = k_sem_take(&receiver_sem, LONG_TIMEOUT);
|
||||||
|
zassert_true(rv == 0, NULL);
|
||||||
|
zassert_true(test_events == 0x1234, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Works with reset_on_receive() to verify that the events stored in the
|
||||||
|
* event object are reset at the appropriate times.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void test_reset_on_receive(void)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sync point 2-1. Clear events before receive.
|
||||||
|
* Short timeout, k_event_wait_all(), incomplete match
|
||||||
|
*/
|
||||||
|
|
||||||
|
k_sem_give(&sync_sem);
|
||||||
|
k_sleep(DELAY); /* Give receiver thread time to run */
|
||||||
|
k_event_post(&test_event, 0x123);
|
||||||
|
rv = k_sem_take(&receiver_sem, LONG_TIMEOUT);
|
||||||
|
zassert_true(rv == 0, NULL);
|
||||||
|
zassert_true(test_events == 0, NULL);
|
||||||
|
zassert_true(test_event.events == 0x123, NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sync point 2-2. Clear events before receive.
|
||||||
|
* Short timeout, k_event_wait(), no matches
|
||||||
|
*/
|
||||||
|
|
||||||
|
k_sem_give(&sync_sem);
|
||||||
|
k_sleep(DELAY);
|
||||||
|
k_event_post(&test_event, 0x248);
|
||||||
|
rv = k_sem_take(&receiver_sem, LONG_TIMEOUT);
|
||||||
|
zassert_true(rv == 0, NULL);
|
||||||
|
zassert_true(test_events == 0, NULL);
|
||||||
|
zassert_true(test_event.events == 0x248, NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sync point 2-3. Clear events before receive.
|
||||||
|
* Short timeout, k_event_wait_all(), complete match
|
||||||
|
*/
|
||||||
|
|
||||||
|
k_sem_give(&sync_sem);
|
||||||
|
k_sleep(DELAY);
|
||||||
|
k_event_post(&test_event, 0x248021);
|
||||||
|
rv = k_sem_take(&receiver_sem, LONG_TIMEOUT);
|
||||||
|
zassert_true(rv == 0, NULL);
|
||||||
|
zassert_true(test_events == 0x248001, NULL);
|
||||||
|
zassert_true(test_event.events == 0x248021, NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sync point 2-4. Clear events before receive.
|
||||||
|
* Short timeout, k_event_wait(), partial match
|
||||||
|
*/
|
||||||
|
|
||||||
|
k_sem_give(&sync_sem);
|
||||||
|
k_sleep(DELAY);
|
||||||
|
k_event_post(&test_event, 0x123456);
|
||||||
|
rv = k_sem_take(&receiver_sem, LONG_TIMEOUT);
|
||||||
|
zassert_true(rv == 0, NULL);
|
||||||
|
zassert_true(test_events == 0x123450, NULL);
|
||||||
|
zassert_true(test_event.events == 0x123456, NULL);
|
||||||
|
|
||||||
|
k_event_set(&test_event, 0x0); /* Clear events */
|
||||||
|
|
||||||
|
k_sem_give(&sync_sem);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_wake_multiple_threads(void)
|
||||||
|
{
|
||||||
|
uint32_t events;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The extra threads are expected to be waiting on <sync_event>
|
||||||
|
* Wake them both up.
|
||||||
|
*/
|
||||||
|
|
||||||
|
k_event_set(&sync_event, 0xfff);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The extra threads send back the events they received. Wait
|
||||||
|
* for all of them.
|
||||||
|
*/
|
||||||
|
|
||||||
|
events = k_event_wait_all(&test_event, 0x333, false, SHORT_TIMEOUT);
|
||||||
|
|
||||||
|
zassert_true(events == 0x333, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test basic k_event_post() and k_event_set() APIs.
|
||||||
|
*
|
||||||
|
* Tests the basic k_event_post() and k_event_set() API. This does not
|
||||||
|
* involve waking or receiving events.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void test_event_deliver(void)
|
||||||
|
{
|
||||||
|
uint32_t events;
|
||||||
|
|
||||||
|
k_event_init(&deliver_event);
|
||||||
|
|
||||||
|
zassert_true(deliver_event.events == 0, NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Verify k_event_post() and k_event_set() update the
|
||||||
|
* events stored in the deliver_event object as expected.
|
||||||
|
*/
|
||||||
|
|
||||||
|
events = 0xAAAA;
|
||||||
|
k_event_post(&deliver_event, events);
|
||||||
|
zassert_true(deliver_event.events == events, NULL);
|
||||||
|
|
||||||
|
events |= 0x55555ABC;
|
||||||
|
k_event_post(&deliver_event, events);
|
||||||
|
zassert_true(deliver_event.events == events, NULL);
|
||||||
|
|
||||||
|
events = 0xAAAA0000;
|
||||||
|
k_event_set(&deliver_event, events);
|
||||||
|
zassert_true(deliver_event.events == events, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test delivery and reception of events.
|
||||||
|
*
|
||||||
|
* Testing both the delivery and reception of events involves the use of
|
||||||
|
* multiple threads and uses the following event related APIs:
|
||||||
|
* k_event_post(), k_event_set(), k_event_wait() and k_event_wait_all().
|
||||||
|
*/
|
||||||
|
|
||||||
|
void test_event_receive(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Create helper threads */
|
||||||
|
|
||||||
|
k_event_set(&test_event, 0x1234);
|
||||||
|
|
||||||
|
(void) k_thread_create(&treceiver, sreceiver, STACK_SIZE,
|
||||||
|
receiver, NULL, NULL, NULL,
|
||||||
|
K_PRIO_PREEMPT(0), 0, K_NO_WAIT);
|
||||||
|
|
||||||
|
(void) k_thread_create(&textra1, sextra1, STACK_SIZE,
|
||||||
|
entry_extra1, NULL, NULL, NULL,
|
||||||
|
K_PRIO_PREEMPT(0), 0, K_NO_WAIT);
|
||||||
|
|
||||||
|
(void) k_thread_create(&textra2, sextra2, STACK_SIZE,
|
||||||
|
entry_extra2, NULL, NULL, NULL,
|
||||||
|
K_PRIO_PREEMPT(0), 0, K_NO_WAIT);
|
||||||
|
|
||||||
|
test_receive_existing_events();
|
||||||
|
|
||||||
|
test_reset_on_receive();
|
||||||
|
|
||||||
|
test_wake_multiple_threads();
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_main(void)
|
||||||
|
{
|
||||||
|
k_thread_access_grant(k_current_get(), &treceiver, &textra1, &textra2,
|
||||||
|
&test_event, &sync_event,
|
||||||
|
&init_event, &deliver_event,
|
||||||
|
&receiver_sem, &sync_sem);
|
||||||
|
|
||||||
|
ztest_test_suite(sys_events,
|
||||||
|
ztest_1cpu_unit_test(test_k_event_init),
|
||||||
|
ztest_1cpu_unit_test(test_event_deliver),
|
||||||
|
ztest_1cpu_unit_test(test_event_receive));
|
||||||
|
|
||||||
|
ztest_run_test_suite(sys_events);
|
||||||
|
}
|
4
tests/kernel/events/sys_event/testcase.yaml
Normal file
4
tests/kernel/events/sys_event/testcase.yaml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
tests:
|
||||||
|
kernel.events.usage:
|
||||||
|
filter: CONFIG_ARCH_HAS_USERSPACE
|
||||||
|
tags: kernel userspace ignore_faults
|
Loading…
Add table
Add a link
Reference in a new issue