test: Add nanokernel test_sleep project
The 'test_sleep' nanokernel project tests the following functionality: 1. Normal expiration of fiber_sleep() 2. Waking a sleeping fiber via fiber_fiber_wakeup() 3. Waking a sleeping fiber via isr_fiber_wakeup() 4. Waking a sleeping fiber via task_fiber_wakeup() 5. Normal expiration of task_sleep() Change-Id: Ie51997ace9a4413f62d77daacd6dff97b6b3a4dd Signed-off-by: Peter Mitsis <peter.mitsis@windriver.com>
This commit is contained in:
parent
b4313cef6f
commit
e0f8162a8b
5
tests/kernel/test_sleep/Makefile
Normal file
5
tests/kernel/test_sleep/Makefile
Normal file
|
@ -0,0 +1,5 @@
|
|||
KERNEL_TYPE = nano
|
||||
CONF_FILE = prj.conf
|
||||
BOARD ?= qemu_x86
|
||||
|
||||
include $(ZEPHYR_BASE)/Makefile.inc
|
45
tests/kernel/test_sleep/README.txt
Normal file
45
tests/kernel/test_sleep/README.txt
Normal file
|
@ -0,0 +1,45 @@
|
|||
Title: Nanokernel Sleep and Wakeup APIs
|
||||
|
||||
Description:
|
||||
|
||||
This test verifies that the nanokernel sleep and wakeup APIs operate as
|
||||
expected.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Building and Running Project:
|
||||
|
||||
This nanokernel project outputs to the console. It can be built and executed
|
||||
on QEMU as follows:
|
||||
|
||||
make qemu
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Troubleshooting:
|
||||
|
||||
Problems caused by out-dated project information can be addressed by
|
||||
issuing one of the following commands then rebuilding the project:
|
||||
|
||||
make clean # discard results of previous builds
|
||||
# but keep existing configuration info
|
||||
or
|
||||
make pristine # discard results of previous builds
|
||||
# and restore pre-defined configuration info
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Sample Output:
|
||||
|
||||
tc_start() - Test Nanokernel Sleep and Wakeup APIs
|
||||
|
||||
Nanokernel objects initialized
|
||||
Test fiber started: id = 0x001030b8
|
||||
Helper fiber started: id = 0x001028e8
|
||||
Testing normal expiration of fiber_sleep()
|
||||
Testing fiber_sleep() + fiber_fiber_wakeup()
|
||||
Testing fiber_sleep() + isr_fiber_wakeup()
|
||||
Testing fiber_sleep() + task_fiber_wakeup()
|
||||
Testing nanokernel task_sleep()
|
||||
===================================================================
|
||||
PROJECT EXECUTION SUCCESSFUL
|
6
tests/kernel/test_sleep/prj.conf
Normal file
6
tests/kernel/test_sleep/prj.conf
Normal file
|
@ -0,0 +1,6 @@
|
|||
# Let stack canaries use non-random number generator.
|
||||
# This option is NOT to be used in production code.
|
||||
|
||||
CONFIG_TEST_RANDOM_GENERATOR=y
|
||||
CONFIG_NANO_TIMEOUTS=y
|
||||
CONFIG_IRQ_OFFLOAD=y
|
3
tests/kernel/test_sleep/src/Makefile
Normal file
3
tests/kernel/test_sleep/src/Makefile
Normal file
|
@ -0,0 +1,3 @@
|
|||
ccflags-y += -I${srctree}/tests/include
|
||||
|
||||
obj-y = sleep.o
|
205
tests/kernel/test_sleep/src/sleep.c
Normal file
205
tests/kernel/test_sleep/src/sleep.c
Normal file
|
@ -0,0 +1,205 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Wind River Systems, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file
|
||||
* @brief Test nanokernel sleep and wakeup APIs
|
||||
*
|
||||
* This module tests the following sleep and wakeup scenarios:
|
||||
* 1. fiber_sleep() without cancellation
|
||||
* 2. fiber_sleep() cancelled via fiber_fiber_wakeup()
|
||||
* 3. fiber_sleep() cancelled via isr_fiber_wakeup()
|
||||
* 4. fiber_sleep() cancelled via task_fiber_wakeup()
|
||||
* 5. task_sleep() - no cancellation exists
|
||||
*/
|
||||
|
||||
#include <tc_util.h>
|
||||
#include <arch/cpu.h>
|
||||
#include <misc/util.h>
|
||||
#include <irq_offload.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <util_test_common.h>
|
||||
|
||||
#define FIBER_STACKSIZE 256
|
||||
|
||||
#define TEST_FIBER_PRIORITY 4
|
||||
#define HELPER_FIBER_PRIORITY 10
|
||||
|
||||
#define ONE_SECOND (sys_clock_ticks_per_sec)
|
||||
|
||||
static struct nano_sem test_fiber_sem;
|
||||
static struct nano_sem helper_fiber_sem;
|
||||
static struct nano_sem task_sem;
|
||||
|
||||
static char __stack test_fiber_stack[FIBER_STACKSIZE];
|
||||
static char __stack helper_fiber_stack[FIBER_STACKSIZE];
|
||||
|
||||
static nano_thread_id_t test_fiber_id;
|
||||
static nano_thread_id_t helper_fiber_id;
|
||||
|
||||
static bool test_failure = true; /* Assume the test will fail */
|
||||
|
||||
static void test_objects_init(void)
|
||||
{
|
||||
nano_sem_init(&test_fiber_sem);
|
||||
nano_sem_init(&helper_fiber_sem);
|
||||
nano_sem_init(&task_sem);
|
||||
|
||||
TC_PRINT("Nanokernel objects initialized\n");
|
||||
}
|
||||
|
||||
static void align_to_tick_boundary(void)
|
||||
{
|
||||
uint32_t tick;
|
||||
|
||||
tick = sys_tick_get_32();
|
||||
while (sys_tick_get_32() == tick) {
|
||||
/* Busy wait to align to tick boundary */
|
||||
}
|
||||
}
|
||||
|
||||
static void test_fiber(int arg1, int arg2)
|
||||
{
|
||||
uint32_t start_tick;
|
||||
uint32_t end_tick;
|
||||
|
||||
nano_fiber_sem_take(&test_fiber_sem, TICKS_UNLIMITED);
|
||||
|
||||
TC_PRINT("Testing normal expiration of fiber_sleep()\n");
|
||||
align_to_tick_boundary();
|
||||
|
||||
start_tick = sys_tick_get_32();
|
||||
fiber_sleep(ONE_SECOND);
|
||||
end_tick = sys_tick_get_32();
|
||||
|
||||
if (end_tick != start_tick + ONE_SECOND) {
|
||||
TC_ERROR(" *** fiber_sleep() slept for %d ticks not %d.",
|
||||
end_tick - start_tick, ONE_SECOND);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
TC_PRINT("Testing fiber_sleep() + fiber_fiber_wakeup()\n");
|
||||
nano_fiber_sem_give(&helper_fiber_sem); /* Activate helper fiber */
|
||||
align_to_tick_boundary();
|
||||
|
||||
start_tick = sys_tick_get_32();
|
||||
fiber_sleep(ONE_SECOND);
|
||||
end_tick = sys_tick_get_32();
|
||||
|
||||
if (end_tick > start_tick) {
|
||||
TC_ERROR(" *** fiber_fiber_wakeup() took too long (%d ticks)\n",
|
||||
end_tick - start_tick);
|
||||
return;
|
||||
}
|
||||
|
||||
TC_PRINT("Testing fiber_sleep() + isr_fiber_wakeup()\n");
|
||||
nano_fiber_sem_give(&helper_fiber_sem); /* Activate helper fiber */
|
||||
align_to_tick_boundary();
|
||||
|
||||
start_tick = sys_tick_get_32();
|
||||
fiber_sleep(ONE_SECOND);
|
||||
end_tick = sys_tick_get_32();
|
||||
|
||||
if (end_tick > start_tick) {
|
||||
TC_ERROR(" *** isr_fiber_wakeup() took too long (%d ticks)\n",
|
||||
end_tick - start_tick);
|
||||
return;
|
||||
}
|
||||
|
||||
TC_PRINT("Testing fiber_sleep() + task_fiber_wakeup()\n");
|
||||
nano_task_sem_give(&task_sem); /* Activate task */
|
||||
align_to_tick_boundary();
|
||||
|
||||
start_tick = sys_tick_get_32();
|
||||
fiber_sleep(ONE_SECOND); /* Task will execute */
|
||||
end_tick = sys_tick_get_32();
|
||||
|
||||
if (end_tick > start_tick) {
|
||||
TC_ERROR(" *** task_fiber_wakeup() took too long (%d ticks)\n",
|
||||
end_tick - start_tick);
|
||||
return;
|
||||
}
|
||||
|
||||
test_failure = false;
|
||||
}
|
||||
|
||||
static void irq_offload_isr(void *arg)
|
||||
{
|
||||
isr_fiber_wakeup((nano_thread_id_t) arg);
|
||||
}
|
||||
|
||||
static void helper_fiber(int arg1, int arg2)
|
||||
{
|
||||
nano_fiber_sem_take(&helper_fiber_sem, TICKS_UNLIMITED);
|
||||
|
||||
/* Wake the test fiber */
|
||||
fiber_fiber_wakeup(test_fiber_id);
|
||||
nano_fiber_sem_take(&helper_fiber_sem, TICKS_UNLIMITED);
|
||||
|
||||
/* Wake the test fiber from an ISR */
|
||||
irq_offload(irq_offload_isr, (void *)test_fiber_id);
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
int status = TC_FAIL;
|
||||
uint32_t start_tick;
|
||||
uint32_t end_tick;
|
||||
|
||||
TC_START("Test Nanokernel Sleep and Wakeup APIs\n");
|
||||
|
||||
test_objects_init();
|
||||
|
||||
test_fiber_id = task_fiber_start(test_fiber_stack, FIBER_STACKSIZE,
|
||||
test_fiber, 0, 0, TEST_FIBER_PRIORITY, 0);
|
||||
TC_PRINT("Test fiber started: id = 0x%x\n", test_fiber_id);
|
||||
|
||||
helper_fiber_id = task_fiber_start(helper_fiber_stack, FIBER_STACKSIZE,
|
||||
helper_fiber, 0, 0, HELPER_FIBER_PRIORITY, 0);
|
||||
TC_PRINT("Helper fiber started: id = 0x%x\n", helper_fiber_id);
|
||||
|
||||
/* Activate test_fiber */
|
||||
nano_task_sem_give(&test_fiber_sem);
|
||||
|
||||
/* Wait for test_fiber to activate us */
|
||||
nano_task_sem_take(&task_sem, TICKS_UNLIMITED);
|
||||
|
||||
/* Wake the test fiber */
|
||||
task_fiber_wakeup(test_fiber_id);
|
||||
|
||||
if (test_failure) {
|
||||
goto done_tests;
|
||||
}
|
||||
|
||||
TC_PRINT("Testing nanokernel task_sleep()\n");
|
||||
align_to_tick_boundary();
|
||||
start_tick = sys_tick_get_32();
|
||||
task_sleep(ONE_SECOND);
|
||||
end_tick = sys_tick_get_32();
|
||||
|
||||
if (end_tick - start_tick != ONE_SECOND) {
|
||||
TC_ERROR("task_sleep() slept for %d ticks, not %d\n",
|
||||
end_tick - start_tick, ONE_SECOND);
|
||||
goto done_tests;
|
||||
}
|
||||
|
||||
status = TC_PASS;
|
||||
|
||||
done_tests:
|
||||
TC_END_REPORT(status);
|
||||
}
|
2
tests/kernel/test_sleep/testcase.ini
Normal file
2
tests/kernel/test_sleep/testcase.ini
Normal file
|
@ -0,0 +1,2 @@
|
|||
[test]
|
||||
tags = core
|
Loading…
Reference in a new issue