2021-06-09 04:56:33 -07:00
|
|
|
|
|
|
|
<instance locked="false"
|
|
|
|
id="org.chibios.spc5.components.portable.chibios_unitary_tests_engine">
|
|
|
|
<description>
|
|
|
|
<brief>
|
|
|
|
<value>ChibiOS/RT Test Suite.</value>
|
|
|
|
</brief>
|
|
|
|
<copyright>
|
|
|
|
<value><![CDATA[/*
|
2020-07-12 06:15:38 -07:00
|
|
|
ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
|
|
|
|
|
|
|
|
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.
|
2016-03-20 04:15:33 -07:00
|
|
|
*/]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</copyright>
|
|
|
|
<introduction>
|
|
|
|
<value>Test suite for ChibiOS/RT. The purpose of this suite is to
|
|
|
|
perform unit tests on the RT modules and to converge to 100%
|
|
|
|
code coverage through successive improvements.</value>
|
|
|
|
</introduction>
|
|
|
|
</description>
|
|
|
|
<global_data_and_code>
|
|
|
|
<code_prefix>
|
|
|
|
<value>rt_</value>
|
|
|
|
</code_prefix>
|
|
|
|
<global_definitions>
|
|
|
|
<value><![CDATA[/*
|
2020-07-12 06:15:38 -07:00
|
|
|
* Allowed delay in timeout checks.
|
|
|
|
*/
|
2021-05-31 02:47:39 -07:00
|
|
|
#if CH_CFG_ST_TIMEDELTA == 0
|
|
|
|
#define ALLOWED_DELAY 2
|
|
|
|
#else
|
2021-06-05 00:23:44 -07:00
|
|
|
#define ALLOWED_DELAY TIME_MS2I(2)
|
2021-05-31 02:47:39 -07:00
|
|
|
#endif
|
2020-07-12 06:15:38 -07:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Maximum number of test threads.
|
|
|
|
*/
|
|
|
|
#define MAX_THREADS 5
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Stack size of test threads.
|
|
|
|
*/
|
|
|
|
#if defined(PORT_ARCHITECTURE_AVR) || defined(PORT__ARCHITECTURE_MSP430)
|
|
|
|
#define THREADS_STACK_SIZE 48
|
|
|
|
#elif defined(PORT__ARCHITECTURE_STM8)
|
|
|
|
#define THREADS_STACK_SIZE 64
|
|
|
|
#elif defined(PORT__ARCHITECTURE_SIMIA32)
|
|
|
|
#define THREADS_STACK_SIZE 512
|
|
|
|
#else
|
|
|
|
#define THREADS_STACK_SIZE 128
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Working Area size of test threads.
|
|
|
|
*/
|
|
|
|
#define WA_SIZE MEM_ALIGN_NEXT(THD_WORKING_AREA_SIZE(THREADS_STACK_SIZE), \
|
|
|
|
PORT_WORKING_AREA_ALIGN)
|
|
|
|
|
|
|
|
extern uint8_t test_buffer[WA_SIZE * 5];
|
|
|
|
extern thread_t *threads[MAX_THREADS];
|
|
|
|
extern void * ROMCONST wa[5];
|
|
|
|
|
|
|
|
void test_print_port_info(void);
|
|
|
|
void test_terminate_threads(void);
|
|
|
|
void test_wait_threads(void);
|
2016-03-29 05:36:24 -07:00
|
|
|
systime_t test_wait_tick(void);]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</global_definitions>
|
|
|
|
<global_code>
|
|
|
|
<value><![CDATA[/*
|
2020-07-12 06:15:38 -07:00
|
|
|
* Global test buffer holding 5 working areas.
|
|
|
|
*/
|
|
|
|
ALIGNED_VAR(PORT_WORKING_AREA_ALIGN) uint8_t test_buffer[WA_SIZE * 5];
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Pointers to the spawned threads.
|
|
|
|
*/
|
|
|
|
thread_t *threads[MAX_THREADS];
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Pointers to the working areas.
|
|
|
|
*/
|
|
|
|
void * ROMCONST wa[5] = {test_buffer + (WA_SIZE * 0),
|
|
|
|
test_buffer + (WA_SIZE * 1),
|
|
|
|
test_buffer + (WA_SIZE * 2),
|
|
|
|
test_buffer + (WA_SIZE * 3),
|
|
|
|
test_buffer + (WA_SIZE * 4)};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Sets a termination request in all the test-spawned threads.
|
|
|
|
*/
|
|
|
|
void test_terminate_threads(void) {
|
|
|
|
unsigned i;
|
|
|
|
|
|
|
|
for (i = 0; i < MAX_THREADS; i++)
|
|
|
|
if (threads[i])
|
|
|
|
chThdTerminate(threads[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Waits for the completion of all the test-spawned threads.
|
|
|
|
*/
|
|
|
|
void test_wait_threads(void) {
|
|
|
|
unsigned i;
|
|
|
|
|
|
|
|
for (i = 0; i < MAX_THREADS; i++)
|
|
|
|
if (threads[i] != NULL) {
|
|
|
|
chThdWait(threads[i]);
|
|
|
|
threads[i] = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Delays execution until next system time tick.
|
|
|
|
*/
|
|
|
|
systime_t test_wait_tick(void) {
|
|
|
|
|
|
|
|
chThdSleep(1);
|
|
|
|
return chVTGetSystemTime();
|
2016-03-20 08:41:04 -07:00
|
|
|
}]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</global_code>
|
|
|
|
</global_data_and_code>
|
|
|
|
<sequences>
|
|
|
|
<sequence>
|
|
|
|
<type index="0">
|
|
|
|
<value>Internal Tests</value>
|
|
|
|
</type>
|
|
|
|
<brief>
|
|
|
|
<value>Information.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>This sequence reports configuration and version
|
|
|
|
information about the RT kernel.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<shared_code>
|
|
|
|
<value><![CDATA[#include "ch.h"]]></value>
|
|
|
|
</shared_code>
|
|
|
|
<cases>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Port Info.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>Port-related info are reported.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value />
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
2017-09-17 08:38:40 -07:00
|
|
|
<value />
|
2021-06-09 04:56:33 -07:00
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Prints the version string.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[#if defined(PORT_ARCHITECTURE_NAME)
|
2017-12-10 06:16:32 -08:00
|
|
|
test_print("--- Architecture: ");
|
2017-12-07 00:55:48 -08:00
|
|
|
test_println(PORT_ARCHITECTURE_NAME);
|
|
|
|
#endif
|
2017-12-10 06:16:32 -08:00
|
|
|
#if defined(PORT_CORE_VARIANT_NAME)
|
|
|
|
test_print("--- Core Variant: ");
|
|
|
|
test_println(PORT_CORE_VARIANT_NAME);
|
|
|
|
#endif
|
2017-12-07 00:55:48 -08:00
|
|
|
#if defined(PORT_COMPILER_NAME)
|
2017-12-10 06:16:32 -08:00
|
|
|
test_print("--- Compiler: ");
|
2017-12-07 00:55:48 -08:00
|
|
|
test_println(PORT_COMPILER_NAME);
|
|
|
|
#endif
|
2017-12-10 06:16:32 -08:00
|
|
|
#if defined(PORT_INFO)
|
|
|
|
test_print("--- Port Info: ");
|
|
|
|
test_println(PORT_INFO);
|
|
|
|
#endif
|
2017-12-07 00:55:48 -08:00
|
|
|
#if defined(PORT_NATURAL_ALIGN)
|
2017-12-10 06:16:32 -08:00
|
|
|
test_print("--- Natural alignment: ");
|
2017-12-07 00:55:48 -08:00
|
|
|
test_printn(PORT_NATURAL_ALIGN);
|
|
|
|
test_println("");
|
|
|
|
#endif
|
|
|
|
#if defined(PORT_STACK_ALIGN)
|
2017-12-10 06:16:32 -08:00
|
|
|
test_print("--- Stack alignment: ");
|
2017-12-07 00:55:48 -08:00
|
|
|
test_printn(PORT_STACK_ALIGN);
|
|
|
|
test_println("");
|
|
|
|
#endif
|
|
|
|
#if defined(PORT_WORKING_AREA_ALIGN)
|
2017-12-10 06:16:32 -08:00
|
|
|
test_print("--- Working area alignment: ");
|
2017-12-07 00:55:48 -08:00
|
|
|
test_printn(PORT_WORKING_AREA_ALIGN);
|
|
|
|
test_println("");
|
|
|
|
#endif]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Kernel Info.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>The version numbers are reported.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value />
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value />
|
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Prints the version string.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[
|
2020-07-12 06:15:38 -07:00
|
|
|
test_println("--- Product: ChibiOS/RT");
|
|
|
|
test_print("--- Stable Flag: ");
|
|
|
|
test_printn(CH_KERNEL_STABLE);
|
|
|
|
test_println("");
|
|
|
|
test_print("--- Version String: ");
|
|
|
|
test_println(CH_KERNEL_VERSION);
|
|
|
|
test_print("--- Major Number: ");
|
|
|
|
test_printn(CH_KERNEL_MAJOR);
|
|
|
|
test_println("");
|
|
|
|
test_print("--- Minor Number: ");
|
|
|
|
test_printn(CH_KERNEL_MINOR);
|
|
|
|
test_println("");
|
|
|
|
test_print("--- Patch Number: ");
|
|
|
|
test_printn(CH_KERNEL_PATCH);
|
2017-09-17 08:38:40 -07:00
|
|
|
test_println("");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Kernel Settings.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>The static kernel settings are reported.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value />
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value />
|
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Prints the configuration options settings.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[test_print("--- CH_CFG_ST_RESOLUTION: ");
|
2020-07-12 06:15:38 -07:00
|
|
|
test_printn(CH_CFG_ST_RESOLUTION);
|
|
|
|
test_println("");
|
|
|
|
test_print("--- CH_CFG_ST_FREQUENCY: ");
|
|
|
|
test_printn(CH_CFG_ST_FREQUENCY);
|
|
|
|
test_println("");
|
2017-12-10 06:16:32 -08:00
|
|
|
test_print("--- CH_CFG_INTERVALS_SIZE: ");
|
|
|
|
test_printn(CH_CFG_INTERVALS_SIZE);
|
|
|
|
test_println("");
|
|
|
|
test_print("--- CH_CFG_TIME_TYPES_SIZE: ");
|
|
|
|
test_printn(CH_CFG_TIME_TYPES_SIZE);
|
|
|
|
test_println("");
|
2020-07-12 06:15:38 -07:00
|
|
|
test_print("--- CH_CFG_ST_TIMEDELTA: ");
|
|
|
|
test_printn(CH_CFG_ST_TIMEDELTA);
|
|
|
|
test_println("");
|
|
|
|
test_print("--- CH_CFG_TIME_QUANTUM: ");
|
|
|
|
test_printn(CH_CFG_TIME_QUANTUM);
|
|
|
|
test_println("");
|
|
|
|
test_print("--- CH_CFG_MEMCORE_SIZE: ");
|
|
|
|
test_printn(CH_CFG_MEMCORE_SIZE);
|
|
|
|
test_println("");
|
|
|
|
test_print("--- CH_CFG_NO_IDLE_THREAD: ");
|
|
|
|
test_printn(CH_CFG_NO_IDLE_THREAD);
|
|
|
|
test_println("");
|
|
|
|
test_print("--- CH_CFG_OPTIMIZE_SPEED: ");
|
|
|
|
test_printn(CH_CFG_OPTIMIZE_SPEED);
|
|
|
|
test_println("");
|
|
|
|
test_print("--- CH_CFG_USE_TM: ");
|
|
|
|
test_printn(CH_CFG_USE_TM);
|
|
|
|
test_println("");
|
|
|
|
test_print("--- CH_CFG_USE_REGISTRY: ");
|
|
|
|
test_printn(CH_CFG_USE_REGISTRY);
|
|
|
|
test_println("");
|
|
|
|
test_print("--- CH_CFG_USE_WAITEXIT: ");
|
|
|
|
test_printn(CH_CFG_USE_WAITEXIT);
|
|
|
|
test_println("");
|
|
|
|
test_print("--- CH_CFG_USE_SEMAPHORES: ");
|
|
|
|
test_printn(CH_CFG_USE_SEMAPHORES);
|
|
|
|
test_println("");
|
|
|
|
test_print("--- CH_CFG_USE_SEMAPHORES_PRIORITY: ");
|
|
|
|
test_printn(CH_CFG_USE_SEMAPHORES_PRIORITY);
|
|
|
|
test_println("");
|
|
|
|
test_print("--- CH_CFG_USE_MUTEXES: ");
|
|
|
|
test_printn(CH_CFG_USE_MUTEXES);
|
|
|
|
test_println("");
|
|
|
|
test_print("--- CH_CFG_USE_MUTEXES_RECURSIVE: ");
|
|
|
|
test_printn(CH_CFG_USE_MUTEXES_RECURSIVE);
|
|
|
|
test_println("");
|
|
|
|
test_print("--- CH_CFG_USE_CONDVARS: ");
|
|
|
|
test_printn(CH_CFG_USE_CONDVARS);
|
|
|
|
test_println("");
|
|
|
|
test_print("--- CH_CFG_USE_CONDVARS_TIMEOUT: ");
|
|
|
|
test_printn(CH_CFG_USE_CONDVARS_TIMEOUT);
|
|
|
|
test_println("");
|
|
|
|
test_print("--- CH_CFG_USE_EVENTS: ");
|
|
|
|
test_printn(CH_CFG_USE_EVENTS);
|
|
|
|
test_println("");
|
|
|
|
test_print("--- CH_CFG_USE_EVENTS_TIMEOUT: ");
|
|
|
|
test_printn(CH_CFG_USE_EVENTS_TIMEOUT);
|
|
|
|
test_println("");
|
|
|
|
test_print("--- CH_CFG_USE_MESSAGES: ");
|
|
|
|
test_printn(CH_CFG_USE_MESSAGES);
|
|
|
|
test_println("");
|
|
|
|
test_print("--- CH_CFG_USE_MESSAGES_PRIORITY: ");
|
|
|
|
test_printn(CH_CFG_USE_MESSAGES_PRIORITY);
|
2017-12-10 06:16:32 -08:00
|
|
|
test_println("");
|
|
|
|
test_print("--- CH_CFG_USE_DYNAMIC: ");
|
|
|
|
test_printn(CH_CFG_USE_DYNAMIC);
|
|
|
|
test_println("");
|
2020-07-12 06:15:38 -07:00
|
|
|
test_print("--- CH_DBG_STATISTICS: ");
|
|
|
|
test_printn(CH_DBG_STATISTICS);
|
|
|
|
test_println("");
|
|
|
|
test_print("--- CH_DBG_SYSTEM_STATE_CHECK: ");
|
|
|
|
test_printn(CH_DBG_SYSTEM_STATE_CHECK);
|
|
|
|
test_println("");
|
|
|
|
test_print("--- CH_DBG_ENABLE_CHECKS: ");
|
|
|
|
test_printn(CH_DBG_ENABLE_CHECKS);
|
|
|
|
test_println("");
|
|
|
|
test_print("--- CH_DBG_ENABLE_ASSERTS: ");
|
|
|
|
test_printn(CH_DBG_ENABLE_ASSERTS);
|
|
|
|
test_println("");
|
|
|
|
test_print("--- CH_DBG_TRACE_MASK: ");
|
|
|
|
test_printn(CH_DBG_TRACE_MASK);
|
|
|
|
test_println("");
|
|
|
|
test_print("--- CH_DBG_TRACE_BUFFER_SIZE: ");
|
|
|
|
test_printn(CH_DBG_TRACE_BUFFER_SIZE);
|
|
|
|
test_println("");
|
|
|
|
test_print("--- CH_DBG_ENABLE_STACK_CHECK: ");
|
|
|
|
test_printn(CH_DBG_ENABLE_STACK_CHECK);
|
|
|
|
test_println("");
|
|
|
|
test_print("--- CH_DBG_FILL_THREADS: ");
|
|
|
|
test_printn(CH_DBG_FILL_THREADS);
|
|
|
|
test_println("");
|
|
|
|
test_print("--- CH_DBG_THREADS_PROFILING: ");
|
|
|
|
test_printn(CH_DBG_THREADS_PROFILING);
|
2017-09-17 08:38:40 -07:00
|
|
|
test_println("");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
</cases>
|
|
|
|
</sequence>
|
|
|
|
<sequence>
|
|
|
|
<type index="0">
|
|
|
|
<value>Internal Tests</value>
|
|
|
|
</type>
|
|
|
|
<brief>
|
|
|
|
<value>System layer and port interface.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>The functionality of the system layer and port interface
|
|
|
|
is tested. Basic RT functionality is taken for granted or this
|
|
|
|
test suite could not even be executed. Errors in
|
|
|
|
implementation are detected by executing this sequence with
|
|
|
|
the state checker enabled (CH_DBG_STATE_CHECKER=TRUE).</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<shared_code>
|
|
|
|
<value><![CDATA[/* Timer callback for testing system functions in ISR context.*/
|
2021-05-07 04:30:54 -07:00
|
|
|
static void vtcb(virtual_timer_t *vtp, void *p) {
|
2020-07-12 06:15:38 -07:00
|
|
|
syssts_t sts;
|
|
|
|
|
2021-05-07 04:30:54 -07:00
|
|
|
(void)vtp;
|
2020-07-12 06:15:38 -07:00
|
|
|
(void)p;
|
|
|
|
|
|
|
|
/* Testing normal case.*/
|
|
|
|
chSysLockFromISR();
|
|
|
|
chSysUnlockFromISR();
|
|
|
|
|
|
|
|
/* Reentrant case.*/
|
|
|
|
chSysLockFromISR();
|
|
|
|
sts = chSysGetStatusAndLockX();
|
|
|
|
chSysRestoreStatusX(sts);
|
|
|
|
chSysUnlockFromISR();
|
2016-03-20 04:15:33 -07:00
|
|
|
}]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</shared_code>
|
|
|
|
<cases>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>System integrity functionality.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>The system self-test functionality is invoked in
|
|
|
|
order to make an initial system state assessment and for
|
|
|
|
coverage.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value />
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value><![CDATA[bool result;]]></value>
|
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Testing Ready List integrity.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chSysLock();
|
2020-07-12 06:15:38 -07:00
|
|
|
result = chSysIntegrityCheckI(CH_INTEGRITY_RLIST);
|
|
|
|
chSysUnlock();
|
2016-03-20 04:37:22 -07:00
|
|
|
test_assert(result == false, "ready list check failed");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Testing Virtual Timers List integrity.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chSysLock();
|
2020-07-12 06:15:38 -07:00
|
|
|
result = chSysIntegrityCheckI(CH_INTEGRITY_VTLIST);
|
|
|
|
chSysUnlock();
|
2016-03-20 04:37:22 -07:00
|
|
|
test_assert(result == false, "virtual timers list check failed");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Testing Registry List integrity.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chSysLock();
|
2020-07-12 06:15:38 -07:00
|
|
|
result = chSysIntegrityCheckI(CH_INTEGRITY_REGISTRY);
|
|
|
|
chSysUnlock();
|
2016-03-20 04:37:22 -07:00
|
|
|
test_assert(result == false, "registry list check failed");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Testing Port-defined integrity.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chSysLock();
|
2020-07-12 06:15:38 -07:00
|
|
|
result = chSysIntegrityCheckI(CH_INTEGRITY_PORT);
|
|
|
|
chSysUnlock();
|
2016-03-20 04:37:22 -07:00
|
|
|
test_assert(result == false, "port layer check failed");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Critical zones functionality.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>The critical zones API is invoked for coverage.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value />
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value><![CDATA[syssts_t sts;
|
2016-03-20 04:15:33 -07:00
|
|
|
virtual_timer_t vt;]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Testing chSysGetStatusAndLockX() and
|
|
|
|
chSysRestoreStatusX(), non reentrant case.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[sts = chSysGetStatusAndLockX();
|
2016-03-20 04:15:33 -07:00
|
|
|
chSysRestoreStatusX(sts);]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Testing chSysGetStatusAndLockX() and
|
|
|
|
chSysRestoreStatusX(), reentrant case.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chSysLock();
|
2020-07-12 06:15:38 -07:00
|
|
|
sts = chSysGetStatusAndLockX();
|
|
|
|
chSysRestoreStatusX(sts);
|
2016-03-20 04:15:33 -07:00
|
|
|
chSysUnlock();]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Testing chSysUnconditionalLock().</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chSysUnconditionalLock();
|
2020-07-12 06:15:38 -07:00
|
|
|
chSysUnconditionalLock();
|
2016-03-20 04:15:33 -07:00
|
|
|
chSysUnlock();]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Testing chSysUnconditionalUnlock().</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chSysLock();
|
2020-07-12 06:15:38 -07:00
|
|
|
chSysUnconditionalUnlock();
|
2016-03-20 04:15:33 -07:00
|
|
|
chSysUnconditionalUnlock();]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Testing from ISR context using a virtual timer.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chVTObjectInit(&vt);
|
2020-07-12 06:15:38 -07:00
|
|
|
chVTSet(&vt, 1, vtcb, NULL);
|
|
|
|
chThdSleep(10);
|
|
|
|
|
2016-03-20 04:15:33 -07:00
|
|
|
test_assert(chVTIsArmed(&vt) == false, "timer still armed");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Interrupts handling functionality.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>The interrupts handling API is invoked for coverage.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value />
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value />
|
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Testing chSysSuspend(), chSysDisable() and
|
|
|
|
chSysEnable().</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chSysSuspend();
|
2020-07-12 06:15:38 -07:00
|
|
|
chSysDisable();
|
|
|
|
chSysSuspend();
|
2016-03-20 04:37:22 -07:00
|
|
|
chSysEnable();]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
</cases>
|
|
|
|
</sequence>
|
|
|
|
<sequence>
|
|
|
|
<type index="0">
|
|
|
|
<value>Internal Tests</value>
|
|
|
|
</type>
|
|
|
|
<brief>
|
|
|
|
<value>Time and Intervals Functionality.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>This sequence tests the ChibiOS/RT functionalities
|
|
|
|
related to time and intervals management.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<shared_code>
|
|
|
|
<value><![CDATA[#include "ch.h"]]></value>
|
|
|
|
</shared_code>
|
|
|
|
<cases>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>System Tick Counter functionality.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>The functionality of the API @p chVTGetSystemTimeX()
|
|
|
|
is tested.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value />
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
2019-11-24 08:05:48 -08:00
|
|
|
<value />
|
2021-06-09 04:56:33 -07:00
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value />
|
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>A System Tick Counter increment is expected, the
|
|
|
|
test simply hangs if it does not happen.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[systime_t time = chVTGetSystemTimeX();
|
2019-11-24 08:05:48 -08:00
|
|
|
while (time == chVTGetSystemTimeX()) {
|
2020-03-15 02:33:02 -07:00
|
|
|
#if defined(SIMULATOR)
|
|
|
|
_sim_check_for_interrupts();
|
|
|
|
#endif
|
2016-03-20 04:15:33 -07:00
|
|
|
}]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Time ranges functionality.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>The functionality of the API @p chTimeIsInRangeX() is
|
|
|
|
tested.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value />
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value />
|
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Checking case where start == end, it must always
|
|
|
|
evaluate as not in range.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[
|
2019-11-24 08:05:48 -08:00
|
|
|
bool b;
|
|
|
|
|
|
|
|
b = chTimeIsInRangeX((systime_t)0, (systime_t)0, (systime_t)0);
|
2019-12-31 03:40:58 -08:00
|
|
|
test_assert(b == false, "in range");
|
2019-11-24 08:05:48 -08:00
|
|
|
b = chTimeIsInRangeX((systime_t)-1, (systime_t)0, (systime_t)0);
|
2019-12-31 03:40:58 -08:00
|
|
|
test_assert(b == false, "in range");
|
2019-11-24 08:05:48 -08:00
|
|
|
b = chTimeIsInRangeX((systime_t)0, (systime_t)-1, (systime_t)-1);
|
2019-12-31 03:40:58 -08:00
|
|
|
test_assert(b == false, "in range");
|
2019-11-24 08:05:48 -08:00
|
|
|
b = chTimeIsInRangeX((systime_t)-1, (systime_t)-1, (systime_t)-1);
|
2019-12-31 03:40:58 -08:00
|
|
|
test_assert(b == false, "in range");
|
2019-11-24 08:05:48 -08:00
|
|
|
]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Checking boundaries for start < end.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[
|
2019-11-24 08:05:48 -08:00
|
|
|
bool b;
|
|
|
|
|
|
|
|
b = chTimeIsInRangeX((systime_t)10, (systime_t)10, (systime_t)100);
|
|
|
|
test_assert(b == true, "not in range");
|
|
|
|
b = chTimeIsInRangeX((systime_t)9, (systime_t)10, (systime_t)100);
|
|
|
|
test_assert(b == false, "in range");
|
|
|
|
b = chTimeIsInRangeX((systime_t)99, (systime_t)10, (systime_t)100);
|
|
|
|
test_assert(b == true, "not in range");
|
|
|
|
b = chTimeIsInRangeX((systime_t)100, (systime_t)10, (systime_t)100);
|
|
|
|
test_assert(b == false, "in range");
|
|
|
|
]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Checking boundaries for start > end.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[
|
2019-11-24 08:05:48 -08:00
|
|
|
bool b;
|
|
|
|
|
|
|
|
b = chTimeIsInRangeX((systime_t)100, (systime_t)100, (systime_t)10);
|
|
|
|
test_assert(b == true, "not in range");
|
|
|
|
b = chTimeIsInRangeX((systime_t)99, (systime_t)100, (systime_t)10);
|
|
|
|
test_assert(b == false, "in range");
|
|
|
|
b = chTimeIsInRangeX((systime_t)9, (systime_t)100, (systime_t)10);
|
|
|
|
test_assert(b == true, "not in range");
|
|
|
|
b = chTimeIsInRangeX((systime_t)10, (systime_t)100, (systime_t)10);
|
|
|
|
test_assert(b == false, "in range");
|
|
|
|
]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
</cases>
|
|
|
|
</sequence>
|
|
|
|
<sequence>
|
|
|
|
<type index="0">
|
|
|
|
<value>Internal Tests</value>
|
|
|
|
</type>
|
|
|
|
<brief>
|
|
|
|
<value>Time Stamps Functionality.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>This sequence tests the ChibiOS/RT functionalities
|
|
|
|
related to time stamps.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<shared_code>
|
|
|
|
<value><![CDATA[#include "ch.h"]]></value>
|
|
|
|
</shared_code>
|
|
|
|
<cases>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Time Stamps functionality.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>The functionality of the API @p chVTGetTimeStamp() is
|
|
|
|
tested.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value />
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
2020-07-11 02:40:59 -07:00
|
|
|
<value />
|
2021-06-09 04:56:33 -07:00
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value />
|
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Time stamps are generated and checked for
|
|
|
|
monotonicity.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[
|
2020-07-11 02:40:59 -07:00
|
|
|
systime_t start, end;
|
|
|
|
systimestamp_t last, now;
|
|
|
|
|
|
|
|
last = chVTGetTimeStamp();
|
|
|
|
start = test_wait_tick();
|
|
|
|
end = chTimeAddX(start, TIME_MS2I(1000));
|
|
|
|
do {
|
|
|
|
now = chVTGetTimeStamp();
|
|
|
|
test_assert(last <= now, "not monotonic");
|
|
|
|
last = now;
|
|
|
|
#if defined(SIMULATOR)
|
|
|
|
_sim_check_for_interrupts();
|
|
|
|
#endif
|
|
|
|
} while (chVTIsSystemTimeWithinX(start, end));]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
</cases>
|
|
|
|
</sequence>
|
|
|
|
<sequence>
|
|
|
|
<type index="0">
|
|
|
|
<value>Internal Tests</value>
|
|
|
|
</type>
|
|
|
|
<brief>
|
|
|
|
<value>Threads Functionality.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>This sequence tests the ChibiOS/RT functionalities
|
|
|
|
related to threading.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<shared_code>
|
|
|
|
<value><![CDATA[static THD_FUNCTION(thread, p) {
|
2020-07-12 06:15:38 -07:00
|
|
|
|
|
|
|
test_emit_token(*(char *)p);
|
2016-03-20 08:41:04 -07:00
|
|
|
}]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</shared_code>
|
|
|
|
<cases>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Thread Sleep functionality.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>The functionality of @p chThdSleep() and derivatives
|
|
|
|
is tested.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value />
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value><![CDATA[systime_t time;]]></value>
|
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The current system time is read then a sleep is
|
|
|
|
performed for 100 system ticks and on exit the system
|
|
|
|
time is verified again.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[time = chVTGetSystemTimeX();
|
2020-07-12 06:15:38 -07:00
|
|
|
chThdSleep(100);
|
|
|
|
test_assert_time_window(chTimeAddX(time, 100),
|
|
|
|
chTimeAddX(time, 100 + CH_CFG_ST_TIMEDELTA + 1),
|
2016-03-20 04:15:33 -07:00
|
|
|
"out of time window");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The current system time is read then a sleep is
|
|
|
|
performed for 100000 microseconds and on exit the
|
|
|
|
system time is verified again.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[time = chVTGetSystemTimeX();
|
2020-07-12 06:15:38 -07:00
|
|
|
chThdSleepMicroseconds(100000);
|
|
|
|
test_assert_time_window(chTimeAddX(time, TIME_US2I(100000)),
|
|
|
|
chTimeAddX(time, TIME_US2I(100000) + CH_CFG_ST_TIMEDELTA + 1),
|
2016-03-20 04:15:33 -07:00
|
|
|
"out of time window");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The current system time is read then a sleep is
|
|
|
|
performed for 100 milliseconds and on exit the system
|
|
|
|
time is verified again.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[time = chVTGetSystemTimeX();
|
2020-07-12 06:15:38 -07:00
|
|
|
chThdSleepMilliseconds(100);
|
|
|
|
test_assert_time_window(chTimeAddX(time, TIME_MS2I(100)),
|
|
|
|
chTimeAddX(time, TIME_MS2I(100) + CH_CFG_ST_TIMEDELTA + 1),
|
2016-03-20 04:15:33 -07:00
|
|
|
"out of time window");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The current system time is read then a sleep is
|
|
|
|
performed for 1 second and on exit the system time is
|
|
|
|
verified again.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[time = chVTGetSystemTimeX();
|
2020-07-12 06:15:38 -07:00
|
|
|
chThdSleepSeconds(1);
|
|
|
|
test_assert_time_window(chTimeAddX(time, TIME_S2I(1)),
|
|
|
|
chTimeAddX(time, TIME_S2I(1) + CH_CFG_ST_TIMEDELTA + 1),
|
2016-03-20 04:15:33 -07:00
|
|
|
"out of time window");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Function chThdSleepUntil() is tested with a
|
|
|
|
timeline of "now" + 100 ticks.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[time = chVTGetSystemTimeX();
|
2020-07-12 06:15:38 -07:00
|
|
|
chThdSleepUntil(chTimeAddX(time, 100));
|
|
|
|
test_assert_time_window(chTimeAddX(time, 100),
|
|
|
|
chTimeAddX(time, 100 + CH_CFG_ST_TIMEDELTA + 1),
|
2016-03-20 04:15:33 -07:00
|
|
|
"out of time window");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Ready List functionality, threads priority order.
|
|
|
|
</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>Five threads, are enqueued in the ready list and
|
|
|
|
atomically executed. The test expects the threads to
|
|
|
|
perform their operations in correct priority order
|
|
|
|
regardless of the initial order.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value />
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value />
|
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Creating 5 threads with increasing priority,
|
|
|
|
execution sequence is tested.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()-5, thread, "E");
|
2020-07-12 06:15:38 -07:00
|
|
|
threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriorityX()-4, thread, "D");
|
|
|
|
threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriorityX()-3, thread, "C");
|
|
|
|
threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriorityX()-2, thread, "B");
|
|
|
|
threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriorityX()-1, thread, "A");
|
|
|
|
test_wait_threads();
|
2016-03-29 03:34:51 -07:00
|
|
|
test_assert_sequence("ABCDE", "invalid sequence");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Creating 5 threads with decreasing priority,
|
|
|
|
execution sequence is tested.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriorityX()-1, thread, "A");
|
2020-07-12 06:15:38 -07:00
|
|
|
threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriorityX()-2, thread, "B");
|
|
|
|
threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriorityX()-3, thread, "C");
|
|
|
|
threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriorityX()-4, thread, "D");
|
|
|
|
threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()-5, thread, "E");
|
|
|
|
test_wait_threads();
|
2016-03-29 03:34:51 -07:00
|
|
|
test_assert_sequence("ABCDE", "invalid sequence");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Creating 5 threads with pseudo-random priority,
|
|
|
|
execution sequence is tested.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriorityX()-4, thread, "D");
|
2020-07-12 06:15:38 -07:00
|
|
|
threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()-5, thread, "E");
|
|
|
|
threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriorityX()-1, thread, "A");
|
|
|
|
threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriorityX()-2, thread, "B");
|
|
|
|
threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriorityX()-3, thread, "C");
|
|
|
|
test_wait_threads();
|
2016-03-29 03:34:51 -07:00
|
|
|
test_assert_sequence("ABCDE", "invalid sequence");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Priority change test.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>A series of priority changes are performed on the
|
|
|
|
current thread in order to verify that the priority change
|
|
|
|
happens as expected.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value />
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value><![CDATA[tprio_t prio, p1;]]></value>
|
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Thread priority is increased by one then a check
|
|
|
|
is performed.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[prio = chThdGetPriorityX();
|
2020-07-12 06:15:38 -07:00
|
|
|
p1 = chThdSetPriority(prio + 1);
|
|
|
|
test_assert(p1 == prio, "unexpected returned priority level");
|
2016-03-28 07:22:13 -07:00
|
|
|
test_assert(chThdGetPriorityX() == prio + 1, "unexpected priority level");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Thread priority is returned to the previous value
|
|
|
|
then a check is performed.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[p1 = chThdSetPriority(p1);
|
2020-07-12 06:15:38 -07:00
|
|
|
test_assert(p1 == prio + 1, "unexpected returned priority level");
|
2016-03-28 07:22:13 -07:00
|
|
|
test_assert(chThdGetPriorityX() == prio, "unexpected priority level");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Priority change test with Priority Inheritance.
|
|
|
|
</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>A series of priority changes are performed on the
|
|
|
|
current thread in order to verify that the priority change
|
|
|
|
happens as expected.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value><![CDATA[CH_CFG_USE_MUTEXES == TRUE]]></value>
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value />
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value><![CDATA[tprio_t prio, p1;]]></value>
|
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Simulating a priority boost situation (prio >
|
|
|
|
realprio).</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[prio = chThdGetPriorityX();
|
2020-12-19 02:45:11 -08:00
|
|
|
chThdGetSelfX()->hdr.pqueue.prio += 2;
|
2016-03-28 07:22:13 -07:00
|
|
|
test_assert(chThdGetPriorityX() == prio + 2, "unexpected priority level");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Raising thread priority above original priority
|
|
|
|
but below the boosted level.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[p1 = chThdSetPriority(prio + 1);
|
2020-07-12 06:15:38 -07:00
|
|
|
test_assert(p1 == prio, "unexpected returned priority level");
|
2020-12-19 02:45:11 -08:00
|
|
|
test_assert(chThdGetSelfX()->hdr.pqueue.prio == prio + 2, "unexpected priority level");
|
2016-03-28 07:22:13 -07:00
|
|
|
test_assert(chThdGetSelfX()->realprio == prio + 1, "unexpected returned real priority level");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Raising thread priority above the boosted level.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[p1 = chThdSetPriority(prio + 3);
|
2020-07-12 06:15:38 -07:00
|
|
|
test_assert(p1 == prio + 1, "unexpected returned priority level");
|
2020-12-19 02:45:11 -08:00
|
|
|
test_assert(chThdGetSelfX()->hdr.pqueue.prio == prio + 3, "unexpected priority level");
|
2016-03-28 07:22:13 -07:00
|
|
|
test_assert(chThdGetSelfX()->realprio == prio + 3, "unexpected real priority level");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Restoring original conditions.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chSysLock();
|
2020-12-19 02:45:11 -08:00
|
|
|
chThdGetSelfX()->hdr.pqueue.prio = prio;
|
2020-07-12 06:15:38 -07:00
|
|
|
chThdGetSelfX()->realprio = prio;
|
2016-03-28 07:22:13 -07:00
|
|
|
chSysUnlock();]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
</cases>
|
|
|
|
</sequence>
|
|
|
|
<sequence>
|
|
|
|
<type index="0">
|
|
|
|
<value>Internal Tests</value>
|
|
|
|
</type>
|
|
|
|
<brief>
|
|
|
|
<value>Suspend/Resume.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>This sequence tests the ChibiOS/RT functionalities
|
|
|
|
related to threads suspend/resume.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<shared_code>
|
|
|
|
<value><![CDATA[static thread_reference_t tr1;
|
2020-07-12 06:15:38 -07:00
|
|
|
|
|
|
|
static THD_FUNCTION(thread1, p) {
|
|
|
|
|
|
|
|
chSysLock();
|
|
|
|
chThdResumeI(&tr1, MSG_OK);
|
|
|
|
chSchRescheduleS();
|
|
|
|
chSysUnlock();
|
|
|
|
test_emit_token(*(char *)p);
|
2016-03-29 03:34:51 -07:00
|
|
|
}]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</shared_code>
|
|
|
|
<cases>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Suspend and Resume functionality.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>The functionality of chThdSuspendTimeoutS() and
|
|
|
|
chThdResumeI() is tested.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value><![CDATA[tr1 = NULL;]]></value>
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value><![CDATA[systime_t time;
|
2016-03-29 03:34:51 -07:00
|
|
|
msg_t msg;]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The function chThdSuspendTimeoutS() is invoked,
|
|
|
|
the thread is remotely resumed with message @p MSG_OK.
|
|
|
|
On return the message and the state of the reference
|
|
|
|
are tested.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()-1, thread1, "A");
|
2020-07-12 06:15:38 -07:00
|
|
|
chSysLock();
|
|
|
|
msg = chThdSuspendTimeoutS(&tr1, TIME_INFINITE);
|
|
|
|
chSysUnlock();
|
|
|
|
test_assert(NULL == tr1, "not NULL");
|
|
|
|
test_assert(MSG_OK == msg,"wrong returned message");
|
2016-03-29 03:34:51 -07:00
|
|
|
test_wait_threads();]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The function chThdSuspendTimeoutS() is invoked,
|
|
|
|
the thread is not resumed so a timeout must occur. On
|
|
|
|
return the message and the state of the reference are
|
|
|
|
tested.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chSysLock();
|
2020-07-12 06:15:38 -07:00
|
|
|
time = chVTGetSystemTimeX();
|
|
|
|
msg = chThdSuspendTimeoutS(&tr1, TIME_MS2I(1000));
|
|
|
|
chSysUnlock();
|
|
|
|
test_assert_time_window(chTimeAddX(time, TIME_MS2I(1000)),
|
|
|
|
chTimeAddX(time, TIME_MS2I(1000) + CH_CFG_ST_TIMEDELTA + 1),
|
|
|
|
"out of time window");
|
|
|
|
test_assert(NULL == tr1, "not NULL");
|
2016-03-29 03:34:51 -07:00
|
|
|
test_assert(MSG_TIMEOUT == msg, "wrong returned message");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
</cases>
|
|
|
|
</sequence>
|
|
|
|
<sequence>
|
|
|
|
<type index="0">
|
|
|
|
<value>Internal Tests</value>
|
|
|
|
</type>
|
|
|
|
<brief>
|
|
|
|
<value>Counter Semaphores.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>This sequence tests the ChibiOS/RT functionalities
|
|
|
|
related to counter semaphores.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value><![CDATA[CH_CFG_USE_SEMAPHORES == TRUE]]></value>
|
|
|
|
</condition>
|
|
|
|
<shared_code>
|
|
|
|
<value><![CDATA[#include "ch.h"
|
2020-07-12 06:15:38 -07:00
|
|
|
|
|
|
|
static semaphore_t sem1;
|
|
|
|
|
|
|
|
static THD_FUNCTION(thread1, p) {
|
|
|
|
|
|
|
|
chSemWait(&sem1);
|
|
|
|
test_emit_token(*(char *)p);
|
|
|
|
}
|
|
|
|
|
|
|
|
static THD_FUNCTION(thread2, p) {
|
|
|
|
|
|
|
|
(void)p;
|
|
|
|
chThdSleepMilliseconds(50);
|
|
|
|
chSysLock();
|
|
|
|
chSemSignalI(&sem1); /* For coverage reasons */
|
|
|
|
chSchRescheduleS();
|
|
|
|
chSysUnlock();
|
|
|
|
}
|
|
|
|
|
|
|
|
static THD_FUNCTION(thread3, p) {
|
|
|
|
|
|
|
|
(void)p;
|
|
|
|
chSemWait(&sem1);
|
|
|
|
chSemSignal(&sem1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static THD_FUNCTION(thread4, p) {
|
|
|
|
|
|
|
|
chBSemSignal((binary_semaphore_t *)p);
|
2016-03-29 03:34:51 -07:00
|
|
|
}]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</shared_code>
|
|
|
|
<cases>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Semaphore primitives, no state change.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>Wait, Signal and Reset primitives are tested. The
|
|
|
|
testing thread does not trigger a state change.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value><![CDATA[chSemObjectInit(&sem1, 1);]]></value>
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value><![CDATA[chSemReset(&sem1, 0);]]></value>
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value />
|
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The function chSemWait() is invoked, after return
|
|
|
|
the counter and the returned message are tested.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[msg_t msg;
|
2020-07-12 06:15:38 -07:00
|
|
|
|
|
|
|
msg = chSemWait(&sem1);
|
|
|
|
test_assert_lock(chSemGetCounterI(&sem1) == 0, "wrong counter value");
|
2016-03-29 03:34:51 -07:00
|
|
|
test_assert(MSG_OK == msg, "wrong returned message");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The function chSemSignal() is invoked, after
|
|
|
|
return the counter is tested.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chSemSignal(&sem1);
|
2016-03-29 03:34:51 -07:00
|
|
|
test_assert_lock(chSemGetCounterI(&sem1) == 1, "wrong counter value");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The function chSemReset() is invoked, after
|
|
|
|
return the counter is tested.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chSemReset(&sem1, 2);
|
2016-03-29 03:34:51 -07:00
|
|
|
test_assert_lock(chSemGetCounterI(&sem1) == 2, "wrong counter value");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Semaphore enqueuing test.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>Five threads with randomized priorities are enqueued
|
|
|
|
to a semaphore then awakened one at time. The test expects
|
|
|
|
that the threads reach their goal in FIFO order or
|
|
|
|
priority order depending on the @p
|
|
|
|
CH_CFG_USE_SEMAPHORES_PRIORITY configuration setting.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value><![CDATA[chSemObjectInit(&sem1, 0);]]></value>
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value />
|
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Five threads are created with mixed priority
|
|
|
|
levels (not increasing nor decreasing). Threads
|
|
|
|
enqueue on a semaphore initialized to zero.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+5, thread1, "A");
|
2020-07-12 06:15:38 -07:00
|
|
|
threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriorityX()+1, thread1, "B");
|
|
|
|
threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriorityX()+3, thread1, "C");
|
|
|
|
threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriorityX()+4, thread1, "D");
|
2016-03-29 03:34:51 -07:00
|
|
|
threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriorityX()+2, thread1, "E");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The semaphore is signaled 5 times. The thread
|
|
|
|
activation sequence is tested.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chSemSignal(&sem1);
|
2020-07-12 06:15:38 -07:00
|
|
|
chSemSignal(&sem1);
|
|
|
|
chSemSignal(&sem1);
|
|
|
|
chSemSignal(&sem1);
|
|
|
|
chSemSignal(&sem1);
|
|
|
|
test_wait_threads();
|
|
|
|
#if CH_CFG_USE_SEMAPHORES_PRIORITY
|
|
|
|
test_assert_sequence("ADCEB", "invalid sequence");
|
|
|
|
#else
|
|
|
|
test_assert_sequence("ABCDE", "invalid sequence");
|
2016-03-29 03:34:51 -07:00
|
|
|
#endif]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Semaphore timeout test.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>The three possible semaphore waiting modes (do not
|
|
|
|
wait, wait with timeout, wait without timeout) are
|
|
|
|
explored. The test expects that the semaphore wait
|
|
|
|
function returns the correct value in each of the above
|
|
|
|
scenario and that the semaphore structure status is
|
|
|
|
correct after each operation.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value><![CDATA[chSemObjectInit(&sem1, 0);]]></value>
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value><![CDATA[unsigned i;
|
2020-07-12 06:15:38 -07:00
|
|
|
systime_t target_time;
|
2016-03-29 05:36:24 -07:00
|
|
|
msg_t msg;]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Testing special case TIME_IMMEDIATE.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[msg = chSemWaitTimeout(&sem1, TIME_IMMEDIATE);
|
2020-07-12 06:15:38 -07:00
|
|
|
test_assert(msg == MSG_TIMEOUT, "wrong wake-up message");
|
2020-12-19 02:45:11 -08:00
|
|
|
test_assert(ch_queue_isempty(&sem1.queue), "queue not empty");
|
2016-03-29 05:36:24 -07:00
|
|
|
test_assert(sem1.cnt == 0, "counter not zero");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Testing non-timeout condition.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX() - 1,
|
2020-07-12 06:15:38 -07:00
|
|
|
thread2, 0);
|
|
|
|
msg = chSemWaitTimeout(&sem1, TIME_MS2I(500));
|
|
|
|
test_wait_threads();
|
|
|
|
test_assert(msg == MSG_OK, "wrong wake-up message");
|
2020-12-19 02:45:11 -08:00
|
|
|
test_assert(ch_queue_isempty(&sem1.queue), "queue not empty");
|
2016-03-29 05:36:24 -07:00
|
|
|
test_assert(sem1.cnt == 0, "counter not zero");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Testing timeout condition.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[target_time = chTimeAddX(test_wait_tick(), TIME_MS2I(5 * 50));
|
2020-07-12 06:15:38 -07:00
|
|
|
for (i = 0; i < 5; i++) {
|
|
|
|
test_emit_token('A' + i);
|
|
|
|
msg = chSemWaitTimeout(&sem1, TIME_MS2I(50));
|
|
|
|
test_assert(msg == MSG_TIMEOUT, "wrong wake-up message");
|
2020-12-19 02:45:11 -08:00
|
|
|
test_assert(ch_queue_isempty(&sem1.queue), "queue not empty");
|
2020-07-12 06:15:38 -07:00
|
|
|
test_assert(sem1.cnt == 0, "counter not zero");
|
|
|
|
}
|
|
|
|
test_assert_sequence("ABCDE", "invalid sequence");
|
|
|
|
test_assert_time_window(target_time,
|
|
|
|
chTimeAddX(target_time, ALLOWED_DELAY),
|
2016-03-29 05:36:24 -07:00
|
|
|
"out of time window");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Testing chSemAddCounterI() functionality.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>The functon is tested by waking up a thread then the
|
|
|
|
semaphore counter value is tested.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value><![CDATA[chSemObjectInit(&sem1, 0);]]></value>
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value />
|
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>A thread is created, it goes to wait on the
|
|
|
|
semaphore.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+1, thread1, "A");]]></value>
|
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The semaphore counter is increased by two, it is
|
|
|
|
then tested to be one, the thread must have completed.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chSysLock();
|
2020-07-12 06:15:38 -07:00
|
|
|
chSemAddCounterI(&sem1, 2);
|
|
|
|
chSchRescheduleS();
|
|
|
|
chSysUnlock();
|
|
|
|
test_wait_threads();
|
|
|
|
test_assert_lock(chSemGetCounterI(&sem1) == 1, "invalid counter");
|
2016-03-29 05:36:24 -07:00
|
|
|
test_assert_sequence("A", "invalid sequence");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Testing chSemWaitSignal() functionality.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>This test case explicitly addresses the @p
|
|
|
|
chSemWaitSignal() function. A thread is created that
|
|
|
|
performs a wait and a signal operations. The tester thread
|
|
|
|
is awakened from an atomic wait/signal operation. The test
|
|
|
|
expects that the semaphore wait function returns the
|
|
|
|
correct value in each of the above scenario and that the
|
|
|
|
semaphore structure status is correct after each
|
|
|
|
operation.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value><![CDATA[chSemObjectInit(&sem1, 0);]]></value>
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value><![CDATA[test_wait_threads();]]></value>
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value />
|
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>An higher priority thread is created that
|
|
|
|
performs non-atomical wait and signal operations on a
|
|
|
|
semaphore.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+1, thread3, 0);]]></value>
|
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The function chSemSignalWait() is invoked by
|
|
|
|
specifying the same semaphore for the wait and signal
|
|
|
|
phases. The counter value must be one on exit.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chSemSignalWait(&sem1, &sem1);
|
2020-12-19 02:45:11 -08:00
|
|
|
test_assert(ch_queue_isempty(&sem1.queue), "queue not empty");
|
2016-03-29 05:36:24 -07:00
|
|
|
test_assert(sem1.cnt == 0, "counter not zero");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The function chSemSignalWait() is invoked again
|
|
|
|
by specifying the same semaphore for the wait and
|
|
|
|
signal phases. The counter value must be one on exit.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chSemSignalWait(&sem1, &sem1);
|
2020-12-19 02:45:11 -08:00
|
|
|
test_assert(ch_queue_isempty(&sem1.queue), "queue not empty");
|
2016-03-29 05:36:24 -07:00
|
|
|
test_assert(sem1.cnt == 0, "counter not zero");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Testing Binary Semaphores special case.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>This test case tests the binary semaphores
|
|
|
|
functionality. The test both checks the binary semaphore
|
|
|
|
status and the expected status of the underlying counting
|
|
|
|
semaphore.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value />
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value><![CDATA[test_wait_threads();]]></value>
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value><![CDATA[binary_semaphore_t bsem;
|
2016-03-29 05:36:24 -07:00
|
|
|
msg_t msg;]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Creating a binary semaphore in "taken" state, the
|
|
|
|
state is checked.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chBSemObjectInit(&bsem, true);
|
2016-03-29 05:36:24 -07:00
|
|
|
test_assert_lock(chBSemGetStateI(&bsem) == true, "not taken");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Resetting the binary semaphore in "taken" state,
|
|
|
|
the state must not change.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chBSemReset(&bsem, true);
|
2016-03-29 05:36:24 -07:00
|
|
|
test_assert_lock(chBSemGetStateI(&bsem) == true, "not taken");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Starting a signaler thread at a lower priority.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[threads[0] = chThdCreateStatic(wa[0], WA_SIZE,
|
2016-03-29 05:36:24 -07:00
|
|
|
chThdGetPriorityX()-1, thread4, &bsem);]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Waiting for the binary semaphore to be signaled,
|
|
|
|
the semaphore is expected to be taken.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[msg = chBSemWait(&bsem);
|
2020-07-12 06:15:38 -07:00
|
|
|
test_assert_lock(chBSemGetStateI(&bsem) == true, "not taken");
|
2016-03-29 05:36:24 -07:00
|
|
|
test_assert(msg == MSG_OK, "unexpected message");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Signaling the binary semaphore, checking the
|
|
|
|
binary semaphore state to be "not taken" and the
|
|
|
|
underlying counter semaphore counter to be one.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chBSemSignal(&bsem);
|
2020-07-12 06:15:38 -07:00
|
|
|
test_assert_lock(chBSemGetStateI(&bsem) ==false, "still taken");
|
2016-03-29 05:36:24 -07:00
|
|
|
test_assert_lock(chSemGetCounterI(&bsem.sem) == 1, "unexpected counter");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Signaling the binary semaphore again, the
|
|
|
|
internal state must not change from "not taken".
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chBSemSignal(&bsem);
|
2020-07-12 06:15:38 -07:00
|
|
|
test_assert_lock(chBSemGetStateI(&bsem) == false, "taken");
|
2016-03-29 05:36:24 -07:00
|
|
|
test_assert_lock(chSemGetCounterI(&bsem.sem) == 1, "unexpected counter");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
</cases>
|
|
|
|
</sequence>
|
|
|
|
<sequence>
|
|
|
|
<type index="0">
|
|
|
|
<value>Internal Tests</value>
|
|
|
|
</type>
|
|
|
|
<brief>
|
|
|
|
<value>Mutexes, Condition Variables and Priority Inheritance.
|
|
|
|
</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>This sequence tests the ChibiOS/RT functionalities
|
|
|
|
related to mutexes, condition variables and priority
|
|
|
|
inheritance algorithm.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value><![CDATA[CH_CFG_USE_MUTEXES == TRUE]]></value>
|
|
|
|
</condition>
|
|
|
|
<shared_code>
|
|
|
|
<value><![CDATA[static MUTEX_DECL(m1);
|
2020-07-12 06:15:38 -07:00
|
|
|
static MUTEX_DECL(m2);
|
|
|
|
#if CH_CFG_USE_CONDVARS || defined(__DOXYGEN__)
|
|
|
|
static CONDVAR_DECL(c1);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if CH_DBG_THREADS_PROFILING || defined(__DOXYGEN__)
|
|
|
|
/**
|
|
|
|
* @brief CPU pulse.
|
|
|
|
* @note The current implementation is not totally reliable.
|
|
|
|
*
|
|
|
|
* @param[in] duration CPU pulse duration in milliseconds
|
|
|
|
*/
|
|
|
|
void test_cpu_pulse(unsigned duration) {
|
|
|
|
systime_t start, end, now;
|
|
|
|
|
|
|
|
start = chThdGetTicksX(chThdGetSelfX());
|
|
|
|
end = chTimeAddX(start, TIME_MS2I(duration));
|
|
|
|
do {
|
|
|
|
now = chThdGetTicksX(chThdGetSelfX());
|
|
|
|
#if defined(SIMULATOR)
|
|
|
|
_sim_check_for_interrupts();
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
while (chTimeIsInRangeX(now, start, end));
|
|
|
|
}
|
|
|
|
#endif /* CH_DBG_THREADS_PROFILING */
|
|
|
|
|
|
|
|
static THD_FUNCTION(thread1, p) {
|
|
|
|
|
|
|
|
chMtxLock(&m1);
|
|
|
|
test_emit_token(*(char *)p);
|
|
|
|
chMtxUnlock(&m1);
|
|
|
|
}
|
|
|
|
|
|
|
|
#if CH_DBG_THREADS_PROFILING || defined(__DOXYGEN__)
|
|
|
|
/* Low priority thread */
|
|
|
|
static THD_FUNCTION(thread2L, p) {
|
|
|
|
|
|
|
|
(void)p;
|
|
|
|
chMtxLock(&m1);
|
|
|
|
test_cpu_pulse(40);
|
|
|
|
chMtxUnlock(&m1);
|
|
|
|
test_cpu_pulse(10);
|
|
|
|
test_emit_token('C');
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Medium priority thread */
|
|
|
|
static THD_FUNCTION(thread2M, p) {
|
|
|
|
|
|
|
|
(void)p;
|
|
|
|
chThdSleepMilliseconds(20);
|
|
|
|
test_cpu_pulse(40);
|
|
|
|
test_emit_token('B');
|
|
|
|
}
|
|
|
|
|
|
|
|
/* High priority thread */
|
|
|
|
static THD_FUNCTION(thread2H, p) {
|
|
|
|
|
|
|
|
(void)p;
|
|
|
|
chThdSleepMilliseconds(40);
|
|
|
|
chMtxLock(&m1);
|
|
|
|
test_cpu_pulse(10);
|
|
|
|
chMtxUnlock(&m1);
|
|
|
|
test_emit_token('A');
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Lowest priority thread */
|
|
|
|
static THD_FUNCTION(thread3LL, p) {
|
|
|
|
|
|
|
|
(void)p;
|
|
|
|
chMtxLock(&m1);
|
|
|
|
test_cpu_pulse(30);
|
|
|
|
chMtxUnlock(&m1);
|
|
|
|
test_emit_token('E');
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Low priority thread */
|
|
|
|
static THD_FUNCTION(thread3L, p) {
|
|
|
|
|
|
|
|
(void)p;
|
|
|
|
chThdSleepMilliseconds(10);
|
|
|
|
chMtxLock(&m2);
|
|
|
|
test_cpu_pulse(20);
|
|
|
|
chMtxLock(&m1);
|
|
|
|
test_cpu_pulse(10);
|
|
|
|
chMtxUnlock(&m1);
|
|
|
|
test_cpu_pulse(10);
|
|
|
|
chMtxUnlock(&m2);
|
|
|
|
test_emit_token('D');
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Medium priority thread */
|
|
|
|
static THD_FUNCTION(thread3M, p) {
|
|
|
|
|
|
|
|
(void)p;
|
|
|
|
chThdSleepMilliseconds(20);
|
|
|
|
chMtxLock(&m2);
|
|
|
|
test_cpu_pulse(10);
|
|
|
|
chMtxUnlock(&m2);
|
|
|
|
test_emit_token('C');
|
|
|
|
}
|
|
|
|
|
|
|
|
/* High priority thread */
|
|
|
|
static THD_FUNCTION(thread3H, p) {
|
|
|
|
|
|
|
|
(void)p;
|
|
|
|
chThdSleepMilliseconds(40);
|
|
|
|
test_cpu_pulse(20);
|
|
|
|
test_emit_token('B');
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Highest priority thread */
|
|
|
|
static THD_FUNCTION(thread3HH, p) {
|
|
|
|
|
|
|
|
(void)p;
|
|
|
|
chThdSleepMilliseconds(50);
|
|
|
|
chMtxLock(&m2);
|
|
|
|
test_cpu_pulse(10);
|
|
|
|
chMtxUnlock(&m2);
|
|
|
|
test_emit_token('A');
|
|
|
|
}
|
|
|
|
#endif /* CH_DBG_THREADS_PROFILING */
|
|
|
|
|
|
|
|
static THD_FUNCTION(thread4A, p) {
|
|
|
|
|
|
|
|
(void)p;
|
|
|
|
chThdSleepMilliseconds(50);
|
|
|
|
chMtxLock(&m1);
|
|
|
|
chMtxUnlock(&m1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static THD_FUNCTION(thread4B, p) {
|
|
|
|
|
|
|
|
(void)p;
|
|
|
|
chThdSleepMilliseconds(150);
|
|
|
|
chSysLock();
|
|
|
|
chMtxLockS(&m2); /* For coverage of the chMtxLockS() function variant.*/
|
|
|
|
chMtxUnlockS(&m2); /* For coverage of the chMtxUnlockS() function variant.*/
|
|
|
|
chSchRescheduleS();
|
|
|
|
chSysUnlock();
|
|
|
|
}
|
|
|
|
|
|
|
|
#if CH_CFG_USE_CONDVARS || defined(__DOXYGEN__)
|
|
|
|
static THD_FUNCTION(thread6, p) {
|
|
|
|
|
|
|
|
chMtxLock(&m1);
|
|
|
|
chCondWait(&c1);
|
|
|
|
test_emit_token(*(char *)p);
|
|
|
|
chMtxUnlock(&m1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static THD_FUNCTION(thread8, p) {
|
|
|
|
|
|
|
|
chMtxLock(&m2);
|
|
|
|
chMtxLock(&m1);
|
|
|
|
#if CH_CFG_USE_CONDVARS_TIMEOUT || defined(__DOXYGEN__)
|
|
|
|
chCondWaitTimeout(&c1, TIME_INFINITE);
|
|
|
|
#else
|
|
|
|
chCondWait(&c1);
|
|
|
|
#endif
|
|
|
|
test_emit_token(*(char *)p);
|
|
|
|
chMtxUnlock(&m1);
|
|
|
|
chMtxUnlock(&m2);
|
|
|
|
}
|
|
|
|
|
|
|
|
static THD_FUNCTION(thread9, p) {
|
|
|
|
|
|
|
|
chMtxLock(&m2);
|
|
|
|
test_emit_token(*(char *)p);
|
|
|
|
chMtxUnlock(&m2);
|
|
|
|
}
|
2016-03-29 08:33:45 -07:00
|
|
|
#endif /* CH_CFG_USE_CONDVARS */]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</shared_code>
|
|
|
|
<cases>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Priority enqueuing test.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>Five threads, with increasing priority, are enqueued
|
|
|
|
on a locked mutex then the mutex is unlocked. The test
|
|
|
|
expects the threads to perform their operations in
|
|
|
|
increasing priority order regardless of the initial order.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value><![CDATA[chMtxObjectInit(&m1);]]></value>
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value><![CDATA[tprio_t prio;]]></value>
|
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Getting the initial priority.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[prio = chThdGetPriorityX();]]></value>
|
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Locking the mutex.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chMtxLock(&m1);]]></value>
|
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Five threads are created that try to lock and
|
|
|
|
unlock the mutex then terminate. The threads are
|
|
|
|
created in ascending priority order.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[threads[0] = chThdCreateStatic(wa[0], WA_SIZE, prio+1, thread1, "E");
|
2020-07-12 06:15:38 -07:00
|
|
|
threads[1] = chThdCreateStatic(wa[1], WA_SIZE, prio+2, thread1, "D");
|
|
|
|
threads[2] = chThdCreateStatic(wa[2], WA_SIZE, prio+3, thread1, "C");
|
|
|
|
threads[3] = chThdCreateStatic(wa[3], WA_SIZE, prio+4, thread1, "B");
|
2016-03-29 08:33:45 -07:00
|
|
|
threads[4] = chThdCreateStatic(wa[4], WA_SIZE, prio+5, thread1, "A");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Unlocking the mutex, the threads will wakeup in
|
|
|
|
priority order because the mutext queue is an ordered
|
|
|
|
one.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chMtxUnlock(&m1);
|
2020-07-12 06:15:38 -07:00
|
|
|
test_wait_threads();
|
|
|
|
test_assert(prio == chThdGetPriorityX(), "wrong priority level");
|
2016-03-29 08:33:45 -07:00
|
|
|
test_assert_sequence("ABCDE", "invalid sequence");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Priority inheritance, simple case.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>Three threads are involved in the classic priority
|
|
|
|
inversion scenario, a medium priority thread tries to
|
|
|
|
starve an high priority thread by blocking a low priority
|
|
|
|
thread into a mutex lock zone. The test expects the
|
|
|
|
threads to reach their goal in increasing priority order
|
|
|
|
by rearranging their priorities in order to avoid the
|
|
|
|
priority inversion trap.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value><![CDATA[CH_DBG_THREADS_PROFILING == TRUE]]></value>
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value><![CDATA[chMtxObjectInit(&m1);]]></value>
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value><![CDATA[systime_t time;]]></value>
|
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Getting the system time for test duration
|
|
|
|
measurement.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[time = test_wait_tick();]]></value>
|
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The three contenders threads are created and let
|
|
|
|
run atomically, the goals sequence is tested, the
|
|
|
|
threads must complete in priority order.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()-1, thread2H, 0);
|
2020-07-12 06:15:38 -07:00
|
|
|
threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriorityX()-2, thread2M, 0);
|
|
|
|
threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriorityX()-3, thread2L, 0);
|
|
|
|
test_wait_threads();
|
2016-03-29 08:33:45 -07:00
|
|
|
test_assert_sequence("ABC", "invalid sequence");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Testing that all threads completed within the
|
|
|
|
specified time windows (100mS...100mS+ALLOWED_DELAY).
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[test_assert_time_window(chTimeAddX(time, TIME_MS2I(100)),
|
2020-07-12 06:15:38 -07:00
|
|
|
chTimeAddX(time, TIME_MS2I(100) + ALLOWED_DELAY),
|
2016-03-29 08:33:45 -07:00
|
|
|
"out of time window");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Priority inheritance, complex case.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>Five threads are involved in the complex priority
|
|
|
|
inversion scenario, the priority inheritance algorithm is
|
|
|
|
tested for depths greater than one. The test expects the
|
|
|
|
threads to perform their operations in increasing priority
|
|
|
|
order by rearranging their priorities in order to avoid
|
|
|
|
the priority inversion trap.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value><![CDATA[CH_DBG_THREADS_PROFILING == TRUE]]></value>
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value><![CDATA[chMtxObjectInit(&m1); /* Mutex B.*/
|
2016-03-29 08:33:45 -07:00
|
|
|
chMtxObjectInit(&m2); /* Mutex A.*/]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value><![CDATA[systime_t time;]]></value>
|
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Getting the system time for test duration
|
|
|
|
measurement.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[time = test_wait_tick();]]></value>
|
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The five contenders threads are created and let
|
|
|
|
run atomically, the goals sequence is tested, the
|
|
|
|
threads must complete in priority order.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()-5, thread3LL, 0);
|
2020-07-12 06:15:38 -07:00
|
|
|
threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriorityX()-4, thread3L, 0);
|
|
|
|
threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriorityX()-3, thread3M, 0);
|
|
|
|
threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriorityX()-2, thread3H, 0);
|
|
|
|
threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriorityX()-1, thread3HH, 0);
|
|
|
|
test_wait_threads();
|
2016-03-29 08:33:45 -07:00
|
|
|
test_assert_sequence("ABCDE", "invalid sequence");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Testing that all threads completed within the
|
|
|
|
specified time windows (110mS...110mS+ALLOWED_DELAY).
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[test_assert_time_window(chTimeAddX(time, TIME_MS2I(110)),
|
2020-07-12 06:15:38 -07:00
|
|
|
chTimeAddX(time, TIME_MS2I(110) + ALLOWED_DELAY),
|
2016-03-29 08:33:45 -07:00
|
|
|
"out of time window");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Priority return verification.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>Two threads are spawned that try to lock the mutexes
|
|
|
|
already locked by the tester thread with precise timing.
|
|
|
|
The test expects that the priority changes caused by the
|
|
|
|
priority inheritance algorithm happen at the right moment
|
|
|
|
and with the right values.<br>
|
|
|
|
Thread A performs wait(50), lock(m1), unlock(m1), exit. Thread B
|
|
|
|
performs wait(150), lock(m2), unlock(m2), exit.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value><![CDATA[chMtxObjectInit(&m1);
|
2016-03-29 08:33:45 -07:00
|
|
|
chMtxObjectInit(&m2);]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value><![CDATA[test_wait_threads();]]></value>
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value><![CDATA[tprio_t p, pa, pb;]]></value>
|
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Getting current thread priority P(0) and
|
|
|
|
assigning to the threads A and B priorities +1 and +2.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[p = chThdGetPriorityX();
|
2020-07-12 06:15:38 -07:00
|
|
|
pa = p + 1;
|
2016-03-29 08:33:45 -07:00
|
|
|
pb = p + 2;]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Spawning threads A and B at priorities P(A) and
|
|
|
|
P(B).</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[threads[0] = chThdCreateStatic(wa[0], WA_SIZE, pa, thread4A, "A");
|
2016-03-29 08:33:45 -07:00
|
|
|
threads[1] = chThdCreateStatic(wa[1], WA_SIZE, pb, thread4B, "B");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Locking the mutex M1 before thread A has a chance
|
|
|
|
to lock it. The priority must not change because A has
|
|
|
|
not yet reached chMtxLock(M1). the mutex is not
|
|
|
|
locked.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chMtxLock(&m1);
|
2016-03-29 08:33:45 -07:00
|
|
|
test_assert(chThdGetPriorityX() == p, "wrong priority level");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Waiting 100mS, this makes thread A reach
|
|
|
|
chMtxLock(M1) and get the mutex. This must boost the
|
|
|
|
priority of the current thread at the same level of
|
|
|
|
thread A.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chThdSleepMilliseconds(100);
|
2016-03-29 08:33:45 -07:00
|
|
|
test_assert(chThdGetPriorityX() == pa, "wrong priority level");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Locking the mutex M2 before thread B has a chance
|
|
|
|
to lock it. The priority must not change because B has
|
|
|
|
not yet reached chMtxLock(M2). the mutex is not
|
|
|
|
locked.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chMtxLock(&m2);
|
2016-03-29 08:33:45 -07:00
|
|
|
test_assert(chThdGetPriorityX() == pa, "wrong priority level");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Waiting 100mS, this makes thread B reach
|
|
|
|
chMtxLock(M2) and get the mutex. This must boost the
|
|
|
|
priority of the current thread at the same level of
|
|
|
|
thread B.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chThdSleepMilliseconds(100);
|
2016-03-29 08:33:45 -07:00
|
|
|
test_assert(chThdGetPriorityX() == pb, "wrong priority level");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Unlocking M2, the priority should fall back to
|
|
|
|
P(A).</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chMtxUnlock(&m2);
|
2016-03-29 08:33:45 -07:00
|
|
|
test_assert(chThdGetPriorityX() == pa, "wrong priority level");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Unlocking M1, the priority should fall back to
|
|
|
|
P(0).</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chMtxUnlock(&m1);
|
2016-03-29 08:33:45 -07:00
|
|
|
test_assert(chThdGetPriorityX() == p, "wrong priority level");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Repeated locks, non recursive scenario.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>The behavior of multiple mutex locks from the same
|
|
|
|
thread is tested when recursion is disabled</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value><![CDATA[CH_CFG_USE_MUTEXES_RECURSIVE == FALSE]]></value>
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value><![CDATA[chMtxObjectInit(&m1);]]></value>
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value><![CDATA[bool b;
|
2016-03-30 07:33:58 -07:00
|
|
|
tprio_t prio;]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Getting current thread priority for later checks.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[prio = chThdGetPriorityX();]]></value>
|
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Locking the mutex first time, it must be possible
|
|
|
|
because it is not owned.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[b = chMtxTryLock(&m1);
|
2016-03-30 07:33:58 -07:00
|
|
|
test_assert(b, "already locked");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Locking the mutex second time, it must fail
|
|
|
|
because it is already owned.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[b = chMtxTryLock(&m1);
|
2016-03-30 07:33:58 -07:00
|
|
|
test_assert(!b, "not locked");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Unlocking the mutex then it must not be owned
|
|
|
|
anymore and the queue must be empty.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chMtxUnlock(&m1);
|
2020-07-12 06:15:38 -07:00
|
|
|
test_assert(m1.owner == NULL, "still owned");
|
2020-12-19 02:45:11 -08:00
|
|
|
test_assert(ch_queue_isempty(&m1.queue), "queue not empty");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Testing that priority has not changed after
|
|
|
|
operations.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[test_assert(chThdGetPriorityX() == prio, "wrong priority level");]]></value>
|
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Testing chMtxUnlockAll() behavior.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[b = chMtxTryLock(&m1);
|
2020-07-12 06:15:38 -07:00
|
|
|
test_assert(b, "already locked");
|
|
|
|
b = chMtxTryLock(&m1);
|
|
|
|
test_assert(!b, "not locked");
|
|
|
|
|
|
|
|
chMtxUnlockAll();
|
|
|
|
test_assert(m1.owner == NULL, "still owned");
|
2020-12-19 02:45:11 -08:00
|
|
|
test_assert(ch_queue_isempty(&m1.queue), "queue not empty");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Testing that priority has not changed after
|
|
|
|
operations.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[test_assert(chThdGetPriorityX() == prio, "wrong priority level");]]></value>
|
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Repeated locks using, recursive scenario.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>The behavior of multiple mutex locks from the same
|
|
|
|
thread is tested when recursion is enabled</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value><![CDATA[CH_CFG_USE_MUTEXES_RECURSIVE == TRUE]]></value>
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value><![CDATA[chMtxObjectInit(&m1);]]></value>
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value><![CDATA[bool b;
|
2016-03-30 07:33:58 -07:00
|
|
|
tprio_t prio;]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Getting current thread priority for later checks.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[prio = chThdGetPriorityX();]]></value>
|
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Locking the mutex first time, it must be possible
|
|
|
|
because it is not owned.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[b = chMtxTryLock(&m1);
|
2016-03-30 07:33:58 -07:00
|
|
|
test_assert(b, "already locked");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Locking the mutex second time, it must be
|
|
|
|
possible because it is recursive.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[b = chMtxTryLock(&m1);
|
2016-03-30 07:33:58 -07:00
|
|
|
test_assert(b, "already locked");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Unlocking the mutex then it must be still owned
|
|
|
|
because recursivity.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chMtxUnlock(&m1);
|
2016-03-30 07:33:58 -07:00
|
|
|
test_assert(m1.owner != NULL, "not owned");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Unlocking the mutex then it must not be owned
|
|
|
|
anymore and the queue must be empty.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chMtxUnlock(&m1);
|
2020-07-12 06:15:38 -07:00
|
|
|
test_assert(m1.owner == NULL, "still owned");
|
2020-12-19 02:45:11 -08:00
|
|
|
test_assert(ch_queue_isempty(&m1.queue), "queue not empty");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Testing that priority has not changed after
|
|
|
|
operations.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[test_assert(chThdGetPriorityX() == prio, "wrong priority level");]]></value>
|
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Testing consecutive
|
|
|
|
chMtxTryLock()/chMtxTryLockS() calls and a final
|
|
|
|
chMtxUnlockAllS().</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[b = chMtxTryLock(&m1);
|
2020-07-12 06:15:38 -07:00
|
|
|
test_assert(b, "already locked");
|
|
|
|
chSysLock();
|
|
|
|
b = chMtxTryLockS(&m1);
|
|
|
|
chSysUnlock();
|
|
|
|
test_assert(b, "already locked");
|
|
|
|
test_assert(m1.cnt == 2, "invalid recursion counter");
|
|
|
|
chSysLock();
|
|
|
|
chMtxUnlockAllS();
|
|
|
|
chSysUnlock();
|
|
|
|
test_assert(m1.owner == NULL, "still owned");
|
2020-12-19 02:45:11 -08:00
|
|
|
test_assert(ch_queue_isempty(&m1.queue), "queue not empty");
|
2016-03-30 07:33:58 -07:00
|
|
|
test_assert(m1.cnt == 0, "invalid recursion counter");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Testing consecutive chMtxLock()/chMtxLockS()
|
|
|
|
calls and a final chMtxUnlockAll().</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chMtxLock(&m1);
|
2020-07-12 06:15:38 -07:00
|
|
|
test_assert(m1.owner != NULL, "not owned");
|
|
|
|
chSysLock();
|
|
|
|
chMtxLockS(&m1);
|
|
|
|
chSysUnlock();
|
|
|
|
test_assert(m1.owner != NULL, "not owned");
|
|
|
|
test_assert(m1.cnt == 2, "invalid recursion counter");
|
|
|
|
chMtxUnlockAll();
|
|
|
|
test_assert(m1.owner == NULL, "still owned");
|
2020-12-19 02:45:11 -08:00
|
|
|
test_assert(ch_queue_isempty(&m1.queue), "queue not empty");
|
2016-03-30 07:33:58 -07:00
|
|
|
test_assert(m1.cnt == 0, "invalid recursion counter");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Testing that priority has not changed after
|
|
|
|
operations.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[test_assert(chThdGetPriorityX() == prio, "wrong priority level");]]></value>
|
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Condition Variable signal test.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>Five threads take a mutex and then enter a
|
|
|
|
conditional variable queue, the tester thread then
|
|
|
|
proceeds to signal the conditional variable five times
|
|
|
|
atomically.<br>
|
|
|
|
The test expects the threads to reach their goal in increasing
|
|
|
|
priority order regardless of the initial order.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value><![CDATA[CH_CFG_USE_CONDVARS == TRUE]]></value>
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value><![CDATA[chCondObjectInit(&c1);
|
2016-03-30 08:18:47 -07:00
|
|
|
chMtxObjectInit(&m1);]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value />
|
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Starting the five threads with increasing
|
|
|
|
priority, the threads will queue on the condition
|
|
|
|
variable.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[tprio_t prio = chThdGetPriorityX();
|
2020-07-12 06:15:38 -07:00
|
|
|
threads[0] = chThdCreateStatic(wa[0], WA_SIZE, prio+1, thread6, "E");
|
|
|
|
threads[1] = chThdCreateStatic(wa[1], WA_SIZE, prio+2, thread6, "D");
|
|
|
|
threads[2] = chThdCreateStatic(wa[2], WA_SIZE, prio+3, thread6, "C");
|
|
|
|
threads[3] = chThdCreateStatic(wa[3], WA_SIZE, prio+4, thread6, "B");
|
2016-03-30 08:18:47 -07:00
|
|
|
threads[4] = chThdCreateStatic(wa[4], WA_SIZE, prio+5, thread6, "A");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Atomically signaling the condition variable five
|
|
|
|
times then waiting for the threads to terminate in
|
|
|
|
priority order, the order is tested.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chSysLock();
|
2020-07-12 06:15:38 -07:00
|
|
|
chCondSignalI(&c1);
|
|
|
|
chCondSignalI(&c1);
|
|
|
|
chCondSignalI(&c1);
|
|
|
|
chCondSignalI(&c1);
|
|
|
|
chCondSignalI(&c1);
|
|
|
|
chSchRescheduleS();
|
|
|
|
chSysUnlock();
|
|
|
|
test_wait_threads();
|
2016-03-30 08:18:47 -07:00
|
|
|
test_assert_sequence("ABCDE", "invalid sequence");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Condition Variable broadcast test.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>Five threads take a mutex and then enter a
|
|
|
|
conditional variable queue, the tester thread then
|
|
|
|
proceeds to broadcast the conditional
|
|
|
|
variable.<br>
|
|
|
|
The test expects the threads to reach their goal in increasing
|
|
|
|
priority order regardless of the initial order.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value><![CDATA[CH_CFG_USE_CONDVARS == TRUE]]></value>
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value><![CDATA[chCondObjectInit(&c1);
|
2016-03-31 03:10:43 -07:00
|
|
|
chMtxObjectInit(&m1);]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value />
|
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Starting the five threads with increasing
|
|
|
|
priority, the threads will queue on the condition
|
|
|
|
variable.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[tprio_t prio = chThdGetPriorityX();
|
2020-07-12 06:15:38 -07:00
|
|
|
threads[0] = chThdCreateStatic(wa[0], WA_SIZE, prio+1, thread6, "E");
|
|
|
|
threads[1] = chThdCreateStatic(wa[1], WA_SIZE, prio+2, thread6, "D");
|
|
|
|
threads[2] = chThdCreateStatic(wa[2], WA_SIZE, prio+3, thread6, "C");
|
|
|
|
threads[3] = chThdCreateStatic(wa[3], WA_SIZE, prio+4, thread6, "B");
|
2016-03-31 03:10:43 -07:00
|
|
|
threads[4] = chThdCreateStatic(wa[4], WA_SIZE, prio+5, thread6, "A");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Broarcasting on the condition variable then
|
|
|
|
waiting for the threads to terminate in priority
|
|
|
|
order, the order is tested.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chCondBroadcast(&c1);
|
2020-07-12 06:15:38 -07:00
|
|
|
test_wait_threads();
|
2016-03-30 08:18:47 -07:00
|
|
|
test_assert_sequence("ABCDE", "invalid sequence");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Condition Variable priority boost test.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>This test case verifies the priority boost of a
|
|
|
|
thread waiting on a conditional variable queue. It tests
|
|
|
|
this very specific situation in order to improve code
|
|
|
|
coverage. The created threads perform the following
|
|
|
|
operations: TA{lock(M2), lock(M1), wait(C1), unlock(M1),
|
|
|
|
unlock(M2)}, TB{lock(M2), wait(C1), unlock(M2)}.
|
|
|
|
TC{lock(M1), unlock(M1)}.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value><![CDATA[CH_CFG_USE_CONDVARS == TRUE]]></value>
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value><![CDATA[chCondObjectInit(&c1);
|
2020-07-12 06:15:38 -07:00
|
|
|
chMtxObjectInit(&m1);
|
2016-03-31 03:10:43 -07:00
|
|
|
chMtxObjectInit(&m2);]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value><![CDATA[tprio_t prio;]]></value>
|
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Reading current base priority.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[prio = chThdGetPriorityX();]]></value>
|
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Thread A is created at priority P(+1), it locks
|
|
|
|
M2, locks M1 and goes to wait on C1.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[threads[0] = chThdCreateStatic(wa[0], WA_SIZE, prio+1, thread8, "A");]]></value>
|
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Thread C is created at priority P(+2), it
|
|
|
|
enqueues on M1 and boosts TA priority at P(+2).
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[threads[1] = chThdCreateStatic(wa[1], WA_SIZE, prio+2, thread6, "C");]]></value>
|
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Thread B is created at priority P(+3), it
|
|
|
|
enqueues on M2 and boosts TA priority at P(+3).
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[threads[2] = chThdCreateStatic(wa[2], WA_SIZE, prio+3, thread9, "B");]]></value>
|
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Signaling C1: TA wakes up, unlocks M1 and
|
|
|
|
priority goes to P(+2). TB locks M1, unlocks M1 and
|
|
|
|
completes. TA unlocks M2 and priority goes to P(+1).
|
|
|
|
TC waits on C1. TA completes.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chCondSignal(&c1);]]></value>
|
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Signaling C1: TC wakes up, unlocks M1 and
|
|
|
|
completes.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chCondSignal(&c1);]]></value>
|
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Checking the order of operations.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[test_wait_threads();
|
2016-03-31 03:10:43 -07:00
|
|
|
test_assert_sequence("ABC", "invalid sequence");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
</cases>
|
|
|
|
</sequence>
|
|
|
|
<sequence>
|
|
|
|
<type index="0">
|
|
|
|
<value>Internal Tests</value>
|
|
|
|
</type>
|
|
|
|
<brief>
|
|
|
|
<value>Synchronous Messages.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>This module implements the test sequence for the
|
|
|
|
Synchronous Messages subsystem.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value><![CDATA[CH_CFG_USE_MESSAGES == TRUE]]></value>
|
|
|
|
</condition>
|
|
|
|
<shared_code>
|
|
|
|
<value><![CDATA[static THD_FUNCTION(msg_thread1, p) {
|
2020-07-12 06:15:38 -07:00
|
|
|
|
|
|
|
chMsgSend(p, 'A');
|
|
|
|
chMsgSend(p, 'B');
|
|
|
|
chMsgSend(p, 'C');
|
|
|
|
chMsgSend(p, 'D');
|
2016-03-30 08:58:48 -07:00
|
|
|
}]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</shared_code>
|
|
|
|
<cases>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Messages Server loop.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>A messenger thread is spawned that sends four
|
|
|
|
messages back to the tester thread.<br>
|
|
|
|
The test expect to receive the messages in the correct sequence and
|
|
|
|
to not find a fifth message waiting.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value />
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value><![CDATA[thread_t *tp;
|
2016-03-30 08:58:48 -07:00
|
|
|
msg_t msg;]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Starting the messenger thread.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX() + 1,
|
2016-03-30 08:58:48 -07:00
|
|
|
msg_thread1, chThdGetSelfX());]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Waiting for four messages then testing the
|
|
|
|
receive order.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[unsigned i;
|
2020-07-12 06:15:38 -07:00
|
|
|
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
|
|
tp = chMsgWait();
|
|
|
|
msg = chMsgGet(tp);
|
|
|
|
chMsgRelease(tp, msg);
|
|
|
|
test_emit_token(msg);
|
|
|
|
}
|
|
|
|
test_wait_threads();
|
2016-03-30 08:58:48 -07:00
|
|
|
test_assert_sequence("ABCD", "invalid sequence");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
</cases>
|
|
|
|
</sequence>
|
|
|
|
<sequence>
|
|
|
|
<type index="0">
|
|
|
|
<value>Internal Tests</value>
|
|
|
|
</type>
|
|
|
|
<brief>
|
|
|
|
<value>Event Sources and Event Flags.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>This module implements the test sequence for the Events
|
|
|
|
subsystem.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value><![CDATA[CH_CFG_USE_EVENTS == TRUE]]></value>
|
|
|
|
</condition>
|
|
|
|
<shared_code>
|
|
|
|
<value><![CDATA[static EVENTSOURCE_DECL(es1);
|
2020-07-12 06:15:38 -07:00
|
|
|
static EVENTSOURCE_DECL(es2);
|
|
|
|
|
|
|
|
static void h1(eventid_t id) {(void)id;test_emit_token('A');}
|
|
|
|
static void h2(eventid_t id) {(void)id;test_emit_token('B');}
|
|
|
|
static void h3(eventid_t id) {(void)id;test_emit_token('C');}
|
|
|
|
static ROMCONST evhandler_t evhndl[] = {h1, h2, h3};
|
|
|
|
|
|
|
|
static THD_FUNCTION(evt_thread3, p) {
|
|
|
|
|
|
|
|
chThdSleepMilliseconds(50);
|
|
|
|
chEvtSignal((thread_t *)p, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static THD_FUNCTION(evt_thread7, p) {
|
|
|
|
|
|
|
|
(void)p;
|
|
|
|
chEvtBroadcast(&es1);
|
|
|
|
chThdSleepMilliseconds(50);
|
|
|
|
chEvtBroadcast(&es2);
|
2016-03-31 07:03:43 -07:00
|
|
|
}]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</shared_code>
|
|
|
|
<cases>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Events registration.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>Two event listeners are registered on an event source
|
|
|
|
and then unregistered in the same order.<br>
|
|
|
|
The test expects that the even source has listeners after
|
|
|
|
the registrations and after the first unregistration,
|
|
|
|
then, after the second unegistration, the test expects no
|
|
|
|
more listeners.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value />
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value><![CDATA[event_listener_t el1, el2;]]></value>
|
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>An Event Source is initialized.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chEvtObjectInit(&es1);]]></value>
|
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Two Event Listeners are registered on the Event
|
|
|
|
Source, the Event Source is tested to have listeners.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chEvtRegisterMask(&es1, &el1, 1);
|
2020-07-12 06:15:38 -07:00
|
|
|
chEvtRegisterMask(&es1, &el2, 2);
|
2016-03-31 07:03:43 -07:00
|
|
|
test_assert_lock(chEvtIsListeningI(&es1), "no listener");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>An Event Listener is unregistered, the Event
|
|
|
|
Source must still have listeners.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chEvtUnregister(&es1, &el1);
|
2016-03-31 07:03:43 -07:00
|
|
|
test_assert_lock(chEvtIsListeningI(&es1), "no listener");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>An Event Listener is unregistered, the Event
|
|
|
|
Source must not have listeners.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chEvtUnregister(&es1, &el2);
|
2016-03-31 07:03:43 -07:00
|
|
|
test_assert_lock(!chEvtIsListeningI(&es1), "stuck listener");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Event Flags dispatching.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>The test dispatches three event flags and verifies
|
|
|
|
that the associated event handlers are invoked in
|
|
|
|
LSb-first order.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value><![CDATA[chEvtGetAndClearEvents(ALL_EVENTS);]]></value>
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value />
|
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Three evenf flag bits are raised then
|
|
|
|
chEvtDispatch() is invoked, the sequence of handlers
|
|
|
|
calls is tested.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chEvtDispatch(evhndl, 7);
|
2016-03-31 07:03:43 -07:00
|
|
|
test_assert_sequence("ABC", "invalid sequence");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Events Flags wait using chEvtWaitOne().</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>Functionality of chEvtWaitOne() is tested under
|
|
|
|
various scenarios.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value><![CDATA[chEvtGetAndClearEvents(ALL_EVENTS);]]></value>
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value><![CDATA[eventmask_t m;
|
2016-03-31 07:03:43 -07:00
|
|
|
systime_t target_time;]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Setting three event flags.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chEvtAddEvents(7);]]></value>
|
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Calling chEvtWaitOne() three times, each time a
|
|
|
|
single flag must be returned in order of priority.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[m = chEvtWaitOne(ALL_EVENTS);
|
2020-07-12 06:15:38 -07:00
|
|
|
test_assert(m == 1, "single event error");
|
|
|
|
m = chEvtWaitOne(ALL_EVENTS);
|
|
|
|
test_assert(m == 2, "single event error");
|
|
|
|
m = chEvtWaitOne(ALL_EVENTS);
|
|
|
|
test_assert(m == 4, "single event error");
|
|
|
|
m = chEvtGetAndClearEvents(ALL_EVENTS);
|
2016-03-31 07:03:43 -07:00
|
|
|
test_assert(m == 0, "stuck event");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Getting current time and starting a signaler
|
|
|
|
thread, the thread will set an event flag after 50mS.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[target_time = chTimeAddX(test_wait_tick(), TIME_MS2I(50));
|
2020-07-12 06:15:38 -07:00
|
|
|
threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX() - 1,
|
2016-03-31 07:03:43 -07:00
|
|
|
evt_thread3, chThdGetSelfX());]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Calling chEvtWaitOne() then verifying that the
|
|
|
|
event has been received after 50mS and that the event
|
|
|
|
flags mask has been emptied.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[m = chEvtWaitOne(ALL_EVENTS);
|
2020-07-12 06:15:38 -07:00
|
|
|
test_assert_time_window(target_time,
|
|
|
|
chTimeAddX(target_time, ALLOWED_DELAY),
|
|
|
|
"out of time window");
|
|
|
|
test_assert(m == 1, "event flag error");
|
|
|
|
m = chEvtGetAndClearEvents(ALL_EVENTS);
|
|
|
|
test_assert(m == 0, "stuck event");
|
2016-03-31 07:03:43 -07:00
|
|
|
test_wait_threads();]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Events Flags wait using chEvtWaitAny().</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>Functionality of chEvtWaitAny() is tested under
|
|
|
|
various scenarios.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value><![CDATA[chEvtGetAndClearEvents(ALL_EVENTS);]]></value>
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value><![CDATA[eventmask_t m;
|
2016-03-31 07:03:43 -07:00
|
|
|
systime_t target_time;]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Setting two, non contiguous, event flags.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chEvtAddEvents(5);]]></value>
|
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Calling chEvtWaitAny() one time, the two flags
|
|
|
|
must be returned.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[m = chEvtWaitAny(ALL_EVENTS);
|
2020-07-12 06:15:38 -07:00
|
|
|
test_assert(m == 5, "unexpected pending bit");
|
|
|
|
m = chEvtGetAndClearEvents(ALL_EVENTS);
|
2016-03-31 07:03:43 -07:00
|
|
|
test_assert(m == 0, "stuck event");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Getting current time and starting a signaler
|
|
|
|
thread, the thread will set an event flag after 50mS.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[target_time = chTimeAddX(test_wait_tick(), TIME_MS2I(50));
|
2020-07-12 06:15:38 -07:00
|
|
|
threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX() - 1,
|
2016-03-31 07:03:43 -07:00
|
|
|
evt_thread3, chThdGetSelfX());]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Calling chEvtWaitAny() then verifying that the
|
|
|
|
event has been received after 50mS and that the event
|
|
|
|
flags mask has been emptied.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[m = chEvtWaitAny(ALL_EVENTS);
|
2020-07-12 06:15:38 -07:00
|
|
|
test_assert_time_window(target_time,
|
|
|
|
chTimeAddX(target_time, ALLOWED_DELAY),
|
|
|
|
"out of time window");
|
|
|
|
test_assert(m == 1, "event flag error");
|
|
|
|
m = chEvtGetAndClearEvents(ALL_EVENTS);
|
|
|
|
test_assert(m == 0, "stuck event");
|
2016-03-31 07:03:43 -07:00
|
|
|
test_wait_threads();]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Events Flags wait using chEvtWaitAll().</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>Functionality of chEvtWaitAll() is tested under
|
|
|
|
various scenarios.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value><![CDATA[chEvtGetAndClearEvents(ALL_EVENTS);]]></value>
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value><![CDATA[eventmask_t m;
|
2016-03-31 07:03:43 -07:00
|
|
|
systime_t target_time;]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Setting two, non contiguous, event flags.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chEvtAddEvents(5);]]></value>
|
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Calling chEvtWaitAll() one time, the two flags
|
|
|
|
must be returned.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[m = chEvtWaitAll(5);
|
2020-07-12 06:15:38 -07:00
|
|
|
test_assert(m == 5, "unexpected pending bit");
|
|
|
|
m = chEvtGetAndClearEvents(ALL_EVENTS);
|
2016-03-31 07:03:43 -07:00
|
|
|
test_assert(m == 0, "stuck event");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Setting one event flag.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chEvtAddEvents(4);]]></value>
|
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Getting current time and starting a signaler
|
|
|
|
thread, the thread will set another event flag after
|
|
|
|
50mS.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[target_time = chTimeAddX(test_wait_tick(), TIME_MS2I(50));
|
2020-07-12 06:15:38 -07:00
|
|
|
threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX() - 1,
|
2016-03-31 07:03:43 -07:00
|
|
|
evt_thread3, chThdGetSelfX());]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Calling chEvtWaitAll() then verifying that both
|
|
|
|
event flags have been received after 50mS and that the
|
|
|
|
event flags mask has been emptied.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[m = chEvtWaitAll(5);
|
2020-07-12 06:15:38 -07:00
|
|
|
test_assert_time_window(target_time,
|
|
|
|
chTimeAddX(target_time, ALLOWED_DELAY),
|
|
|
|
"out of time window");
|
|
|
|
test_assert(m == 5, "event flags error");
|
|
|
|
m = chEvtGetAndClearEvents(ALL_EVENTS);
|
|
|
|
test_assert(m == 0, "stuck event");
|
2016-03-31 07:03:43 -07:00
|
|
|
test_wait_threads();]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Events Flags wait timeouts.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>Timeout functionality is tested for
|
|
|
|
chEvtWaitOneTimeout(), chEvtWaitAnyTimeout() and
|
|
|
|
chEvtWaitAllTimeout().</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value><![CDATA[CH_CFG_USE_EVENTS_TIMEOUT == TRUE]]></value>
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value><![CDATA[chEvtGetAndClearEvents(ALL_EVENTS);]]></value>
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value><![CDATA[eventmask_t m;]]></value>
|
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The functions are invoked first with
|
|
|
|
TIME_IMMEDIATE timeout, the timeout condition is
|
|
|
|
tested.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[m = chEvtWaitOneTimeout(ALL_EVENTS, TIME_IMMEDIATE);
|
2020-07-12 06:15:38 -07:00
|
|
|
test_assert(m == 0, "spurious event");
|
|
|
|
m = chEvtWaitAnyTimeout(ALL_EVENTS, TIME_IMMEDIATE);
|
|
|
|
test_assert(m == 0, "spurious event");
|
|
|
|
m = chEvtWaitAllTimeout(ALL_EVENTS, TIME_IMMEDIATE);
|
2016-03-31 07:57:58 -07:00
|
|
|
test_assert(m == 0, "spurious event");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The functions are invoked first with a 50mS
|
|
|
|
timeout, the timeout condition is tested.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[m = chEvtWaitOneTimeout(ALL_EVENTS, TIME_MS2I(50));
|
2020-07-12 06:15:38 -07:00
|
|
|
test_assert(m == 0, "spurious event");
|
|
|
|
m = chEvtWaitAnyTimeout(ALL_EVENTS, TIME_MS2I(50));
|
|
|
|
test_assert(m == 0, "spurious event");
|
|
|
|
m = chEvtWaitAllTimeout(ALL_EVENTS, TIME_MS2I(50));
|
2016-03-31 07:57:58 -07:00
|
|
|
test_assert(m == 0, "spurious event");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Broadcasting using chEvtBroadcast().</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>Functionality of chEvtBroadcast() is tested.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value><![CDATA[chEvtGetAndClearEvents(ALL_EVENTS);
|
2020-07-12 06:15:38 -07:00
|
|
|
chEvtObjectInit(&es1);
|
2016-03-31 07:57:58 -07:00
|
|
|
chEvtObjectInit(&es2);]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value><![CDATA[eventmask_t m;
|
2020-07-12 06:15:38 -07:00
|
|
|
event_listener_t el1, el2;
|
2016-03-31 07:57:58 -07:00
|
|
|
systime_t target_time;]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Registering on two event sources associating them
|
|
|
|
with flags 1 and 4.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chEvtRegisterMask(&es1, &el1, 1);
|
2016-03-31 07:57:58 -07:00
|
|
|
chEvtRegisterMask(&es2, &el2, 4);]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Getting current time and starting a broadcaster
|
|
|
|
thread, the thread broadcast the first Event Source
|
|
|
|
immediately and the other after 50mS.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[target_time = chTimeAddX(test_wait_tick(), TIME_MS2I(50));
|
2020-07-12 06:15:38 -07:00
|
|
|
threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX() - 1,
|
2016-03-31 07:57:58 -07:00
|
|
|
evt_thread7, "A");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Calling chEvtWaitAll() then verifying that both
|
|
|
|
event flags have been received after 50mS and that the
|
|
|
|
event flags mask has been emptied.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[m = chEvtWaitAll(5);
|
2020-07-12 06:15:38 -07:00
|
|
|
test_assert_time_window(target_time,
|
|
|
|
chTimeAddX(target_time, ALLOWED_DELAY),
|
|
|
|
"out of time window");
|
|
|
|
m = chEvtGetAndClearEvents(ALL_EVENTS);
|
|
|
|
test_assert(m == 0, "stuck event");
|
2016-03-31 07:57:58 -07:00
|
|
|
test_wait_threads();]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Unregistering from the Event Sources.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chEvtUnregister(&es1, &el1);
|
2020-07-12 06:15:38 -07:00
|
|
|
chEvtUnregister(&es2, &el2);
|
|
|
|
test_assert(!chEvtIsListeningI(&es1), "stuck listener");
|
2016-03-31 07:57:58 -07:00
|
|
|
test_assert(!chEvtIsListeningI(&es2), "stuck listener");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
</cases>
|
|
|
|
</sequence>
|
|
|
|
<sequence>
|
|
|
|
<type index="0">
|
|
|
|
<value>Internal Tests</value>
|
|
|
|
</type>
|
|
|
|
<brief>
|
|
|
|
<value>Dynamic threads.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>This module implements the test sequence for the dynamic
|
|
|
|
thread creation APIs.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value><![CDATA[CH_CFG_USE_DYNAMIC == TRUE]]></value>
|
|
|
|
</condition>
|
|
|
|
<shared_code>
|
|
|
|
<value><![CDATA[#if CH_CFG_USE_HEAP
|
2020-07-12 06:15:38 -07:00
|
|
|
static memory_heap_t heap1;
|
|
|
|
#endif
|
|
|
|
#if CH_CFG_USE_MEMPOOLS
|
|
|
|
static memory_pool_t mp1;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static THD_FUNCTION(dyn_thread1, p) {
|
|
|
|
|
|
|
|
test_emit_token(*(char *)p);
|
2016-03-31 22:08:20 -07:00
|
|
|
}]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</shared_code>
|
|
|
|
<cases>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Threads creation from Memory Heap.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>Two threads are started by allocating the memory from
|
|
|
|
the Memory Heap then a third thread is started with a huge
|
|
|
|
stack requirement.<br>
|
|
|
|
The test expects the first two threads to successfully start and the
|
|
|
|
third one to fail.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value><![CDATA[CH_CFG_USE_HEAP == TRUE]]></value>
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value><![CDATA[chHeapObjectInit(&heap1, test_buffer, sizeof test_buffer);]]></value>
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value><![CDATA[size_t n1, total1, largest1;
|
2020-07-12 06:15:38 -07:00
|
|
|
size_t n2, total2, largest2;
|
2016-03-31 22:08:20 -07:00
|
|
|
tprio_t prio;]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Getting base priority for threads.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[prio = chThdGetPriorityX();]]></value>
|
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Getting heap info before the test.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[n1 = chHeapStatus(&heap1, &total1, &largest1);
|
2016-03-31 22:08:20 -07:00
|
|
|
test_assert(n1 == 1, "heap fragmented");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Creating thread 1, it is expected to succeed.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[threads[0] = chThdCreateFromHeap(&heap1,
|
2020-07-12 06:15:38 -07:00
|
|
|
THD_WORKING_AREA_SIZE(THREADS_STACK_SIZE),
|
|
|
|
"dyn1",
|
|
|
|
prio-1, dyn_thread1, "A");
|
2016-03-31 22:08:20 -07:00
|
|
|
test_assert(threads[0] != NULL, "thread creation failed");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Creating thread 2, it is expected to succeed.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[threads[1] = chThdCreateFromHeap(&heap1,
|
2020-07-12 06:15:38 -07:00
|
|
|
THD_WORKING_AREA_SIZE(THREADS_STACK_SIZE),
|
|
|
|
"dyn2",
|
|
|
|
prio-2, dyn_thread1, "B");
|
2016-03-31 22:08:20 -07:00
|
|
|
test_assert(threads[1] != NULL, "thread creation failed");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Creating thread 3, it is expected to fail</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[threads[2] = chThdCreateFromHeap(&heap1,
|
2018-02-06 01:41:01 -08:00
|
|
|
(((size_t)-1) >> 1U) + 1U,
|
2020-07-12 06:15:38 -07:00
|
|
|
"dyn3",
|
|
|
|
prio-3, dyn_thread1, "C");
|
2016-03-31 22:08:20 -07:00
|
|
|
test_assert(threads[2] == NULL, "thread creation not failed");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Letting threads execute then checking the start
|
|
|
|
order and freeing memory.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[test_wait_threads();
|
2016-03-31 22:08:20 -07:00
|
|
|
test_assert_sequence("AB", "invalid sequence");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Getting heap info again for verification.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[n2 = chHeapStatus(&heap1, &total2, &largest2);
|
2020-07-12 06:15:38 -07:00
|
|
|
test_assert(n1 == n2, "fragmentation changed");
|
|
|
|
test_assert(total1 == total2, "total free space changed");
|
2016-03-31 22:08:20 -07:00
|
|
|
test_assert(largest1 == largest2, "largest fragment size changed");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Threads creation from Memory Pool.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>Five thread creation are attempted from a pool
|
|
|
|
containing only four elements.<br>
|
|
|
|
The test expects the first four threads to successfully start and
|
|
|
|
the last one to fail.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value><![CDATA[CH_CFG_USE_MEMPOOLS == TRUE]]></value>
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value><![CDATA[chPoolObjectInit(&mp1, THD_WORKING_AREA_SIZE(THREADS_STACK_SIZE), NULL);]]></value>
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value><![CDATA[unsigned i;
|
2016-03-31 22:08:20 -07:00
|
|
|
tprio_t prio;]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Adding four working areas to the pool.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[for (i = 0; i < 4; i++)
|
2016-03-31 22:08:20 -07:00
|
|
|
chPoolFree(&mp1, wa[i]);]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Getting base priority for threads.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[prio = chThdGetPriorityX();]]></value>
|
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Creating the five threads.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[threads[0] = chThdCreateFromMemoryPool(&mp1, "dyn1", prio-1, dyn_thread1, "A");
|
2020-07-12 06:15:38 -07:00
|
|
|
threads[1] = chThdCreateFromMemoryPool(&mp1, "dyn2", prio-2, dyn_thread1, "B");
|
|
|
|
threads[2] = chThdCreateFromMemoryPool(&mp1, "dyn3", prio-3, dyn_thread1, "C");
|
|
|
|
threads[3] = chThdCreateFromMemoryPool(&mp1, "dyn4", prio-4, dyn_thread1, "D");
|
2016-03-31 22:08:20 -07:00
|
|
|
threads[4] = chThdCreateFromMemoryPool(&mp1, "dyn5", prio-5, dyn_thread1, "E");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Testing that only the fifth thread creation
|
|
|
|
failed.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[test_assert((threads[0] != NULL) &&
|
2020-07-12 06:15:38 -07:00
|
|
|
(threads[1] != NULL) &&
|
|
|
|
(threads[2] != NULL) &&
|
|
|
|
(threads[3] != NULL),
|
|
|
|
"thread creation failed");
|
|
|
|
test_assert(threads[4] == NULL,
|
2016-03-31 22:08:20 -07:00
|
|
|
"thread creation not failed");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Letting them run, free the memory then checking
|
|
|
|
the execution sequence.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[test_wait_threads();
|
2016-03-31 22:08:20 -07:00
|
|
|
test_assert_sequence("ABCD", "invalid sequence");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Testing that the pool contains four elements
|
|
|
|
again.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[for (i = 0; i < 4; i++)
|
2020-07-12 06:15:38 -07:00
|
|
|
test_assert(chPoolAlloc(&mp1) != NULL, "pool list empty");
|
2016-03-31 22:08:20 -07:00
|
|
|
test_assert(chPoolAlloc(&mp1) == NULL, "pool list not empty");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
</cases>
|
|
|
|
</sequence>
|
|
|
|
<sequence>
|
|
|
|
<type index="2">
|
|
|
|
<value>Benchmarks</value>
|
|
|
|
</type>
|
|
|
|
<brief>
|
|
|
|
<value>Benchmarks.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>This module implements a series of system benchmarks. The
|
|
|
|
benchmarks are useful as a stress test and as a reference when
|
|
|
|
comparing ChibiOS/RT with similar systems.<br>
|
|
|
|
Objective of the test sequence is to provide a performance
|
|
|
|
index for the most critical system subsystems. The performance
|
|
|
|
numbers allow to discover performance regressions between
|
|
|
|
successive ChibiOS/RT releases.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<shared_code>
|
|
|
|
<value><![CDATA[#if CH_CFG_USE_SEMAPHORES || defined(__DOXYGEN__)
|
2020-07-12 06:15:38 -07:00
|
|
|
static semaphore_t sem1;
|
|
|
|
#endif
|
|
|
|
#if CH_CFG_USE_MUTEXES || defined(__DOXYGEN__)
|
|
|
|
static mutex_t mtx1;
|
|
|
|
#endif
|
|
|
|
|
2021-05-07 04:30:54 -07:00
|
|
|
static void tmo(virtual_timer_t *vtp, void *param) {
|
|
|
|
|
|
|
|
(void)vtp;
|
|
|
|
(void)param;
|
|
|
|
}
|
2020-07-12 06:15:38 -07:00
|
|
|
|
|
|
|
#if CH_CFG_USE_MESSAGES
|
|
|
|
static THD_FUNCTION(bmk_thread1, p) {
|
|
|
|
thread_t *tp;
|
|
|
|
msg_t msg;
|
|
|
|
|
|
|
|
(void)p;
|
|
|
|
do {
|
|
|
|
tp = chMsgWait();
|
|
|
|
msg = chMsgGet(tp);
|
|
|
|
chMsgRelease(tp, msg);
|
|
|
|
} while (msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
NOINLINE static unsigned int msg_loop_test(thread_t *tp) {
|
|
|
|
systime_t start, end;
|
|
|
|
|
|
|
|
uint32_t n = 0;
|
|
|
|
start = test_wait_tick();
|
|
|
|
end = chTimeAddX(start, TIME_MS2I(1000));
|
|
|
|
do {
|
|
|
|
(void)chMsgSend(tp, 1);
|
|
|
|
n++;
|
|
|
|
#if defined(SIMULATOR)
|
|
|
|
_sim_check_for_interrupts();
|
|
|
|
#endif
|
|
|
|
} while (chVTIsSystemTimeWithinX(start, end));
|
|
|
|
(void)chMsgSend(tp, 0);
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static THD_FUNCTION(bmk_thread3, p) {
|
|
|
|
|
|
|
|
chThdExit((msg_t)p);
|
|
|
|
}
|
|
|
|
|
|
|
|
static THD_FUNCTION(bmk_thread4, p) {
|
|
|
|
msg_t msg;
|
|
|
|
thread_t *self = chThdGetSelfX();
|
|
|
|
|
|
|
|
(void)p;
|
|
|
|
chSysLock();
|
|
|
|
do {
|
|
|
|
chSchGoSleepS(CH_STATE_SUSPENDED);
|
|
|
|
msg = self->u.rdymsg;
|
|
|
|
} while (msg == MSG_OK);
|
|
|
|
chSysUnlock();
|
|
|
|
}
|
|
|
|
|
|
|
|
#if CH_CFG_USE_SEMAPHORES
|
|
|
|
static THD_FUNCTION(bmk_thread7, p) {
|
|
|
|
|
|
|
|
(void)p;
|
|
|
|
while (!chThdShouldTerminateX())
|
|
|
|
chSemWait(&sem1);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static THD_FUNCTION(bmk_thread8, p) {
|
|
|
|
|
|
|
|
do {
|
|
|
|
chThdYield();
|
|
|
|
chThdYield();
|
|
|
|
chThdYield();
|
|
|
|
chThdYield();
|
|
|
|
(*(uint32_t *)p) += 4;
|
|
|
|
#if defined(SIMULATOR)
|
|
|
|
_sim_check_for_interrupts();
|
|
|
|
#endif
|
|
|
|
} while(!chThdShouldTerminateX());
|
2016-04-01 02:08:17 -07:00
|
|
|
}]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</shared_code>
|
|
|
|
<cases>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Messages performance #1.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>A message server thread is created with a lower
|
|
|
|
priority than the client thread, the messages throughput
|
|
|
|
per second is measured and the result printed on the
|
|
|
|
output log.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value><![CDATA[CH_CFG_USE_MESSAGES == TRUE]]></value>
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value />
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value><![CDATA[uint32_t n;]]></value>
|
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The messenger thread is started at a lower
|
|
|
|
priority than the current thread.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()-1, bmk_thread1, NULL);]]></value>
|
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The number of messages exchanged is counted in a
|
|
|
|
one second time window.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[n = msg_loop_test(threads[0]);
|
2016-04-01 02:08:17 -07:00
|
|
|
test_wait_threads();]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Score is printed.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[test_print("--- Score : ");
|
2020-07-12 06:15:38 -07:00
|
|
|
test_printn(n);
|
|
|
|
test_print(" msgs/S, ");
|
|
|
|
test_printn(n << 1);
|
2016-04-01 02:08:17 -07:00
|
|
|
test_println(" ctxswc/S");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Messages performance #2.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>A message server thread is created with an higher
|
|
|
|
priority than the client thread, the messages throughput
|
|
|
|
per second is measured and the result printed on the
|
|
|
|
output log.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value><![CDATA[CH_CFG_USE_MESSAGES == TRUE]]></value>
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value />
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value><![CDATA[uint32_t n;]]></value>
|
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The messenger thread is started at an higher
|
|
|
|
priority than the current thread.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+1, bmk_thread1, NULL);]]></value>
|
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The number of messages exchanged is counted in a
|
|
|
|
one second time window.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[n = msg_loop_test(threads[0]);
|
2016-04-01 02:08:17 -07:00
|
|
|
test_wait_threads();]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Score is printed.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[test_print("--- Score : ");
|
2020-07-12 06:15:38 -07:00
|
|
|
test_printn(n);
|
|
|
|
test_print(" msgs/S, ");
|
|
|
|
test_printn(n << 1);
|
2016-04-01 02:08:17 -07:00
|
|
|
test_println(" ctxswc/S");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Messages performance #3.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>A message server thread is created with an higher
|
|
|
|
priority than the client thread, four lower priority
|
|
|
|
threads crowd the ready list, the messages throughput per
|
|
|
|
second is measured while the ready list and the result
|
|
|
|
printed on the output log.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value><![CDATA[CH_CFG_USE_MESSAGES == TRUE]]></value>
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value />
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value><![CDATA[uint32_t n;]]></value>
|
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The messenger thread is started at an higher
|
|
|
|
priority than the current thread.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+1, bmk_thread1, NULL);]]></value>
|
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Four threads are started at a lower priority than
|
|
|
|
the current thread.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriorityX()-2, bmk_thread3, NULL);
|
2020-07-12 06:15:38 -07:00
|
|
|
threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriorityX()-3, bmk_thread3, NULL);
|
|
|
|
threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriorityX()-4, bmk_thread3, NULL);
|
2016-04-01 02:08:17 -07:00
|
|
|
threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriorityX()-5, bmk_thread3, NULL);]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The number of messages exchanged is counted in a
|
|
|
|
one second time window.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[n = msg_loop_test(threads[0]);
|
2016-04-01 02:08:17 -07:00
|
|
|
test_wait_threads();]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Score is printed.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[test_print("--- Score : ");
|
2020-07-12 06:15:38 -07:00
|
|
|
test_printn(n);
|
|
|
|
test_print(" msgs/S, ");
|
|
|
|
test_printn(n << 1);
|
2016-04-01 02:08:17 -07:00
|
|
|
test_println(" ctxswc/S");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Context Switch performance.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>A thread is created that just performs a @p
|
|
|
|
chSchGoSleepS() into a loop, the thread is awakened as
|
|
|
|
fast is possible by the tester thread.<br>
|
|
|
|
The Context Switch performance is calculated by measuring the number
|
|
|
|
of iterations after a second of continuous operations.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value />
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value><![CDATA[thread_t *tp;
|
2016-04-01 02:08:17 -07:00
|
|
|
uint32_t n;]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Starting the target thread at an higher priority
|
|
|
|
level.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[tp = threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+1,
|
2016-04-01 02:08:17 -07:00
|
|
|
bmk_thread4, NULL);]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Waking up the thread as fast as possible in a one
|
|
|
|
second time window.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[systime_t start, end;
|
2020-07-12 06:15:38 -07:00
|
|
|
|
|
|
|
n = 0;
|
|
|
|
start = test_wait_tick();
|
|
|
|
end = chTimeAddX(start, TIME_MS2I(1000));
|
|
|
|
do {
|
|
|
|
chSysLock();
|
|
|
|
chSchWakeupS(tp, MSG_OK);
|
|
|
|
chSchWakeupS(tp, MSG_OK);
|
|
|
|
chSchWakeupS(tp, MSG_OK);
|
|
|
|
chSchWakeupS(tp, MSG_OK);
|
|
|
|
chSysUnlock();
|
|
|
|
n += 4;
|
|
|
|
#if defined(SIMULATOR)
|
|
|
|
_sim_check_for_interrupts();
|
|
|
|
#endif
|
2016-04-01 02:08:17 -07:00
|
|
|
} while (chVTIsSystemTimeWithinX(start, end));]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Stopping the target thread.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chSysLock();
|
2020-07-12 06:15:38 -07:00
|
|
|
chSchWakeupS(tp, MSG_TIMEOUT);
|
|
|
|
chSysUnlock();
|
2016-04-01 02:08:17 -07:00
|
|
|
test_wait_threads();]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Score is printed.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[test_print("--- Score : ");
|
2020-07-12 06:15:38 -07:00
|
|
|
test_printn(n * 2);
|
2016-04-01 02:08:17 -07:00
|
|
|
test_println(" ctxswc/S");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Threads performance, full cycle.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>Threads are continuously created and terminated into
|
|
|
|
a loop. A full chThdCreateStatic() / @p chThdExit() / @p
|
|
|
|
chThdWait() cycle is performed in each
|
|
|
|
iteration.<br>
|
|
|
|
The performance is calculated by measuring the number of iterations
|
|
|
|
after a second of continuous operations.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value />
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value><![CDATA[uint32_t n;
|
2020-07-12 06:15:38 -07:00
|
|
|
tprio_t prio = chThdGetPriorityX() - 1;
|
2016-04-01 02:08:17 -07:00
|
|
|
systime_t start, end;]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>A thread is created at a lower priority level and
|
|
|
|
its termination detected using @p chThdWait(). The
|
|
|
|
operation is repeated continuously in a one-second
|
|
|
|
time window.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[n = 0;
|
2020-07-12 06:15:38 -07:00
|
|
|
start = test_wait_tick();
|
|
|
|
end = chTimeAddX(start, TIME_MS2I(1000));
|
|
|
|
do {
|
|
|
|
chThdWait(chThdCreateStatic(wa[0], WA_SIZE, prio, bmk_thread3, NULL));
|
|
|
|
n++;
|
|
|
|
#if defined(SIMULATOR)
|
|
|
|
_sim_check_for_interrupts();
|
|
|
|
#endif
|
2016-04-01 02:08:17 -07:00
|
|
|
} while (chVTIsSystemTimeWithinX(start, end));]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Score is printed.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[test_print("--- Score : ");
|
2020-07-12 06:15:38 -07:00
|
|
|
test_printn(n);
|
2016-04-01 02:08:17 -07:00
|
|
|
test_println(" threads/S");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Threads performance, create/exit only.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>Threads are continuously created and terminated into
|
|
|
|
a loop. A partial @p chThdCreateStatic() / @p chThdExit()
|
|
|
|
cycle is performed in each iteration, the @p chThdWait()
|
|
|
|
is not necessary because the thread is created at an
|
|
|
|
higher priority so there is no need to wait for it to
|
|
|
|
terminate.<br> The performance is calculated by
|
|
|
|
measuring the number of iterations after a second of
|
|
|
|
continuous operations.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value />
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value><![CDATA[uint32_t n;
|
2020-07-12 06:15:38 -07:00
|
|
|
tprio_t prio = chThdGetPriorityX() + 1;
|
2016-04-01 02:08:17 -07:00
|
|
|
systime_t start, end;]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>A thread is created at an higher priority level
|
|
|
|
and let terminate immediately. The operation is
|
|
|
|
repeated continuously in a one-second time window.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[n = 0;
|
2020-07-12 06:15:38 -07:00
|
|
|
start = test_wait_tick();
|
|
|
|
end = chTimeAddX(start, TIME_MS2I(1000));
|
|
|
|
do {
|
|
|
|
#if CH_CFG_USE_REGISTRY
|
|
|
|
chThdRelease(chThdCreateStatic(wa[0], WA_SIZE, prio, bmk_thread3, NULL));
|
|
|
|
#else
|
|
|
|
chThdCreateStatic(wa[0], WA_SIZE, prio, bmk_thread3, NULL);
|
|
|
|
#endif
|
|
|
|
n++;
|
|
|
|
#if defined(SIMULATOR)
|
|
|
|
_sim_check_for_interrupts();
|
|
|
|
#endif
|
2016-04-01 02:08:17 -07:00
|
|
|
} while (chVTIsSystemTimeWithinX(start, end));]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Score is printed.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[test_print("--- Score : ");
|
2020-07-12 06:15:38 -07:00
|
|
|
test_printn(n);
|
2016-04-01 02:08:17 -07:00
|
|
|
test_println(" threads/S");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Mass reschedule performance.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>Five threads are created and atomically rescheduled
|
|
|
|
by resetting the semaphore where they are waiting on. The
|
|
|
|
operation is performed into a continuous
|
|
|
|
loop.<br>
|
|
|
|
The performance is calculated by measuring the number of iterations
|
|
|
|
after a second of continuous operations.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value><![CDATA[CH_CFG_USE_SEMAPHORES == TRUE]]></value>
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value><![CDATA[chSemObjectInit(&sem1, 0);]]></value>
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value><![CDATA[uint32_t n;]]></value>
|
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Five threads are created at higher priority that
|
|
|
|
immediately enqueue on a semaphore.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+5, bmk_thread7, NULL);
|
2020-07-12 06:15:38 -07:00
|
|
|
threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriorityX()+4, bmk_thread7, NULL);
|
|
|
|
threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriorityX()+3, bmk_thread7, NULL);
|
|
|
|
threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriorityX()+2, bmk_thread7, NULL);
|
2016-04-01 05:13:54 -07:00
|
|
|
threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriorityX()+1, bmk_thread7, NULL);]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The semaphore is reset waking up the five
|
|
|
|
threads. The operation is repeated continuously in a
|
|
|
|
one-second time window.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[systime_t start, end;
|
2020-07-12 06:15:38 -07:00
|
|
|
|
|
|
|
n = 0;
|
|
|
|
start = test_wait_tick();
|
|
|
|
end = chTimeAddX(start, TIME_MS2I(1000));
|
|
|
|
do {
|
|
|
|
chSemReset(&sem1, 0);
|
|
|
|
n++;
|
|
|
|
#if defined(SIMULATOR)
|
|
|
|
_sim_check_for_interrupts();
|
|
|
|
#endif
|
2016-04-01 05:13:54 -07:00
|
|
|
} while (chVTIsSystemTimeWithinX(start, end));]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The five threads are terminated.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[test_terminate_threads();
|
2020-07-12 06:15:38 -07:00
|
|
|
chSemReset(&sem1, 0);
|
2016-04-01 05:13:54 -07:00
|
|
|
test_wait_threads();]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The score is printed.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[test_print("--- Score : ");
|
2020-07-12 06:15:38 -07:00
|
|
|
test_printn(n);
|
|
|
|
test_print(" reschedules/S, ");
|
|
|
|
test_printn(n * 6);
|
2016-04-01 05:13:54 -07:00
|
|
|
test_println(" ctxswc/S");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Round-Robin voluntary reschedule.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>Five threads are created at equal priority, each
|
|
|
|
thread just increases a variable and
|
|
|
|
yields.<br>
|
|
|
|
The performance is calculated by measuring the number of iterations
|
|
|
|
after a second of continuous operations.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value />
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value><![CDATA[uint32_t n;]]></value>
|
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The five threads are created at lower priority.
|
|
|
|
The threds have equal priority and start calling @p
|
|
|
|
chThdYield() continuously.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[n = 0;
|
2020-07-12 06:15:38 -07:00
|
|
|
test_wait_tick();threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()-1, bmk_thread8, (void *)&n);
|
|
|
|
|
|
|
|
threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriorityX()-1, bmk_thread8, (void *)&n);
|
|
|
|
threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriorityX()-1, bmk_thread8, (void *)&n);
|
|
|
|
threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriorityX()-1, bmk_thread8, (void *)&n);
|
2016-04-01 05:13:54 -07:00
|
|
|
threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriorityX()-1, bmk_thread8, (void *)&n);]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Waiting one second then terminating the 5
|
|
|
|
threads.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[chThdSleepSeconds(1);
|
2020-07-12 06:15:38 -07:00
|
|
|
test_terminate_threads();
|
2016-04-01 05:13:54 -07:00
|
|
|
test_wait_threads();]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The score is printed.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[test_print("--- Score : ");
|
2020-07-12 06:15:38 -07:00
|
|
|
test_printn(n);
|
2016-04-01 05:13:54 -07:00
|
|
|
test_println(" ctxswc/S");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Virtual Timers set/reset performance.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>A virtual timer is set and immediately reset into a
|
|
|
|
continuous loop.<br>
|
|
|
|
The performance is calculated by measuring the number of iterations
|
|
|
|
after a second of continuous operations.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value />
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value><![CDATA[static virtual_timer_t vt1, vt2;
|
2016-04-01 05:13:54 -07:00
|
|
|
uint32_t n;]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>Two timers are set then reset without waiting for
|
|
|
|
their counter to elapse. The operation is repeated
|
|
|
|
continuously in a one-second time window.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[systime_t start, end;
|
2020-07-12 06:15:38 -07:00
|
|
|
|
|
|
|
n = 0;
|
|
|
|
start = test_wait_tick();
|
|
|
|
end = chTimeAddX(start, TIME_MS2I(1000));
|
|
|
|
do {
|
|
|
|
chSysLock();
|
|
|
|
chVTDoSetI(&vt1, 1, tmo, NULL);
|
|
|
|
chVTDoSetI(&vt2, 10000, tmo, NULL);
|
|
|
|
chVTDoResetI(&vt1);
|
|
|
|
chVTDoResetI(&vt2);
|
|
|
|
chSysUnlock();
|
|
|
|
n++;
|
|
|
|
#if defined(SIMULATOR)
|
|
|
|
_sim_check_for_interrupts();
|
|
|
|
#endif
|
2016-04-01 05:13:54 -07:00
|
|
|
} while (chVTIsSystemTimeWithinX(start, end));]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The score is printed.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[test_print("--- Score : ");
|
2020-07-12 06:15:38 -07:00
|
|
|
test_printn(n * 2);
|
2016-04-01 05:13:54 -07:00
|
|
|
test_println(" timers/S");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Semaphores wait/signal performance</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>A counting semaphore is taken/released into a
|
|
|
|
continuous loop, no Context Switch happens because the
|
|
|
|
counter is always non negative.<br>
|
|
|
|
The performance is calculated by measuring the number of iterations
|
|
|
|
after a second of continuous operations.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value><![CDATA[CH_CFG_USE_SEMAPHORES == TRUE]]></value>
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value><![CDATA[chSemObjectInit(&sem1, 1);]]></value>
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value><![CDATA[uint32_t n;]]></value>
|
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>A semaphore is teken and released. The operation
|
|
|
|
is repeated continuously in a one-second time window.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[systime_t start, end;
|
2020-07-12 06:15:38 -07:00
|
|
|
|
|
|
|
n = 0;
|
|
|
|
start = test_wait_tick();
|
|
|
|
end = chTimeAddX(start, TIME_MS2I(1000));
|
|
|
|
do {
|
|
|
|
chSemWait(&sem1);
|
|
|
|
chSemSignal(&sem1);
|
|
|
|
chSemWait(&sem1);
|
|
|
|
chSemSignal(&sem1);
|
|
|
|
chSemWait(&sem1);
|
|
|
|
chSemSignal(&sem1);
|
|
|
|
chSemWait(&sem1);
|
|
|
|
chSemSignal(&sem1);
|
|
|
|
n++;
|
|
|
|
#if defined(SIMULATOR)
|
|
|
|
_sim_check_for_interrupts();
|
|
|
|
#endif
|
2016-04-01 05:13:54 -07:00
|
|
|
} while (chVTIsSystemTimeWithinX(start, end));]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The score is printed.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[test_print("--- Score : ");
|
2020-07-12 06:15:38 -07:00
|
|
|
test_printn(n * 4);
|
2016-04-01 05:13:54 -07:00
|
|
|
test_println(" wait+signal/S");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>Mutexes lock/unlock performance</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>A mutex is locked/unlocked into a continuous loop, no
|
|
|
|
Context Switch happens because there are no other threads
|
|
|
|
asking for the mutex.<br>
|
|
|
|
The performance is calculated by measuring the number of iterations
|
|
|
|
after a second of continuous operations.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value><![CDATA[CH_CFG_USE_MUTEXES ==TRUE]]></value>
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value><![CDATA[chMtxObjectInit(&mtx1);]]></value>
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value><![CDATA[uint32_t n;]]></value>
|
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>A mutex is locked and unlocked. The operation is
|
|
|
|
repeated continuously in a one-second time window.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[systime_t start, end;
|
2020-07-12 06:15:38 -07:00
|
|
|
|
|
|
|
n = 0;
|
|
|
|
start = test_wait_tick();
|
|
|
|
end = chTimeAddX(start, TIME_MS2I(1000));
|
|
|
|
do {
|
|
|
|
chMtxLock(&mtx1);
|
|
|
|
chMtxUnlock(&mtx1);
|
|
|
|
chMtxLock(&mtx1);
|
|
|
|
chMtxUnlock(&mtx1);
|
|
|
|
chMtxLock(&mtx1);
|
|
|
|
chMtxUnlock(&mtx1);
|
|
|
|
chMtxLock(&mtx1);
|
|
|
|
chMtxUnlock(&mtx1);
|
|
|
|
n++;
|
|
|
|
#if defined(SIMULATOR)
|
|
|
|
_sim_check_for_interrupts();
|
|
|
|
#endif
|
2016-04-01 05:13:54 -07:00
|
|
|
} while (chVTIsSystemTimeWithinX(start, end));]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The score is printed.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[test_print("--- Score : ");
|
2020-07-12 06:15:38 -07:00
|
|
|
test_printn(n * 4);
|
2016-04-01 05:13:54 -07:00
|
|
|
test_println(" lock+unlock/S");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
<case>
|
|
|
|
<brief>
|
|
|
|
<value>RAM Footprint.</value>
|
|
|
|
</brief>
|
|
|
|
<description>
|
|
|
|
<value>The memory size of the various kernel objects is
|
|
|
|
printed.</value>
|
|
|
|
</description>
|
|
|
|
<condition>
|
|
|
|
<value />
|
|
|
|
</condition>
|
|
|
|
<various_code>
|
|
|
|
<setup_code>
|
|
|
|
<value />
|
|
|
|
</setup_code>
|
|
|
|
<teardown_code>
|
|
|
|
<value />
|
|
|
|
</teardown_code>
|
|
|
|
<local_variables>
|
|
|
|
<value />
|
|
|
|
</local_variables>
|
|
|
|
</various_code>
|
|
|
|
<steps>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The size of the system area is printed.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[test_print("--- OS : ");
|
2020-07-12 06:15:38 -07:00
|
|
|
test_printn(sizeof(os_instance_t));
|
2016-04-01 05:13:54 -07:00
|
|
|
test_println(" bytes");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The size of a thread structure is printed.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[test_print("--- Thread: ");
|
2020-07-12 06:15:38 -07:00
|
|
|
test_printn(sizeof(thread_t));
|
2016-04-01 05:13:54 -07:00
|
|
|
test_println(" bytes");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The size of a virtual timer structure is printed.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[test_print("--- Timer : ");
|
2020-07-12 06:15:38 -07:00
|
|
|
test_printn(sizeof(virtual_timer_t));
|
2016-04-01 05:13:54 -07:00
|
|
|
test_println(" bytes");]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The size of a semaphore structure is printed.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[#if CH_CFG_USE_SEMAPHORES || defined(__DOXYGEN__)
|
2020-07-12 06:15:38 -07:00
|
|
|
test_print("--- Semaph: ");
|
|
|
|
test_printn(sizeof(semaphore_t));
|
|
|
|
test_println(" bytes");
|
2016-04-01 05:13:54 -07:00
|
|
|
#endif]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The size of a mutex is printed.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[#if CH_CFG_USE_MUTEXES || defined(__DOXYGEN__)
|
2020-07-12 06:15:38 -07:00
|
|
|
test_print("--- Mutex : ");
|
|
|
|
test_printn(sizeof(mutex_t));
|
|
|
|
test_println(" bytes");
|
2016-04-01 05:13:54 -07:00
|
|
|
#endif]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The size of a condition variable is printed.
|
|
|
|
</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[#if CH_CFG_USE_CONDVARS || defined(__DOXYGEN__)
|
2020-07-12 06:15:38 -07:00
|
|
|
test_print("--- CondV.: ");
|
|
|
|
test_printn(sizeof(condition_variable_t));
|
|
|
|
test_println(" bytes");
|
2016-04-01 05:13:54 -07:00
|
|
|
#endif]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The size of an event source is printed.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[#if CH_CFG_USE_EVENTS || defined(__DOXYGEN__)
|
2020-07-12 06:15:38 -07:00
|
|
|
test_print("--- EventS: ");
|
|
|
|
test_printn(sizeof(event_source_t));
|
|
|
|
test_println(" bytes");
|
2016-04-01 05:13:54 -07:00
|
|
|
#endif]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The size of an event listener is printed.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[#if CH_CFG_USE_EVENTS || defined(__DOXYGEN__)
|
2020-07-12 06:15:38 -07:00
|
|
|
test_print("--- EventL: ");
|
|
|
|
test_printn(sizeof(event_listener_t));
|
|
|
|
test_println(" bytes");
|
2016-04-01 05:13:54 -07:00
|
|
|
#endif]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
<step>
|
|
|
|
<description>
|
|
|
|
<value>The size of a mailbox is printed.</value>
|
|
|
|
</description>
|
|
|
|
<tags>
|
|
|
|
<value />
|
|
|
|
</tags>
|
|
|
|
<code>
|
|
|
|
<value><![CDATA[#if CH_CFG_USE_MAILBOXES || defined(__DOXYGEN__)
|
2020-07-12 06:15:38 -07:00
|
|
|
test_print("--- MailB.: ");
|
|
|
|
test_printn(sizeof(mailbox_t));
|
|
|
|
test_println(" bytes");
|
2016-04-01 05:13:54 -07:00
|
|
|
#endif]]></value>
|
2021-06-09 04:56:33 -07:00
|
|
|
</code>
|
|
|
|
</step>
|
|
|
|
</steps>
|
|
|
|
</case>
|
|
|
|
</cases>
|
|
|
|
</sequence>
|
|
|
|
</sequences>
|
|
|
|
</instance>
|