aboutsummaryrefslogtreecommitdiffstats
path: root/test/nil
diff options
context:
space:
mode:
authorGiovanni Di Sirio <gdisirio@gmail.com>2017-09-17 15:38:40 +0000
committerGiovanni Di Sirio <gdisirio@gmail.com>2017-09-17 15:38:40 +0000
commit3b3afb7d55d3822b4ae734d166022e327ee0c563 (patch)
tree9419c8346dbc6436ea569053c24c212c90deead6 /test/nil
parentfb355909fa1e96f24087c1380daef19cc0eb0532 (diff)
downloadChibiOS-3b3afb7d55d3822b4ae734d166022e327ee0c563.tar.gz
ChibiOS-3b3afb7d55d3822b4ae734d166022e327ee0c563.tar.bz2
ChibiOS-3b3afb7d55d3822b4ae734d166022e327ee0c563.zip
Improved RT and NIL test suite.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@10614 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'test/nil')
-rw-r--r--test/nil/configuration.xml150
-rw-r--r--test/nil/source/test/test_root.c12
-rw-r--r--test/nil/source/test/test_root.h1
-rw-r--r--test/nil/source/test/test_sequence_001.c162
-rw-r--r--test/nil/source/test/test_sequence_002.c226
-rw-r--r--test/nil/source/test/test_sequence_003.c234
-rw-r--r--test/nil/source/test/test_sequence_004.c387
-rw-r--r--test/nil/source/test/test_sequence_005.c342
-rw-r--r--test/nil/source/test/test_sequence_006.c297
-rw-r--r--test/nil/source/test/test_sequence_007.c273
-rw-r--r--test/nil/source/test/test_sequence_007.h27
-rw-r--r--test/nil/test.mk3
12 files changed, 1235 insertions, 879 deletions
diff --git a/test/nil/configuration.xml b/test/nil/configuration.xml
index 710e9a3be..d58582dd8 100644
--- a/test/nil/configuration.xml
+++ b/test/nil/configuration.xml
@@ -82,6 +82,156 @@ THD_FUNCTION(test_support, arg) {
<value>Internal Tests</value>
</type>
<brief>
+ <value>Information.</value>
+ </brief>
+ <description>
+ <value>This sequence reports configuration and version information about the NIL kernel.</value>
+ </description>
+ <condition>
+ <value />
+ </condition>
+ <shared_code>
+ <value><![CDATA[#include "ch.h"]]></value>
+ </shared_code>
+ <cases>
+ <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[test_println("*** Product: ChibiOS/NIL");
+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);
+test_println("");]]></value>
+ </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_NUM_THREADS: ");
+test_printn(CH_CFG_NUM_THREADS);
+test_println("");
+test_print("*** CH_CFG_ST_RESOLUTION: ");
+test_printn(CH_CFG_ST_RESOLUTION);
+test_println("");
+test_print("*** CH_CFG_ST_FREQUENCY: ");
+test_printn(CH_CFG_ST_FREQUENCY);
+test_println("");
+test_print("*** CH_CFG_ST_TIMEDELTA: ");
+test_printn(CH_CFG_ST_TIMEDELTA);
+test_println("");
+test_print("*** CH_CFG_USE_SEMAPHORES: ");
+test_printn(CH_CFG_USE_SEMAPHORES);
+test_println("");
+test_print("*** CH_CFG_USE_MUTEXES: ");
+test_printn(CH_CFG_USE_MUTEXES);
+test_println("");
+test_print("*** CH_CFG_USE_EVENTS: ");
+test_printn(CH_CFG_USE_EVENTS);
+test_println("");
+test_print("*** CH_CFG_USE_MAILBOXES: ");
+test_printn(CH_CFG_USE_MAILBOXES);
+test_println("");
+test_print("*** CH_CFG_USE_MEMCORE: ");
+test_printn(CH_CFG_USE_MEMCORE);
+test_println("");
+test_print("*** CH_CFG_USE_HEAP: ");
+test_printn(CH_CFG_USE_HEAP);
+test_println("");
+test_print("*** CH_CFG_USE_MEMPOOLS: ");
+test_printn(CH_CFG_USE_MEMPOOLS);
+test_println("");
+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_ENABLE_STACK_CHECK: ");
+test_printn(CH_DBG_ENABLE_STACK_CHECK);
+test_println("");]]></value>
+ </code>
+ </step>
+ </steps>
+ </case>
+ </cases>
+ </sequence>
+ <sequence>
+ <type index="0">
+ <value>Internal Tests</value>
+ </type>
+ <brief>
<value>Threads Functionality.</value>
</brief>
<description>
diff --git a/test/nil/source/test/test_root.c b/test/nil/source/test/test_root.c
index 177a46853..a41bb56bc 100644
--- a/test/nil/source/test/test_root.c
+++ b/test/nil/source/test/test_root.c
@@ -27,6 +27,7 @@
* - @subpage test_sequence_004
* - @subpage test_sequence_005
* - @subpage test_sequence_006
+ * - @subpage test_sequence_007
* .
*/
@@ -50,18 +51,19 @@
*/
const testcase_t * const *test_suite[] = {
test_sequence_001,
-#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
test_sequence_002,
-#endif
+#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
test_sequence_003,
-#if (CH_CFG_USE_MAILBOXES) || defined(__DOXYGEN__)
+#endif
test_sequence_004,
+#if (CH_CFG_USE_MAILBOXES) || defined(__DOXYGEN__)
+ test_sequence_005,
#endif
#if (CH_CFG_USE_MEMPOOLS) || defined(__DOXYGEN__)
- test_sequence_005,
+ test_sequence_006,
#endif
#if (CH_CFG_USE_HEAP) || defined(__DOXYGEN__)
- test_sequence_006,
+ test_sequence_007,
#endif
NULL
};
diff --git a/test/nil/source/test/test_root.h b/test/nil/source/test/test_root.h
index 694abf9c5..a5b5d6958 100644
--- a/test/nil/source/test/test_root.h
+++ b/test/nil/source/test/test_root.h
@@ -28,6 +28,7 @@
#include "test_sequence_004.h"
#include "test_sequence_005.h"
#include "test_sequence_006.h"
+#include "test_sequence_007.h"
#if !defined(__DOXYGEN__)
diff --git a/test/nil/source/test/test_sequence_001.c b/test/nil/source/test/test_sequence_001.c
index df99ee49b..683a26f3f 100644
--- a/test/nil/source/test/test_sequence_001.c
+++ b/test/nil/source/test/test_sequence_001.c
@@ -22,13 +22,13 @@
* @file test_sequence_001.c
* @brief Test Sequence 001 code.
*
- * @page test_sequence_001 [1] Threads Functionality
+ * @page test_sequence_001 [1] Information
*
* File: @ref test_sequence_001.c
*
* <h2>Description</h2>
- * This sequence tests the ChibiOS/NIL functionalities related to
- * threading.
+ * This sequence reports configuration and version information about
+ * the NIL kernel.
*
* <h2>Test Cases</h2>
* - @subpage test_001_001
@@ -47,123 +47,115 @@
****************************************************************************/
/**
- * @page test_001_001 [1.1] System Tick Counter functionality
+ * @page test_001_001 [1.1] Kernel Info
*
* <h2>Description</h2>
- * The functionality of the API @p chVTGetSystemTimeX() is tested.
+ * The version numbers are reported.
*
* <h2>Test Steps</h2>
- * - [1.1.1] A System Tick Counter increment is expected, the test
- * simply hangs if it does not happen.
+ * - [1.1.1] Prints the version string.
* .
*/
static void test_001_001_execute(void) {
- /* [1.1.1] A System Tick Counter increment is expected, the test
- simply hangs if it does not happen.*/
+ /* [1.1.1] Prints the version string.*/
test_set_step(1);
{
- systime_t time = chVTGetSystemTimeX();
- while (time == chVTGetSystemTimeX()) {
- }
+ test_println("*** Product: ChibiOS/NIL");
+ 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);
+ test_println("");
}
}
static const testcase_t test_001_001 = {
- "System Tick Counter functionality",
+ "Kernel Info",
NULL,
NULL,
test_001_001_execute
};
/**
- * @page test_001_002 [1.2] Thread Sleep functionality
+ * @page test_001_002 [1.2] Kernel Settings
*
* <h2>Description</h2>
- * The functionality of @p chThdSleep() and derivatives is tested.
+ * The static kernel settings are reported.
*
* <h2>Test Steps</h2>
- * - [1.2.1] The current system time is read then a sleep is performed
- * for 100 system ticks and on exit the system time is verified
- * again.
- * - [1.2.2] The current system time is read then a sleep is performed
- * for 100000 microseconds and on exit the system time is verified
- * again.
- * - [1.2.3] The current system time is read then a sleep is performed
- * for 100 milliseconds and on exit the system time is verified
- * again.
- * - [1.2.4] The current system time is read then a sleep is performed
- * for 1 second and on exit the system time is verified again.
- * - [1.2.5] Function chThdSleepUntil() is tested with a timeline of
- * "now" + 100 ticks.
+ * - [1.2.1] Prints the configuration options settings.
* .
*/
static void test_001_002_execute(void) {
- systime_t time;
- /* [1.2.1] The current system time is read then a sleep is performed
- for 100 system ticks and on exit the system time is verified
- again.*/
+ /* [1.2.1] Prints the configuration options settings.*/
test_set_step(1);
{
- time = chVTGetSystemTimeX();
- chThdSleep(100);
- test_assert_time_window(time + 100,
- time + 100 + 1,
- "out of time window");
- }
-
- /* [1.2.2] The current system time is read then a sleep is performed
- for 100000 microseconds and on exit the system time is verified
- again.*/
- test_set_step(2);
- {
- time = chVTGetSystemTimeX();
- chThdSleepMicroseconds(100000);
- test_assert_time_window(time + US2ST(100000),
- time + US2ST(100000) + 1,
- "out of time window");
- }
-
- /* [1.2.3] The current system time is read then a sleep is performed
- for 100 milliseconds and on exit the system time is verified
- again.*/
- test_set_step(3);
- {
- time = chVTGetSystemTimeX();
- chThdSleepMilliseconds(100);
- test_assert_time_window(time + MS2ST(100),
- time + MS2ST(100) + 1,
- "out of time window");
- }
-
- /* [1.2.4] The current system time is read then a sleep is performed
- for 1 second and on exit the system time is verified again.*/
- test_set_step(4);
- {
- time = chVTGetSystemTimeX();
- chThdSleepSeconds(1);
- test_assert_time_window(time + S2ST(1),
- time + S2ST(1) + 1,
- "out of time window");
- }
-
- /* [1.2.5] Function chThdSleepUntil() is tested with a timeline of
- "now" + 100 ticks.*/
- test_set_step(5);
- {
- time = chVTGetSystemTimeX();
- chThdSleepUntil(time + 100);
- test_assert_time_window(time + 100,
- time + 100 + 1,
- "out of time window");
+ test_print("*** CH_CFG_NUM_THREADS: ");
+ test_printn(CH_CFG_NUM_THREADS);
+ test_println("");
+ test_print("*** CH_CFG_ST_RESOLUTION: ");
+ test_printn(CH_CFG_ST_RESOLUTION);
+ test_println("");
+ test_print("*** CH_CFG_ST_FREQUENCY: ");
+ test_printn(CH_CFG_ST_FREQUENCY);
+ test_println("");
+ test_print("*** CH_CFG_ST_TIMEDELTA: ");
+ test_printn(CH_CFG_ST_TIMEDELTA);
+ test_println("");
+ test_print("*** CH_CFG_USE_SEMAPHORES: ");
+ test_printn(CH_CFG_USE_SEMAPHORES);
+ test_println("");
+ test_print("*** CH_CFG_USE_MUTEXES: ");
+ test_printn(CH_CFG_USE_MUTEXES);
+ test_println("");
+ test_print("*** CH_CFG_USE_EVENTS: ");
+ test_printn(CH_CFG_USE_EVENTS);
+ test_println("");
+ test_print("*** CH_CFG_USE_MAILBOXES: ");
+ test_printn(CH_CFG_USE_MAILBOXES);
+ test_println("");
+ test_print("*** CH_CFG_USE_MEMCORE: ");
+ test_printn(CH_CFG_USE_MEMCORE);
+ test_println("");
+ test_print("*** CH_CFG_USE_HEAP: ");
+ test_printn(CH_CFG_USE_HEAP);
+ test_println("");
+ test_print("*** CH_CFG_USE_MEMPOOLS: ");
+ test_printn(CH_CFG_USE_MEMPOOLS);
+ test_println("");
+ 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_ENABLE_STACK_CHECK: ");
+ test_printn(CH_DBG_ENABLE_STACK_CHECK);
+ test_println("");
}
}
static const testcase_t test_001_002 = {
- "Thread Sleep functionality",
+ "Kernel Settings",
NULL,
NULL,
test_001_002_execute
@@ -174,7 +166,7 @@ static const testcase_t test_001_002 = {
****************************************************************************/
/**
- * @brief Threads Functionality.
+ * @brief Information.
*/
const testcase_t * const test_sequence_001[] = {
&test_001_001,
diff --git a/test/nil/source/test/test_sequence_002.c b/test/nil/source/test/test_sequence_002.c
index 1e0f41d43..9e72d707d 100644
--- a/test/nil/source/test/test_sequence_002.c
+++ b/test/nil/source/test/test_sequence_002.c
@@ -22,224 +22,151 @@
* @file test_sequence_002.c
* @brief Test Sequence 002 code.
*
- * @page test_sequence_002 [2] Semaphores
+ * @page test_sequence_002 [2] Threads Functionality
*
* File: @ref test_sequence_002.c
*
* <h2>Description</h2>
* This sequence tests the ChibiOS/NIL functionalities related to
- * counter semaphores.
- *
- * <h2>Conditions</h2>
- * This sequence is only executed if the following preprocessor condition
- * evaluates to true:
- * - CH_CFG_USE_SEMAPHORES
- * .
+ * threading.
*
* <h2>Test Cases</h2>
* - @subpage test_002_001
* - @subpage test_002_002
- * - @subpage test_002_003
* .
*/
-#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
-
/****************************************************************************
* Shared code.
****************************************************************************/
#include "ch.h"
-static semaphore_t sem1;
-
/****************************************************************************
* Test cases.
****************************************************************************/
/**
- * @page test_002_001 [2.1] Semaphore primitives, no state change
+ * @page test_002_001 [2.1] System Tick Counter functionality
*
* <h2>Description</h2>
- * Wait, Signal and Reset primitives are tested. The testing thread
- * does not trigger a state change.
+ * The functionality of the API @p chVTGetSystemTimeX() is tested.
*
* <h2>Test Steps</h2>
- * - [2.1.1] The function chSemWait() is invoked, after return the
- * counter and the returned message are tested.
- * - [2.1.2] The function chSemSignal() is invoked, after return the
- * counter is tested.
- * - [2.1.3] The function chSemReset() is invoked, after return the
- * counter is tested.
+ * - [2.1.1] A System Tick Counter increment is expected, the test
+ * simply hangs if it does not happen.
* .
*/
-static void test_002_001_setup(void) {
- chSemObjectInit(&sem1, 1);
-}
-
-static void test_002_001_teardown(void) {
- chSemReset(&sem1, 0);
-}
-
static void test_002_001_execute(void) {
- /* [2.1.1] The function chSemWait() is invoked, after return the
- counter and the returned message are tested.*/
+ /* [2.1.1] A System Tick Counter increment is expected, the test
+ simply hangs if it does not happen.*/
test_set_step(1);
{
- msg_t msg;
-
- msg = chSemWait(&sem1);
- test_assert_lock(chSemGetCounterI(&sem1) == 0, "wrong counter value");
- test_assert(MSG_OK == msg, "wrong returned message");
- }
-
- /* [2.1.2] The function chSemSignal() is invoked, after return the
- counter is tested.*/
- test_set_step(2);
- {
- chSemSignal(&sem1);
- test_assert_lock(chSemGetCounterI(&sem1) == 1, "wrong counter value");
- }
-
- /* [2.1.3] The function chSemReset() is invoked, after return the
- counter is tested.*/
- test_set_step(3);
- {
- chSemReset(&sem1, 2);
- test_assert_lock(chSemGetCounterI(&sem1) == 2, "wrong counter value");
+ systime_t time = chVTGetSystemTimeX();
+ while (time == chVTGetSystemTimeX()) {
+ }
}
}
static const testcase_t test_002_001 = {
- "Semaphore primitives, no state change",
- test_002_001_setup,
- test_002_001_teardown,
+ "System Tick Counter functionality",
+ NULL,
+ NULL,
test_002_001_execute
};
/**
- * @page test_002_002 [2.2] Semaphore primitives, with state change
+ * @page test_002_002 [2.2] Thread Sleep functionality
*
* <h2>Description</h2>
- * Wait, Signal and Reset primitives are tested. The testing thread
- * triggers a state change.
+ * The functionality of @p chThdSleep() and derivatives is tested.
*
* <h2>Test Steps</h2>
- * - [2.2.1] The function chSemWait() is invoked, after return the
- * counter and the returned message are tested. The semaphore is
- * signaled by another thread.
- * - [2.2.2] The function chSemWait() is invoked, after return the
- * counter and the returned message are tested. The semaphore is
- * reset by another thread.
+ * - [2.2.1] The current system time is read then a sleep is performed
+ * for 100 system ticks and on exit the system time is verified
+ * again.
+ * - [2.2.2] The current system time is read then a sleep is performed
+ * for 100000 microseconds and on exit the system time is verified
+ * again.
+ * - [2.2.3] The current system time is read then a sleep is performed
+ * for 100 milliseconds and on exit the system time is verified
+ * again.
+ * - [2.2.4] The current system time is read then a sleep is performed
+ * for 1 second and on exit the system time is verified again.
+ * - [2.2.5] Function chThdSleepUntil() is tested with a timeline of
+ * "now" + 100 ticks.
* .
*/
-static void test_002_002_setup(void) {
- chSemObjectInit(&gsem1, 0);
-}
-
-static void test_002_002_teardown(void) {
- chSemReset(&gsem1, 0);
-}
-
static void test_002_002_execute(void) {
+ systime_t time;
- /* [2.2.1] The function chSemWait() is invoked, after return the
- counter and the returned message are tested. The semaphore is
- signaled by another thread.*/
+ /* [2.2.1] The current system time is read then a sleep is performed
+ for 100 system ticks and on exit the system time is verified
+ again.*/
test_set_step(1);
{
- msg_t msg;
-
- msg = chSemWait(&gsem1);
- test_assert_lock(chSemGetCounterI(&gsem1) == 0, "wrong counter value");
- test_assert(MSG_OK == msg, "wrong returned message");
+ time = chVTGetSystemTimeX();
+ chThdSleep(100);
+ test_assert_time_window(time + 100,
+ time + 100 + 1,
+ "out of time window");
}
- /* [2.2.2] The function chSemWait() is invoked, after return the
- counter and the returned message are tested. The semaphore is
- reset by another thread.*/
+ /* [2.2.2] The current system time is read then a sleep is performed
+ for 100000 microseconds and on exit the system time is verified
+ again.*/
test_set_step(2);
{
- msg_t msg;
-
- msg = chSemWait(&gsem2);
- test_assert_lock(chSemGetCounterI(&gsem2) == 0,"wrong counter value");
- test_assert(MSG_RESET == msg, "wrong returned message");
+ time = chVTGetSystemTimeX();
+ chThdSleepMicroseconds(100000);
+ test_assert_time_window(time + US2ST(100000),
+ time + US2ST(100000) + 1,
+ "out of time window");
}
-}
-
-static const testcase_t test_002_002 = {
- "Semaphore primitives, with state change",
- test_002_002_setup,
- test_002_002_teardown,
- test_002_002_execute
-};
-
-/**
- * @page test_002_003 [2.3] Semaphores timeout
- *
- * <h2>Description</h2>
- * Timeout on semaphores is tested.
- *
- * <h2>Test Steps</h2>
- * - [2.3.1] The function chSemWaitTimeout() is invoked a first time,
- * after return the system time, the counter and the returned message
- * are tested.
- * - [2.3.2] The function chSemWaitTimeout() is invoked again, after
- * return the system time, the counter and the returned message are
- * tested.
- * .
- */
-
-static void test_002_003_setup(void) {
- chSemObjectInit(&sem1, 0);
-}
-
-static void test_002_003_teardown(void) {
- chSemReset(&sem1, 0);
-}
-static void test_002_003_execute(void) {
- systime_t time;
- msg_t msg;
+ /* [2.2.3] The current system time is read then a sleep is performed
+ for 100 milliseconds and on exit the system time is verified
+ again.*/
+ test_set_step(3);
+ {
+ time = chVTGetSystemTimeX();
+ chThdSleepMilliseconds(100);
+ test_assert_time_window(time + MS2ST(100),
+ time + MS2ST(100) + 1,
+ "out of time window");
+ }
- /* [2.3.1] The function chSemWaitTimeout() is invoked a first time,
- after return the system time, the counter and the returned message
- are tested.*/
- test_set_step(1);
+ /* [2.2.4] The current system time is read then a sleep is performed
+ for 1 second and on exit the system time is verified again.*/
+ test_set_step(4);
{
time = chVTGetSystemTimeX();
- msg = chSemWaitTimeout(&sem1, MS2ST(1000));
- test_assert_time_window(time + MS2ST(1000),
- time + MS2ST(1000) + 1,
+ chThdSleepSeconds(1);
+ test_assert_time_window(time + S2ST(1),
+ time + S2ST(1) + 1,
"out of time window");
- test_assert_lock(chSemGetCounterI(&sem1) == 0, "wrong counter value");
- test_assert(MSG_TIMEOUT == msg, "wrong timeout message");
}
- /* [2.3.2] The function chSemWaitTimeout() is invoked again, after
- return the system time, the counter and the returned message are
- tested.*/
- test_set_step(2);
+ /* [2.2.5] Function chThdSleepUntil() is tested with a timeline of
+ "now" + 100 ticks.*/
+ test_set_step(5);
{
time = chVTGetSystemTimeX();
- msg = chSemWaitTimeout(&sem1, MS2ST(1000));
- test_assert_time_window(time + MS2ST(1000),
- time + MS2ST(1000) + 1,
+ chThdSleepUntil(time + 100);
+ test_assert_time_window(time + 100,
+ time + 100 + 1,
"out of time window");
- test_assert_lock(chSemGetCounterI(&sem1) == 0, "wrong counter value");
- test_assert(MSG_TIMEOUT == msg, "wrong timeout message");
}
}
-static const testcase_t test_002_003 = {
- "Semaphores timeout",
- test_002_003_setup,
- test_002_003_teardown,
- test_002_003_execute
+static const testcase_t test_002_002 = {
+ "Thread Sleep functionality",
+ NULL,
+ NULL,
+ test_002_002_execute
};
/****************************************************************************
@@ -247,13 +174,10 @@ static const testcase_t test_002_003 = {
****************************************************************************/
/**
- * @brief Semaphores.
+ * @brief Threads Functionality.
*/
const testcase_t * const test_sequence_002[] = {
&test_002_001,
&test_002_002,
- &test_002_003,
NULL
};
-
-#endif /* CH_CFG_USE_SEMAPHORES */
diff --git a/test/nil/source/test/test_sequence_003.c b/test/nil/source/test/test_sequence_003.c
index bf5c7941f..22e233620 100644
--- a/test/nil/source/test/test_sequence_003.c
+++ b/test/nil/source/test/test_sequence_003.c
@@ -22,178 +22,238 @@
* @file test_sequence_003.c
* @brief Test Sequence 003 code.
*
- * @page test_sequence_003 [3] Suspend/Resume and Event Flags
+ * @page test_sequence_003 [3] Semaphores
*
* File: @ref test_sequence_003.c
*
* <h2>Description</h2>
* This sequence tests the ChibiOS/NIL functionalities related to
- * threads suspend/resume and event flags.
+ * counter semaphores.
+ *
+ * <h2>Conditions</h2>
+ * This sequence is only executed if the following preprocessor condition
+ * evaluates to true:
+ * - CH_CFG_USE_SEMAPHORES
+ * .
*
* <h2>Test Cases</h2>
* - @subpage test_003_001
* - @subpage test_003_002
+ * - @subpage test_003_003
* .
*/
+#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
+
/****************************************************************************
* Shared code.
****************************************************************************/
-static thread_reference_t tr1;
+#include "ch.h"
+
+static semaphore_t sem1;
/****************************************************************************
* Test cases.
****************************************************************************/
/**
- * @page test_003_001 [3.1] Suspend and Resume functionality
+ * @page test_003_001 [3.1] Semaphore primitives, no state change
*
* <h2>Description</h2>
- * The functionality of chThdSuspendTimeoutS() and chThdResumeI() is
- * tested.
+ * Wait, Signal and Reset primitives are tested. The testing thread
+ * does not trigger a state change.
*
* <h2>Test Steps</h2>
- * - [3.1.1] 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.
- * - [3.1.2] 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.
+ * - [3.1.1] The function chSemWait() is invoked, after return the
+ * counter and the returned message are tested.
+ * - [3.1.2] The function chSemSignal() is invoked, after return the
+ * counter is tested.
+ * - [3.1.3] The function chSemReset() is invoked, after return the
+ * counter is tested.
* .
*/
static void test_003_001_setup(void) {
- tr1 = NULL;
+ chSemObjectInit(&sem1, 1);
+}
+
+static void test_003_001_teardown(void) {
+ chSemReset(&sem1, 0);
}
static void test_003_001_execute(void) {
- systime_t time;
- msg_t msg;
- /* [3.1.1] 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.*/
+ /* [3.1.1] The function chSemWait() is invoked, after return the
+ counter and the returned message are tested.*/
test_set_step(1);
{
- chSysLock();
- msg = chThdSuspendTimeoutS(&gtr1, TIME_INFINITE);
- chSysUnlock();
- test_assert(NULL == gtr1, "not NULL");
- test_assert(MSG_OK == msg,"wrong returned message");
+ msg_t msg;
+
+ msg = chSemWait(&sem1);
+ test_assert_lock(chSemGetCounterI(&sem1) == 0, "wrong counter value");
+ test_assert(MSG_OK == msg, "wrong returned message");
}
- /* [3.1.2] 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.*/
+ /* [3.1.2] The function chSemSignal() is invoked, after return the
+ counter is tested.*/
test_set_step(2);
{
- chSysLock();
- time = chVTGetSystemTimeX();
- msg = chThdSuspendTimeoutS(&tr1, MS2ST(1000));
- chSysUnlock();
- test_assert_time_window(time + MS2ST(1000),
- time + MS2ST(1000) + 1,
- "out of time window");
- test_assert(NULL == tr1, "not NULL");
- test_assert(MSG_TIMEOUT == msg, "wrong returned message");
+ chSemSignal(&sem1);
+ test_assert_lock(chSemGetCounterI(&sem1) == 1, "wrong counter value");
+ }
+
+ /* [3.1.3] The function chSemReset() is invoked, after return the
+ counter is tested.*/
+ test_set_step(3);
+ {
+ chSemReset(&sem1, 2);
+ test_assert_lock(chSemGetCounterI(&sem1) == 2, "wrong counter value");
}
}
static const testcase_t test_003_001 = {
- "Suspend and Resume functionality",
+ "Semaphore primitives, no state change",
test_003_001_setup,
- NULL,
+ test_003_001_teardown,
test_003_001_execute
};
-#if (CH_CFG_USE_EVENTS) || defined(__DOXYGEN__)
/**
- * @page test_003_002 [3.2] Events Flags functionality
+ * @page test_003_002 [3.2] Semaphore primitives, with state change
*
* <h2>Description</h2>
- * Event flags functionality is tested.
- *
- * <h2>Conditions</h2>
- * This test is only executed if the following preprocessor condition
- * evaluates to true:
- * - CH_CFG_USE_EVENTS
- * .
+ * Wait, Signal and Reset primitives are tested. The testing thread
+ * triggers a state change.
*
* <h2>Test Steps</h2>
- * - [3.2.1] A set of event flags are set on the current thread then
- * the function chEvtWaitAnyTimeout() is invoked, the function is
- * supposed to return immediately because the event flags are already
- * pending, after return the events mask is tested.
- * - [3.2.2] The pending event flags mask is cleared then the function
- * chEvtWaitAnyTimeout() is invoked, after return the events mask is
- * tested. The thread is signaled by another thread.
- * - [3.2.3] The function chEvtWaitAnyTimeout() is invoked, no event
- * can wakeup the thread, the function must return because timeout.
+ * - [3.2.1] The function chSemWait() is invoked, after return the
+ * counter and the returned message are tested. The semaphore is
+ * signaled by another thread.
+ * - [3.2.2] The function chSemWait() is invoked, after return the
+ * counter and the returned message are tested. The semaphore is
+ * reset by another thread.
* .
*/
+static void test_003_002_setup(void) {
+ chSemObjectInit(&gsem1, 0);
+}
+
+static void test_003_002_teardown(void) {
+ chSemReset(&gsem1, 0);
+}
+
static void test_003_002_execute(void) {
- systime_t time;
- eventmask_t events;
- /* [3.2.1] A set of event flags are set on the current thread then
- the function chEvtWaitAnyTimeout() is invoked, the function is
- supposed to return immediately because the event flags are already
- pending, after return the events mask is tested.*/
+ /* [3.2.1] The function chSemWait() is invoked, after return the
+ counter and the returned message are tested. The semaphore is
+ signaled by another thread.*/
test_set_step(1);
{
- time = chVTGetSystemTimeX();
- chEvtSignal(chThdGetSelfX(), 0x55);
- events = chEvtWaitAnyTimeout(ALL_EVENTS, MS2ST(1000));
- test_assert((eventmask_t)0 != events, "timed out");
- test_assert((eventmask_t)0x55 == events, "wrong events mask");
+ msg_t msg;
+
+ msg = chSemWait(&gsem1);
+ test_assert_lock(chSemGetCounterI(&gsem1) == 0, "wrong counter value");
+ test_assert(MSG_OK == msg, "wrong returned message");
}
- /* [3.2.2] The pending event flags mask is cleared then the function
- chEvtWaitAnyTimeout() is invoked, after return the events mask is
- tested. The thread is signaled by another thread.*/
+ /* [3.2.2] The function chSemWait() is invoked, after return the
+ counter and the returned message are tested. The semaphore is
+ reset by another thread.*/
test_set_step(2);
{
+ msg_t msg;
+
+ msg = chSemWait(&gsem2);
+ test_assert_lock(chSemGetCounterI(&gsem2) == 0,"wrong counter value");
+ test_assert(MSG_RESET == msg, "wrong returned message");
+ }
+}
+
+static const testcase_t test_003_002 = {
+ "Semaphore primitives, with state change",
+ test_003_002_setup,
+ test_003_002_teardown,
+ test_003_002_execute
+};
+
+/**
+ * @page test_003_003 [3.3] Semaphores timeout
+ *
+ * <h2>Description</h2>
+ * Timeout on semaphores is tested.
+ *
+ * <h2>Test Steps</h2>
+ * - [3.3.1] The function chSemWaitTimeout() is invoked a first time,
+ * after return the system time, the counter and the returned message
+ * are tested.
+ * - [3.3.2] The function chSemWaitTimeout() is invoked again, after
+ * return the system time, the counter and the returned message are
+ * tested.
+ * .
+ */
+
+static void test_003_003_setup(void) {
+ chSemObjectInit(&sem1, 0);
+}
+
+static void test_003_003_teardown(void) {
+ chSemReset(&sem1, 0);
+}
+
+static void test_003_003_execute(void) {
+ systime_t time;
+ msg_t msg;
+
+ /* [3.3.1] The function chSemWaitTimeout() is invoked a first time,
+ after return the system time, the counter and the returned message
+ are tested.*/
+ test_set_step(1);
+ {
time = chVTGetSystemTimeX();
- chThdGetSelfX()->epmask = 0;
- events = chEvtWaitAnyTimeout(ALL_EVENTS, MS2ST(1000));
- test_assert((eventmask_t)0 != events, "timed out");
- test_assert((eventmask_t)0x55 == events, "wrong events mask");
+ msg = chSemWaitTimeout(&sem1, MS2ST(1000));
+ test_assert_time_window(time + MS2ST(1000),
+ time + MS2ST(1000) + 1,
+ "out of time window");
+ test_assert_lock(chSemGetCounterI(&sem1) == 0, "wrong counter value");
+ test_assert(MSG_TIMEOUT == msg, "wrong timeout message");
}
- /* [3.2.3] The function chEvtWaitAnyTimeout() is invoked, no event
- can wakeup the thread, the function must return because timeout.*/
- test_set_step(3);
+ /* [3.3.2] The function chSemWaitTimeout() is invoked again, after
+ return the system time, the counter and the returned message are
+ tested.*/
+ test_set_step(2);
{
time = chVTGetSystemTimeX();
- events = chEvtWaitAnyTimeout(0, MS2ST(1000));
+ msg = chSemWaitTimeout(&sem1, MS2ST(1000));
test_assert_time_window(time + MS2ST(1000),
time + MS2ST(1000) + 1,
"out of time window");
- test_assert((eventmask_t)0 == events, "wrong events mask");
+ test_assert_lock(chSemGetCounterI(&sem1) == 0, "wrong counter value");
+ test_assert(MSG_TIMEOUT == msg, "wrong timeout message");
}
}
-static const testcase_t test_003_002 = {
- "Events Flags functionality",
- NULL,
- NULL,
- test_003_002_execute
+static const testcase_t test_003_003 = {
+ "Semaphores timeout",
+ test_003_003_setup,
+ test_003_003_teardown,
+ test_003_003_execute
};
-#endif /* CH_CFG_USE_EVENTS */
/****************************************************************************
* Exported data.
****************************************************************************/
/**
- * @brief Suspend/Resume and Event Flags.
+ * @brief Semaphores.
*/
const testcase_t * const test_sequence_003[] = {
&test_003_001,
-#if (CH_CFG_USE_EVENTS) || defined(__DOXYGEN__)
&test_003_002,
-#endif
+ &test_003_003,
NULL
};
+
+#endif /* CH_CFG_USE_SEMAPHORES */
diff --git a/test/nil/source/test/test_sequence_004.c b/test/nil/source/test/test_sequence_004.c
index c3f3463d3..52e3e88d0 100644
--- a/test/nil/source/test/test_sequence_004.c
+++ b/test/nil/source/test/test_sequence_004.c
@@ -22,387 +22,178 @@
* @file test_sequence_004.c
* @brief Test Sequence 004 code.
*
- * @page test_sequence_004 [4] Mailboxes
+ * @page test_sequence_004 [4] Suspend/Resume and Event Flags
*
* File: @ref test_sequence_004.c
*
* <h2>Description</h2>
* This sequence tests the ChibiOS/NIL functionalities related to
- * mailboxes.
- *
- * <h2>Conditions</h2>
- * This sequence is only executed if the following preprocessor condition
- * evaluates to true:
- * - CH_CFG_USE_MAILBOXES
- * .
+ * threads suspend/resume and event flags.
*
* <h2>Test Cases</h2>
* - @subpage test_004_001
* - @subpage test_004_002
- * - @subpage test_004_003
* .
*/
-#if (CH_CFG_USE_MAILBOXES) || defined(__DOXYGEN__)
-
/****************************************************************************
* Shared code.
****************************************************************************/
-#define ALLOWED_DELAY MS2ST(5)
-#define MB_SIZE 4
-
-static msg_t mb_buffer[MB_SIZE];
-static MAILBOX_DECL(mb1, mb_buffer, MB_SIZE);
+static thread_reference_t tr1;
/****************************************************************************
* Test cases.
****************************************************************************/
/**
- * @page test_004_001 [4.1] Mailbox normal API, non-blocking tests
+ * @page test_004_001 [4.1] Suspend and Resume functionality
*
* <h2>Description</h2>
- * The mailbox normal API is tested without triggering blocking
- * conditions.
+ * The functionality of chThdSuspendTimeoutS() and chThdResumeI() is
+ * tested.
*
* <h2>Test Steps</h2>
- * - [4.1.1] Testing the mailbox size.
- * - [4.1.2] Resetting the mailbox, conditions are checked, no errors
- * expected.
- * - [4.1.3] Testing the behavior of API when the mailbox is in reset
- * state then return in active state.
- * - [4.1.4] Filling the mailbox using chMBPost() and chMBPostAhead()
- * once, no errors expected.
- * - [4.1.5] Testing intermediate conditions. Data pointers must be
- * aligned, semaphore counters are checked.
- * - [4.1.6] Emptying the mailbox using chMBFetch(), no errors
- * expected.
- * - [4.1.7] Posting and then fetching one more message, no errors
- * expected.
- * - [4.1.8] Testing final conditions. Data pointers must be aligned to
- * buffer start, semaphore counters are checked.
+ * - [4.1.1] 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.
+ * - [4.1.2] 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.
* .
*/
static void test_004_001_setup(void) {
- chMBObjectInit(&mb1, mb_buffer, MB_SIZE);
-}
-
-static void test_004_001_teardown(void) {
- chMBReset(&mb1);
+ tr1 = NULL;
}
static void test_004_001_execute(void) {
- msg_t msg1, msg2;
- unsigned i;
+ systime_t time;
+ msg_t msg;
- /* [4.1.1] Testing the mailbox size.*/
+ /* [4.1.1] 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.*/
test_set_step(1);
{
- test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "wrong size");
+ chSysLock();
+ msg = chThdSuspendTimeoutS(&gtr1, TIME_INFINITE);
+ chSysUnlock();
+ test_assert(NULL == gtr1, "not NULL");
+ test_assert(MSG_OK == msg,"wrong returned message");
}
- /* [4.1.2] Resetting the mailbox, conditions are checked, no errors
- expected.*/
+ /* [4.1.2] 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.*/
test_set_step(2);
{
- chMBReset(&mb1);
- test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "not empty");
- test_assert_lock(chMBGetUsedCountI(&mb1) == 0, "still full");
- test_assert_lock(mb1.buffer == mb1.wrptr, "write pointer not aligned to base");
- test_assert_lock(mb1.buffer == mb1.rdptr, "read pointer not aligned to base");
- }
-
- /* [4.1.3] Testing the behavior of API when the mailbox is in reset
- state then return in active state.*/
- test_set_step(3);
- {
- msg1 = chMBPost(&mb1, (msg_t)0, TIME_INFINITE);
- test_assert(msg1 == MSG_RESET, "not in reset state");
- msg1 = chMBPostAhead(&mb1, (msg_t)0, TIME_INFINITE);
- test_assert(msg1 == MSG_RESET, "not in reset state");
- msg1 = chMBFetch(&mb1, &msg2, TIME_INFINITE);
- test_assert(msg1 == MSG_RESET, "not in reset state");
- chMBResumeX(&mb1);
- }
-
- /* [4.1.4] Filling the mailbox using chMBPost() and chMBPostAhead()
- once, no errors expected.*/
- test_set_step(4);
- {
- for (i = 0; i < MB_SIZE - 1; i++) {
- msg1 = chMBPost(&mb1, 'B' + i, TIME_INFINITE);
- test_assert(msg1 == MSG_OK, "wrong wake-up message");
- }
- msg1 = chMBPostAhead(&mb1, 'A', TIME_INFINITE);
- test_assert(msg1 == MSG_OK, "wrong wake-up message");
- }
-
- /* [4.1.5] Testing intermediate conditions. Data pointers must be
- aligned, semaphore counters are checked.*/
- test_set_step(5);
- {
- test_assert_lock(chMBGetFreeCountI(&mb1) == 0, "still empty");
- test_assert_lock(chMBGetUsedCountI(&mb1) == MB_SIZE, "not full");
- test_assert_lock(mb1.rdptr == mb1.wrptr, "pointers not aligned");
- }
-
- /* [4.1.6] Emptying the mailbox using chMBFetch(), no errors
- expected.*/
- test_set_step(6);
- {
- for (i = 0; i < MB_SIZE; i++) {
- msg1 = chMBFetch(&mb1, &msg2, TIME_INFINITE);
- test_assert(msg1 == MSG_OK, "wrong wake-up message");
- test_emit_token(msg2);
- }
- test_assert_sequence("ABCD", "wrong get sequence");
- }
-
- /* [4.1.7] Posting and then fetching one more message, no errors
- expected.*/
- test_set_step(7);
- {
- msg1 = chMBPost(&mb1, 'B' + i, TIME_INFINITE);
- test_assert(msg1 == MSG_OK, "wrong wake-up message");
- msg1 = chMBFetch(&mb1, &msg2, TIME_INFINITE);
- test_assert(msg1 == MSG_OK, "wrong wake-up message");
- }
-
- /* [4.1.8] Testing final conditions. Data pointers must be aligned to
- buffer start, semaphore counters are checked.*/
- test_set_step(8);
- {
- test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "not empty");
- test_assert_lock(chMBGetUsedCountI(&mb1) == 0, "still full");
- test_assert(mb1.buffer == mb1.wrptr, "write pointer not aligned to base");
- test_assert(mb1.buffer == mb1.rdptr, "read pointer not aligned to base");
+ chSysLock();
+ time = chVTGetSystemTimeX();
+ msg = chThdSuspendTimeoutS(&tr1, MS2ST(1000));
+ chSysUnlock();
+ test_assert_time_window(time + MS2ST(1000),
+ time + MS2ST(1000) + 1,
+ "out of time window");
+ test_assert(NULL == tr1, "not NULL");
+ test_assert(MSG_TIMEOUT == msg, "wrong returned message");
}
}
static const testcase_t test_004_001 = {
- "Mailbox normal API, non-blocking tests",
+ "Suspend and Resume functionality",
test_004_001_setup,
- test_004_001_teardown,
+ NULL,
test_004_001_execute
};
+#if (CH_CFG_USE_EVENTS) || defined(__DOXYGEN__)
/**
- * @page test_004_002 [4.2] Mailbox I-Class API, non-blocking tests
+ * @page test_004_002 [4.2] Events Flags functionality
*
* <h2>Description</h2>
- * The mailbox I-Class API is tested without triggering blocking
- * conditions.
+ * Event flags functionality is tested.
+ *
+ * <h2>Conditions</h2>
+ * This test is only executed if the following preprocessor condition
+ * evaluates to true:
+ * - CH_CFG_USE_EVENTS
+ * .
*
* <h2>Test Steps</h2>
- * - [4.2.1] Testing the mailbox size.
- * - [4.2.2] Resetting the mailbox, conditions are checked, no errors
- * expected.
- * - [4.2.3] Filling the mailbox using chMBPostI() and chMBPostAheadI()
- * once, no errors expected.
- * - [4.2.4] Testing intermediate conditions. Data pointers must be
- * aligned, semaphore counters are checked.
- * - [4.2.5] Emptying the mailbox using chMBFetchI(), no errors
- * expected.
- * - [4.2.6] Posting and then fetching one more message, no errors
- * expected.
- * - [4.2.7] Testing final conditions. Data pointers must be aligned to
- * buffer start, semaphore counters are checked.
+ * - [4.2.1] A set of event flags are set on the current thread then
+ * the function chEvtWaitAnyTimeout() is invoked, the function is
+ * supposed to return immediately because the event flags are already
+ * pending, after return the events mask is tested.
+ * - [4.2.2] The pending event flags mask is cleared then the function
+ * chEvtWaitAnyTimeout() is invoked, after return the events mask is
+ * tested. The thread is signaled by another thread.
+ * - [4.2.3] The function chEvtWaitAnyTimeout() is invoked, no event
+ * can wakeup the thread, the function must return because timeout.
* .
*/
-static void test_004_002_setup(void) {
- chMBObjectInit(&mb1, mb_buffer, MB_SIZE);
-}
-
-static void test_004_002_teardown(void) {
- chMBReset(&mb1);
-}
-
static void test_004_002_execute(void) {
- msg_t msg1, msg2;
- unsigned i;
+ systime_t time;
+ eventmask_t events;
- /* [4.2.1] Testing the mailbox size.*/
+ /* [4.2.1] A set of event flags are set on the current thread then
+ the function chEvtWaitAnyTimeout() is invoked, the function is
+ supposed to return immediately because the event flags are already
+ pending, after return the events mask is tested.*/
test_set_step(1);
{
- test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "wrong size");
+ time = chVTGetSystemTimeX();
+ chEvtSignal(chThdGetSelfX(), 0x55);
+ events = chEvtWaitAnyTimeout(ALL_EVENTS, MS2ST(1000));
+ test_assert((eventmask_t)0 != events, "timed out");
+ test_assert((eventmask_t)0x55 == events, "wrong events mask");
}
- /* [4.2.2] Resetting the mailbox, conditions are checked, no errors
- expected.*/
+ /* [4.2.2] The pending event flags mask is cleared then the function
+ chEvtWaitAnyTimeout() is invoked, after return the events mask is
+ tested. The thread is signaled by another thread.*/
test_set_step(2);
{
- chSysLock();
- chMBResetI(&mb1);
- chSysUnlock();
- test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "not empty");
- test_assert_lock(chMBGetUsedCountI(&mb1) == 0, "still full");
- test_assert_lock(mb1.buffer == mb1.wrptr, "write pointer not aligned to base");
- test_assert_lock(mb1.buffer == mb1.rdptr, "read pointer not aligned to base");
- chMBResumeX(&mb1);
+ time = chVTGetSystemTimeX();
+ chThdGetSelfX()->epmask = 0;
+ events = chEvtWaitAnyTimeout(ALL_EVENTS, MS2ST(1000));
+ test_assert((eventmask_t)0 != events, "timed out");
+ test_assert((eventmask_t)0x55 == events, "wrong events mask");
}
- /* [4.2.3] Filling the mailbox using chMBPostI() and chMBPostAheadI()
- once, no errors expected.*/
+ /* [4.2.3] The function chEvtWaitAnyTimeout() is invoked, no event
+ can wakeup the thread, the function must return because timeout.*/
test_set_step(3);
{
- for (i = 0; i < MB_SIZE - 1; i++) {
- chSysLock();
- msg1 = chMBPostI(&mb1, 'B' + i);
- chSysUnlock();
- test_assert(msg1 == MSG_OK, "wrong wake-up message");
- }
- chSysLock();
- msg1 = chMBPostAheadI(&mb1, 'A');
- chSysUnlock();
- test_assert(msg1 == MSG_OK, "wrong wake-up message");
- }
-
- /* [4.2.4] Testing intermediate conditions. Data pointers must be
- aligned, semaphore counters are checked.*/
- test_set_step(4);
- {
- test_assert_lock(chMBGetFreeCountI(&mb1) == 0, "still empty");
- test_assert_lock(chMBGetUsedCountI(&mb1) == MB_SIZE, "not full");
- test_assert_lock(mb1.rdptr == mb1.wrptr, "pointers not aligned");
- }
-
- /* [4.2.5] Emptying the mailbox using chMBFetchI(), no errors
- expected.*/
- test_set_step(5);
- {
- for (i = 0; i < MB_SIZE; i++) {
- chSysLock();
- msg1 = chMBFetchI(&mb1, &msg2);
- chSysUnlock();
- test_assert(msg1 == MSG_OK, "wrong wake-up message");
- test_emit_token(msg2);
- }
- test_assert_sequence("ABCD", "wrong get sequence");
- }
-
- /* [4.2.6] Posting and then fetching one more message, no errors
- expected.*/
- test_set_step(6);
- {
- msg1 = chMBPost(&mb1, 'B' + i, TIME_INFINITE);
- test_assert(msg1 == MSG_OK, "wrong wake-up message");
- msg1 = chMBFetch(&mb1, &msg2, TIME_INFINITE);
- test_assert(msg1 == MSG_OK, "wrong wake-up message");
- }
-
- /* [4.2.7] Testing final conditions. Data pointers must be aligned to
- buffer start, semaphore counters are checked.*/
- test_set_step(7);
- {
- test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "not empty");
- test_assert_lock(chMBGetUsedCountI(&mb1) == 0, "still full");
- test_assert(mb1.buffer == mb1.wrptr, "write pointer not aligned to base");
- test_assert(mb1.buffer == mb1.rdptr, "read pointer not aligned to base");
+ time = chVTGetSystemTimeX();
+ events = chEvtWaitAnyTimeout(0, MS2ST(1000));
+ test_assert_time_window(time + MS2ST(1000),
+ time + MS2ST(1000) + 1,
+ "out of time window");
+ test_assert((eventmask_t)0 == events, "wrong events mask");
}
}
static const testcase_t test_004_002 = {
- "Mailbox I-Class API, non-blocking tests",
- test_004_002_setup,
- test_004_002_teardown,
+ "Events Flags functionality",
+ NULL,
+ NULL,
test_004_002_execute
};
-
-/**
- * @page test_004_003 [4.3] Mailbox timeouts
- *
- * <h2>Description</h2>
- * The mailbox API is tested for timeouts.
- *
- * <h2>Test Steps</h2>
- * - [4.3.1] Filling the mailbox.
- * - [4.3.2] Testing chMBPost(), chMBPostI(), chMBPostAhead() and
- * chMBPostAheadI() timeout.
- * - [4.3.3] Resetting the mailbox.
- * - [4.3.4] Testing chMBFetch() and chMBFetchI() timeout.
- * .
- */
-
-static void test_004_003_setup(void) {
- chMBObjectInit(&mb1, mb_buffer, MB_SIZE);
-}
-
-static void test_004_003_teardown(void) {
- chMBReset(&mb1);
-}
-
-static void test_004_003_execute(void) {
- msg_t msg1, msg2;
- unsigned i;
-
- /* [4.3.1] Filling the mailbox.*/
- test_set_step(1);
- {
- for (i = 0; i < MB_SIZE; i++) {
- msg1 = chMBPost(&mb1, 'B' + i, TIME_INFINITE);
- test_assert(msg1 == MSG_OK, "wrong wake-up message");
- }
- }
-
- /* [4.3.2] Testing chMBPost(), chMBPostI(), chMBPostAhead() and
- chMBPostAheadI() timeout.*/
- test_set_step(2);
- {
- msg1 = chMBPost(&mb1, 'X', 1);
- test_assert(msg1 == MSG_TIMEOUT, "wrong wake-up message");
- chSysLock();
- msg1 = chMBPostI(&mb1, 'X');
- chSysUnlock();
- test_assert(msg1 == MSG_TIMEOUT, "wrong wake-up message");
- msg1 = chMBPostAhead(&mb1, 'X', 1);
- test_assert(msg1 == MSG_TIMEOUT, "wrong wake-up message");
- chSysLock();
- msg1 = chMBPostAheadI(&mb1, 'X');
- chSysUnlock();
- test_assert(msg1 == MSG_TIMEOUT, "wrong wake-up message");
- }
-
- /* [4.3.3] Resetting the mailbox.*/
- test_set_step(3);
- {
- chMBReset(&mb1);;
- chMBResumeX(&mb1);
- }
-
- /* [4.3.4] Testing chMBFetch() and chMBFetchI() timeout.*/
- test_set_step(4);
- {
- msg1 = chMBFetch(&mb1, &msg2, 1);
- test_assert(msg1 == MSG_TIMEOUT, "wrong wake-up message");
- chSysLock();
- msg1 = chMBFetchI(&mb1, &msg2);
- chSysUnlock();
- test_assert(msg1 == MSG_TIMEOUT, "wrong wake-up message");
- }
-}
-
-static const testcase_t test_004_003 = {
- "Mailbox timeouts",
- test_004_003_setup,
- test_004_003_teardown,
- test_004_003_execute
-};
+#endif /* CH_CFG_USE_EVENTS */
/****************************************************************************
* Exported data.
****************************************************************************/
/**
- * @brief Mailboxes.
+ * @brief Suspend/Resume and Event Flags.
*/
const testcase_t * const test_sequence_004[] = {
&test_004_001,
+#if (CH_CFG_USE_EVENTS) || defined(__DOXYGEN__)
&test_004_002,
- &test_004_003,
+#endif
NULL
};
-
-#endif /* CH_CFG_USE_MAILBOXES */
diff --git a/test/nil/source/test/test_sequence_005.c b/test/nil/source/test/test_sequence_005.c
index 3c0ef8668..70954f1d1 100644
--- a/test/nil/source/test/test_sequence_005.c
+++ b/test/nil/source/test/test_sequence_005.c
@@ -22,18 +22,18 @@
* @file test_sequence_005.c
* @brief Test Sequence 005 code.
*
- * @page test_sequence_005 [5] Memory Pools
+ * @page test_sequence_005 [5] Mailboxes
*
* File: @ref test_sequence_005.c
*
* <h2>Description</h2>
* This sequence tests the ChibiOS/NIL functionalities related to
- * memory pools.
+ * mailboxes.
*
* <h2>Conditions</h2>
* This sequence is only executed if the following preprocessor condition
* evaluates to true:
- * - CH_CFG_USE_MEMPOOLS
+ * - CH_CFG_USE_MAILBOXES
* .
*
* <h2>Test Cases</h2>
@@ -43,254 +43,366 @@
* .
*/
-#if (CH_CFG_USE_MEMPOOLS) || defined(__DOXYGEN__)
+#if (CH_CFG_USE_MAILBOXES) || defined(__DOXYGEN__)
/****************************************************************************
* Shared code.
****************************************************************************/
-#define MEMORY_POOL_SIZE 4
+#define ALLOWED_DELAY MS2ST(5)
+#define MB_SIZE 4
-static uint32_t objects[MEMORY_POOL_SIZE];
-static MEMORYPOOL_DECL(mp1, sizeof (uint32_t), NULL);
-
-#if CH_CFG_USE_SEMAPHORES
-static GUARDEDMEMORYPOOL_DECL(gmp1, sizeof (uint32_t));
-#endif
-
-static void *null_provider(size_t size, unsigned align) {
-
- (void)size;
- (void)align;
-
- return NULL;
-}
+static msg_t mb_buffer[MB_SIZE];
+static MAILBOX_DECL(mb1, mb_buffer, MB_SIZE);
/****************************************************************************
* Test cases.
****************************************************************************/
/**
- * @page test_005_001 [5.1] Loading and emptying a memory pool
+ * @page test_005_001 [5.1] Mailbox normal API, non-blocking tests
*
* <h2>Description</h2>
- * The memory pool functionality is tested by loading and emptying it,
- * all conditions are tested.
+ * The mailbox normal API is tested without triggering blocking
+ * conditions.
*
* <h2>Test Steps</h2>
- * - [5.1.1] Adding the objects to the pool using chPoolLoadArray().
- * - [5.1.2] Emptying the pool using chPoolAlloc().
- * - [5.1.3] Now must be empty.
- * - [5.1.4] Adding the objects to the pool using chPoolFree().
- * - [5.1.5] Emptying the pool using chPoolAlloc() again.
- * - [5.1.6] Now must be empty again.
- * - [5.1.7] Covering the case where a provider is unable to return
- * more memory.
+ * - [5.1.1] Testing the mailbox size.
+ * - [5.1.2] Resetting the mailbox, conditions are checked, no errors
+ * expected.
+ * - [5.1.3] Testing the behavior of API when the mailbox is in reset
+ * state then return in active state.
+ * - [5.1.4] Filling the mailbox using chMBPost() and chMBPostAhead()
+ * once, no errors expected.
+ * - [5.1.5] Testing intermediate conditions. Data pointers must be
+ * aligned, semaphore counters are checked.
+ * - [5.1.6] Emptying the mailbox using chMBFetch(), no errors
+ * expected.
+ * - [5.1.7] Posting and then fetching one more message, no errors
+ * expected.
+ * - [5.1.8] Testing final conditions. Data pointers must be aligned to
+ * buffer start, semaphore counters are checked.
* .
*/
static void test_005_001_setup(void) {
- chPoolObjectInit(&mp1, sizeof (uint32_t), NULL);
+ chMBObjectInit(&mb1, mb_buffer, MB_SIZE);
+}
+
+static void test_005_001_teardown(void) {
+ chMBReset(&mb1);
}
static void test_005_001_execute(void) {
+ msg_t msg1, msg2;
unsigned i;
- /* [5.1.1] Adding the objects to the pool using chPoolLoadArray().*/
+ /* [5.1.1] Testing the mailbox size.*/
test_set_step(1);
{
- chPoolLoadArray(&mp1, objects, MEMORY_POOL_SIZE);
+ test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "wrong size");
}
- /* [5.1.2] Emptying the pool using chPoolAlloc().*/
+ /* [5.1.2] Resetting the mailbox, conditions are checked, no errors
+ expected.*/
test_set_step(2);
{
- for (i = 0; i < MEMORY_POOL_SIZE; i++)
- test_assert(chPoolAlloc(&mp1) != NULL, "list empty");
+ chMBReset(&mb1);
+ test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "not empty");
+ test_assert_lock(chMBGetUsedCountI(&mb1) == 0, "still full");
+ test_assert_lock(mb1.buffer == mb1.wrptr, "write pointer not aligned to base");
+ test_assert_lock(mb1.buffer == mb1.rdptr, "read pointer not aligned to base");
}
- /* [5.1.3] Now must be empty.*/
+ /* [5.1.3] Testing the behavior of API when the mailbox is in reset
+ state then return in active state.*/
test_set_step(3);
{
- test_assert(chPoolAlloc(&mp1) == NULL, "list not empty");
+ msg1 = chMBPost(&mb1, (msg_t)0, TIME_INFINITE);
+ test_assert(msg1 == MSG_RESET, "not in reset state");
+ msg1 = chMBPostAhead(&mb1, (msg_t)0, TIME_INFINITE);
+ test_assert(msg1 == MSG_RESET, "not in reset state");
+ msg1 = chMBFetch(&mb1, &msg2, TIME_INFINITE);
+ test_assert(msg1 == MSG_RESET, "not in reset state");
+ chMBResumeX(&mb1);
}
- /* [5.1.4] Adding the objects to the pool using chPoolFree().*/
+ /* [5.1.4] Filling the mailbox using chMBPost() and chMBPostAhead()
+ once, no errors expected.*/
test_set_step(4);
{
- for (i = 0; i < MEMORY_POOL_SIZE; i++)
- chPoolFree(&mp1, &objects[i]);
+ for (i = 0; i < MB_SIZE - 1; i++) {
+ msg1 = chMBPost(&mb1, 'B' + i, TIME_INFINITE);
+ test_assert(msg1 == MSG_OK, "wrong wake-up message");
+ }
+ msg1 = chMBPostAhead(&mb1, 'A', TIME_INFINITE);
+ test_assert(msg1 == MSG_OK, "wrong wake-up message");
}
- /* [5.1.5] Emptying the pool using chPoolAlloc() again.*/
+ /* [5.1.5] Testing intermediate conditions. Data pointers must be
+ aligned, semaphore counters are checked.*/
test_set_step(5);
{
- for (i = 0; i < MEMORY_POOL_SIZE; i++)
- test_assert(chPoolAlloc(&mp1) != NULL, "list empty");
+ test_assert_lock(chMBGetFreeCountI(&mb1) == 0, "still empty");
+ test_assert_lock(chMBGetUsedCountI(&mb1) == MB_SIZE, "not full");
+ test_assert_lock(mb1.rdptr == mb1.wrptr, "pointers not aligned");
}
- /* [5.1.6] Now must be empty again.*/
+ /* [5.1.6] Emptying the mailbox using chMBFetch(), no errors
+ expected.*/
test_set_step(6);
{
- test_assert(chPoolAlloc(&mp1) == NULL, "list not empty");
+ for (i = 0; i < MB_SIZE; i++) {
+ msg1 = chMBFetch(&mb1, &msg2, TIME_INFINITE);
+ test_assert(msg1 == MSG_OK, "wrong wake-up message");
+ test_emit_token(msg2);
+ }
+ test_assert_sequence("ABCD", "wrong get sequence");
}
- /* [5.1.7] Covering the case where a provider is unable to return
- more memory.*/
+ /* [5.1.7] Posting and then fetching one more message, no errors
+ expected.*/
test_set_step(7);
{
- chPoolObjectInit(&mp1, sizeof (uint32_t), null_provider);
- test_assert(chPoolAlloc(&mp1) == NULL, "provider returned memory");
+ msg1 = chMBPost(&mb1, 'B' + i, TIME_INFINITE);
+ test_assert(msg1 == MSG_OK, "wrong wake-up message");
+ msg1 = chMBFetch(&mb1, &msg2, TIME_INFINITE);
+ test_assert(msg1 == MSG_OK, "wrong wake-up message");
+ }
+
+ /* [5.1.8] Testing final conditions. Data pointers must be aligned to
+ buffer start, semaphore counters are checked.*/
+ test_set_step(8);
+ {
+ test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "not empty");
+ test_assert_lock(chMBGetUsedCountI(&mb1) == 0, "still full");
+ test_assert(mb1.buffer == mb1.wrptr, "write pointer not aligned to base");
+ test_assert(mb1.buffer == mb1.rdptr, "read pointer not aligned to base");
}
}
static const testcase_t test_005_001 = {
- "Loading and emptying a memory pool",
+ "Mailbox normal API, non-blocking tests",
test_005_001_setup,
- NULL,
+ test_005_001_teardown,
test_005_001_execute
};
-#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
/**
- * @page test_005_002 [5.2] Loading and emptying a guarded memory pool without waiting
+ * @page test_005_002 [5.2] Mailbox I-Class API, non-blocking tests
*
* <h2>Description</h2>
- * The memory pool functionality is tested by loading and emptying it,
- * all conditions are tested.
- *
- * <h2>Conditions</h2>
- * This test is only executed if the following preprocessor condition
- * evaluates to true:
- * - CH_CFG_USE_SEMAPHORES
- * .
+ * The mailbox I-Class API is tested without triggering blocking
+ * conditions.
*
* <h2>Test Steps</h2>
- * - [5.2.1] Adding the objects to the pool using
- * chGuardedPoolLoadArray().
- * - [5.2.2] Emptying the pool using chGuardedPoolAllocTimeout().
- * - [5.2.3] Now must be empty.
- * - [5.2.4] Adding the objects to the pool using chGuardedPoolFree().
- * - [5.2.5] Emptying the pool using chGuardedPoolAllocTimeout() again.
- * - [5.2.6] Now must be empty again.
+ * - [5.2.1] Testing the mailbox size.
+ * - [5.2.2] Resetting the mailbox, conditions are checked, no errors
+ * expected.
+ * - [5.2.3] Filling the mailbox using chMBPostI() and chMBPostAheadI()
+ * once, no errors expected.
+ * - [5.2.4] Testing intermediate conditions. Data pointers must be
+ * aligned, semaphore counters are checked.
+ * - [5.2.5] Emptying the mailbox using chMBFetchI(), no errors
+ * expected.
+ * - [5.2.6] Posting and then fetching one more message, no errors
+ * expected.
+ * - [5.2.7] Testing final conditions. Data pointers must be aligned to
+ * buffer start, semaphore counters are checked.
* .
*/
static void test_005_002_setup(void) {
- chGuardedPoolObjectInit(&gmp1, sizeof (uint32_t));
+ chMBObjectInit(&mb1, mb_buffer, MB_SIZE);
+}
+
+static void test_005_002_teardown(void) {
+ chMBReset(&mb1);
}
static void test_005_002_execute(void) {
+ msg_t msg1, msg2;
unsigned i;
- /* [5.2.1] Adding the objects to the pool using
- chGuardedPoolLoadArray().*/
+ /* [5.2.1] Testing the mailbox size.*/
test_set_step(1);
{
- chGuardedPoolLoadArray(&gmp1, objects, MEMORY_POOL_SIZE);
+ test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "wrong size");
}
- /* [5.2.2] Emptying the pool using chGuardedPoolAllocTimeout().*/
+ /* [5.2.2] Resetting the mailbox, conditions are checked, no errors
+ expected.*/
test_set_step(2);
{
- for (i = 0; i < MEMORY_POOL_SIZE; i++)
- test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) != NULL, "list empty");
+ chSysLock();
+ chMBResetI(&mb1);
+ chSysUnlock();
+ test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "not empty");
+ test_assert_lock(chMBGetUsedCountI(&mb1) == 0, "still full");
+ test_assert_lock(mb1.buffer == mb1.wrptr, "write pointer not aligned to base");
+ test_assert_lock(mb1.buffer == mb1.rdptr, "read pointer not aligned to base");
+ chMBResumeX(&mb1);
}
- /* [5.2.3] Now must be empty.*/
+ /* [5.2.3] Filling the mailbox using chMBPostI() and chMBPostAheadI()
+ once, no errors expected.*/
test_set_step(3);
{
- test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) == NULL, "list not empty");
+ for (i = 0; i < MB_SIZE - 1; i++) {
+ chSysLock();
+ msg1 = chMBPostI(&mb1, 'B' + i);
+ chSysUnlock();
+ test_assert(msg1 == MSG_OK, "wrong wake-up message");
+ }
+ chSysLock();
+ msg1 = chMBPostAheadI(&mb1, 'A');
+ chSysUnlock();
+ test_assert(msg1 == MSG_OK, "wrong wake-up message");
}
- /* [5.2.4] Adding the objects to the pool using
- chGuardedPoolFree().*/
+ /* [5.2.4] Testing intermediate conditions. Data pointers must be
+ aligned, semaphore counters are checked.*/
test_set_step(4);
{
- for (i = 0; i < MEMORY_POOL_SIZE; i++)
- chGuardedPoolFree(&gmp1, &objects[i]);
+ test_assert_lock(chMBGetFreeCountI(&mb1) == 0, "still empty");
+ test_assert_lock(chMBGetUsedCountI(&mb1) == MB_SIZE, "not full");
+ test_assert_lock(mb1.rdptr == mb1.wrptr, "pointers not aligned");
}
- /* [5.2.5] Emptying the pool using chGuardedPoolAllocTimeout()
- again.*/
+ /* [5.2.5] Emptying the mailbox using chMBFetchI(), no errors
+ expected.*/
test_set_step(5);
{
- for (i = 0; i < MEMORY_POOL_SIZE; i++)
- test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) != NULL, "list empty");
+ for (i = 0; i < MB_SIZE; i++) {
+ chSysLock();
+ msg1 = chMBFetchI(&mb1, &msg2);
+ chSysUnlock();
+ test_assert(msg1 == MSG_OK, "wrong wake-up message");
+ test_emit_token(msg2);
+ }
+ test_assert_sequence("ABCD", "wrong get sequence");
}
- /* [5.2.6] Now must be empty again.*/
+ /* [5.2.6] Posting and then fetching one more message, no errors
+ expected.*/
test_set_step(6);
{
- test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) == NULL, "list not empty");
+ msg1 = chMBPost(&mb1, 'B' + i, TIME_INFINITE);
+ test_assert(msg1 == MSG_OK, "wrong wake-up message");
+ msg1 = chMBFetch(&mb1, &msg2, TIME_INFINITE);
+ test_assert(msg1 == MSG_OK, "wrong wake-up message");
+ }
+
+ /* [5.2.7] Testing final conditions. Data pointers must be aligned to
+ buffer start, semaphore counters are checked.*/
+ test_set_step(7);
+ {
+ test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "not empty");
+ test_assert_lock(chMBGetUsedCountI(&mb1) == 0, "still full");
+ test_assert(mb1.buffer == mb1.wrptr, "write pointer not aligned to base");
+ test_assert(mb1.buffer == mb1.rdptr, "read pointer not aligned to base");
}
}
static const testcase_t test_005_002 = {
- "Loading and emptying a guarded memory pool without waiting",
+ "Mailbox I-Class API, non-blocking tests",
test_005_002_setup,
- NULL,
+ test_005_002_teardown,
test_005_002_execute
};
-#endif /* CH_CFG_USE_SEMAPHORES */
-#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
/**
- * @page test_005_003 [5.3] Guarded Memory Pools timeout
+ * @page test_005_003 [5.3] Mailbox timeouts
*
* <h2>Description</h2>
- * The timeout features for the Guarded Memory Pools is tested.
- *
- * <h2>Conditions</h2>
- * This test is only executed if the following preprocessor condition
- * evaluates to true:
- * - CH_CFG_USE_SEMAPHORES
- * .
+ * The mailbox API is tested for timeouts.
*
* <h2>Test Steps</h2>
- * - [5.3.1] Trying to allocate with 100mS timeout, must fail because
- * the pool is empty.
+ * - [5.3.1] Filling the mailbox.
+ * - [5.3.2] Testing chMBPost(), chMBPostI(), chMBPostAhead() and
+ * chMBPostAheadI() timeout.
+ * - [5.3.3] Resetting the mailbox.
+ * - [5.3.4] Testing chMBFetch() and chMBFetchI() timeout.
* .
*/
static void test_005_003_setup(void) {
- chGuardedPoolObjectInit(&gmp1, sizeof (uint32_t));
+ chMBObjectInit(&mb1, mb_buffer, MB_SIZE);
+}
+
+static void test_005_003_teardown(void) {
+ chMBReset(&mb1);
}
static void test_005_003_execute(void) {
+ msg_t msg1, msg2;
+ unsigned i;
- /* [5.3.1] Trying to allocate with 100mS timeout, must fail because
- the pool is empty.*/
+ /* [5.3.1] Filling the mailbox.*/
test_set_step(1);
{
- test_assert(chGuardedPoolAllocTimeout(&gmp1, MS2ST(100)) == NULL, "list not empty");
+ for (i = 0; i < MB_SIZE; i++) {
+ msg1 = chMBPost(&mb1, 'B' + i, TIME_INFINITE);
+ test_assert(msg1 == MSG_OK, "wrong wake-up message");
+ }
+ }
+
+ /* [5.3.2] Testing chMBPost(), chMBPostI(), chMBPostAhead() and
+ chMBPostAheadI() timeout.*/
+ test_set_step(2);
+ {
+ msg1 = chMBPost(&mb1, 'X', 1);
+ test_assert(msg1 == MSG_TIMEOUT, "wrong wake-up message");
+ chSysLock();
+ msg1 = chMBPostI(&mb1, 'X');
+ chSysUnlock();
+ test_assert(msg1 == MSG_TIMEOUT, "wrong wake-up message");
+ msg1 = chMBPostAhead(&mb1, 'X', 1);
+ test_assert(msg1 == MSG_TIMEOUT, "wrong wake-up message");
+ chSysLock();
+ msg1 = chMBPostAheadI(&mb1, 'X');
+ chSysUnlock();
+ test_assert(msg1 == MSG_TIMEOUT, "wrong wake-up message");
+ }
+
+ /* [5.3.3] Resetting the mailbox.*/
+ test_set_step(3);
+ {
+ chMBReset(&mb1);;
+ chMBResumeX(&mb1);
+ }
+
+ /* [5.3.4] Testing chMBFetch() and chMBFetchI() timeout.*/
+ test_set_step(4);
+ {
+ msg1 = chMBFetch(&mb1, &msg2, 1);
+ test_assert(msg1 == MSG_TIMEOUT, "wrong wake-up message");
+ chSysLock();
+ msg1 = chMBFetchI(&mb1, &msg2);
+ chSysUnlock();
+ test_assert(msg1 == MSG_TIMEOUT, "wrong wake-up message");
}
}
static const testcase_t test_005_003 = {
- "Guarded Memory Pools timeout",
+ "Mailbox timeouts",
test_005_003_setup,
- NULL,
+ test_005_003_teardown,
test_005_003_execute
};
-#endif /* CH_CFG_USE_SEMAPHORES */
/****************************************************************************
* Exported data.
****************************************************************************/
/**
- * @brief Memory Pools.
+ * @brief Mailboxes.
*/
const testcase_t * const test_sequence_005[] = {
&test_005_001,
-#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
&test_005_002,
-#endif
-#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
&test_005_003,
-#endif
NULL
};
-#endif /* CH_CFG_USE_MEMPOOLS */
+#endif /* CH_CFG_USE_MAILBOXES */
diff --git a/test/nil/source/test/test_sequence_006.c b/test/nil/source/test/test_sequence_006.c
index ba3e8cbf9..dad464e6c 100644
--- a/test/nil/source/test/test_sequence_006.c
+++ b/test/nil/source/test/test_sequence_006.c
@@ -22,252 +22,275 @@
* @file test_sequence_006.c
* @brief Test Sequence 006 code.
*
- * @page test_sequence_006 [6] Memory Heaps
+ * @page test_sequence_006 [6] Memory Pools
*
* File: @ref test_sequence_006.c
*
* <h2>Description</h2>
* This sequence tests the ChibiOS/NIL functionalities related to
- * memory heaps.
+ * memory pools.
*
* <h2>Conditions</h2>
* This sequence is only executed if the following preprocessor condition
* evaluates to true:
- * - CH_CFG_USE_HEAP
+ * - CH_CFG_USE_MEMPOOLS
* .
*
* <h2>Test Cases</h2>
* - @subpage test_006_001
* - @subpage test_006_002
+ * - @subpage test_006_003
* .
*/
-#if (CH_CFG_USE_HEAP) || defined(__DOXYGEN__)
+#if (CH_CFG_USE_MEMPOOLS) || defined(__DOXYGEN__)
/****************************************************************************
* Shared code.
****************************************************************************/
-#define ALLOC_SIZE 16
-#define HEAP_SIZE (ALLOC_SIZE * 8)
+#define MEMORY_POOL_SIZE 4
-static memory_heap_t test_heap;
-static CH_HEAP_AREA(myheap, HEAP_SIZE);
+static uint32_t objects[MEMORY_POOL_SIZE];
+static MEMORYPOOL_DECL(mp1, sizeof (uint32_t), NULL);
+
+#if CH_CFG_USE_SEMAPHORES
+static GUARDEDMEMORYPOOL_DECL(gmp1, sizeof (uint32_t));
+#endif
+
+static void *null_provider(size_t size, unsigned align) {
+
+ (void)size;
+ (void)align;
+
+ return NULL;
+}
/****************************************************************************
* Test cases.
****************************************************************************/
/**
- * @page test_006_001 [6.1] Allocation and fragmentation
+ * @page test_006_001 [6.1] Loading and emptying a memory pool
*
* <h2>Description</h2>
- * Series of allocations/deallocations are performed in carefully
- * designed sequences in order to stimulate all the possible code paths
- * inside the allocator. The test expects to find the heap back to the
- * initial status after each sequence.
+ * The memory pool functionality is tested by loading and emptying it,
+ * all conditions are tested.
*
* <h2>Test Steps</h2>
- * - [6.1.1] Testing initial conditions, the heap must not be
- * fragmented and one free block present.
- * - [6.1.2] Trying to allocate an block bigger than available space,
- * an error is expected.
- * - [6.1.3] Single block allocation using chHeapAlloc() then the block
- * is freed using chHeapFree(), must not fail.
- * - [6.1.4] Using chHeapStatus() to assess the heap state. There must
- * be at least one free block of sufficient size.
- * - [6.1.5] Allocating then freeing in the same order.
- * - [6.1.6] Allocating then freeing in reverse order.
- * - [6.1.7] Small fragments handling. Checking the behavior when
- * allocating blocks with size not multiple of alignment unit.
- * - [6.1.8] Skipping a fragment, the first fragment in the list is too
- * small so the allocator must pick the second one.
- * - [6.1.9] Allocating the whole available space.
- * - [6.1.10] Testing final conditions. The heap geometry must be the
- * same than the one registered at beginning.
+ * - [6.1.1] Adding the objects to the pool using chPoolLoadArray().
+ * - [6.1.2] Emptying the pool using chPoolAlloc().
+ * - [6.1.3] Now must be empty.
+ * - [6.1.4] Adding the objects to the pool using chPoolFree().
+ * - [6.1.5] Emptying the pool using chPoolAlloc() again.
+ * - [6.1.6] Now must be empty again.
+ * - [6.1.7] Covering the case where a provider is unable to return
+ * more memory.
* .
*/
static void test_006_001_setup(void) {
- chHeapObjectInit(&test_heap, myheap, sizeof(myheap));
+ chPoolObjectInit(&mp1, sizeof (uint32_t), NULL);
}
static void test_006_001_execute(void) {
- void *p1, *p2, *p3;
- size_t n, sz;
+ unsigned i;
- /* [6.1.1] Testing initial conditions, the heap must not be
- fragmented and one free block present.*/
+ /* [6.1.1] Adding the objects to the pool using chPoolLoadArray().*/
test_set_step(1);
{
- test_assert(chHeapStatus(&test_heap, &sz, NULL) == 1, "heap fragmented");
+ chPoolLoadArray(&mp1, objects, MEMORY_POOL_SIZE);
}
- /* [6.1.2] Trying to allocate an block bigger than available space,
- an error is expected.*/
+ /* [6.1.2] Emptying the pool using chPoolAlloc().*/
test_set_step(2);
{
- p1 = chHeapAlloc(&test_heap, HEAP_SIZE * 2);
- test_assert(p1 == NULL, "allocation not failed");
+ for (i = 0; i < MEMORY_POOL_SIZE; i++)
+ test_assert(chPoolAlloc(&mp1) != NULL, "list empty");
}
- /* [6.1.3] Single block allocation using chHeapAlloc() then the block
- is freed using chHeapFree(), must not fail.*/
+ /* [6.1.3] Now must be empty.*/
test_set_step(3);
{
- p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
- test_assert(p1 != NULL, "allocation failed");
- chHeapFree(p1);
+ test_assert(chPoolAlloc(&mp1) == NULL, "list not empty");
}
- /* [6.1.4] Using chHeapStatus() to assess the heap state. There must
- be at least one free block of sufficient size.*/
+ /* [6.1.4] Adding the objects to the pool using chPoolFree().*/
test_set_step(4);
{
- size_t total_size, largest_size;
-
- n = chHeapStatus(&test_heap, &total_size, &largest_size);
- test_assert(n == 1, "missing free block");
- test_assert(total_size >= ALLOC_SIZE, "unexpected heap state");
- test_assert(total_size == largest_size, "unexpected heap state");
+ for (i = 0; i < MEMORY_POOL_SIZE; i++)
+ chPoolFree(&mp1, &objects[i]);
}
- /* [6.1.5] Allocating then freeing in the same order.*/
+ /* [6.1.5] Emptying the pool using chPoolAlloc() again.*/
test_set_step(5);
{
- p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
- p2 = chHeapAlloc(&test_heap, ALLOC_SIZE);
- p3 = chHeapAlloc(&test_heap, ALLOC_SIZE);
- chHeapFree(p1); /* Does not merge.*/
- chHeapFree(p2); /* Merges backward.*/
- chHeapFree(p3); /* Merges both sides.*/
- test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
+ for (i = 0; i < MEMORY_POOL_SIZE; i++)
+ test_assert(chPoolAlloc(&mp1) != NULL, "list empty");
}
- /* [6.1.6] Allocating then freeing in reverse order.*/
+ /* [6.1.6] Now must be empty again.*/
test_set_step(6);
{
- p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
- p2 = chHeapAlloc(&test_heap, ALLOC_SIZE);
- p3 = chHeapAlloc(&test_heap, ALLOC_SIZE);
- chHeapFree(p3); /* Merges forward.*/
- chHeapFree(p2); /* Merges forward.*/
- chHeapFree(p1); /* Merges forward.*/
- test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
+ test_assert(chPoolAlloc(&mp1) == NULL, "list not empty");
}
- /* [6.1.7] Small fragments handling. Checking the behavior when
- allocating blocks with size not multiple of alignment unit.*/
+ /* [6.1.7] Covering the case where a provider is unable to return
+ more memory.*/
test_set_step(7);
{
- p1 = chHeapAlloc(&test_heap, ALLOC_SIZE + 1);
- p2 = chHeapAlloc(&test_heap, ALLOC_SIZE);
- chHeapFree(p1);
- test_assert(chHeapStatus(&test_heap, &n, NULL) == 2, "invalid state");
- p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
- /* Note, the first situation happens when the alignment size is smaller
- than the header size, the second in the other cases.*/
- test_assert((chHeapStatus(&test_heap, &n, NULL) == 1) ||
- (chHeapStatus(&test_heap, &n, NULL) == 2), "heap fragmented");
- chHeapFree(p2);
- chHeapFree(p1);
- test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
- }
-
- /* [6.1.8] Skipping a fragment, the first fragment in the list is too
- small so the allocator must pick the second one.*/
- test_set_step(8);
- {
- p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
- p2 = chHeapAlloc(&test_heap, ALLOC_SIZE);
- chHeapFree(p1);
- test_assert( chHeapStatus(&test_heap, &n, NULL) == 2, "invalid state");
- p1 = chHeapAlloc(&test_heap, ALLOC_SIZE * 2); /* Skips first fragment.*/
- chHeapFree(p1);
- chHeapFree(p2);
- test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
- }
-
- /* [6.1.9] Allocating the whole available space.*/
- test_set_step(9);
- {
- (void)chHeapStatus(&test_heap, &n, NULL);
- p1 = chHeapAlloc(&test_heap, n);
- test_assert(p1 != NULL, "allocation failed");
- test_assert(chHeapStatus(&test_heap, NULL, NULL) == 0, "not empty");
- chHeapFree(p1);
- }
-
- /* [6.1.10] Testing final conditions. The heap geometry must be the
- same than the one registered at beginning.*/
- test_set_step(10);
- {
- test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
- test_assert(n == sz, "size changed");
+ chPoolObjectInit(&mp1, sizeof (uint32_t), null_provider);
+ test_assert(chPoolAlloc(&mp1) == NULL, "provider returned memory");
}
}
static const testcase_t test_006_001 = {
- "Allocation and fragmentation",
+ "Loading and emptying a memory pool",
test_006_001_setup,
NULL,
test_006_001_execute
};
+#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
/**
- * @page test_006_002 [6.2] Default Heap
+ * @page test_006_002 [6.2] Loading and emptying a guarded memory pool without waiting
*
* <h2>Description</h2>
- * The default heap is pre-allocated in the system. We test base
- * functionality.
+ * The memory pool functionality is tested by loading and emptying it,
+ * all conditions are tested.
+ *
+ * <h2>Conditions</h2>
+ * This test is only executed if the following preprocessor condition
+ * evaluates to true:
+ * - CH_CFG_USE_SEMAPHORES
+ * .
*
* <h2>Test Steps</h2>
- * - [6.2.1] Single block allocation using chHeapAlloc() then the block
- * is freed using chHeapFree(), must not fail.
- * - [6.2.2] Testing allocation failure.
+ * - [6.2.1] Adding the objects to the pool using
+ * chGuardedPoolLoadArray().
+ * - [6.2.2] Emptying the pool using chGuardedPoolAllocTimeout().
+ * - [6.2.3] Now must be empty.
+ * - [6.2.4] Adding the objects to the pool using chGuardedPoolFree().
+ * - [6.2.5] Emptying the pool using chGuardedPoolAllocTimeout() again.
+ * - [6.2.6] Now must be empty again.
* .
*/
+static void test_006_002_setup(void) {
+ chGuardedPoolObjectInit(&gmp1, sizeof (uint32_t));
+}
+
static void test_006_002_execute(void) {
- void *p1;
- size_t total_size, largest_size;
+ unsigned i;
- /* [6.2.1] Single block allocation using chHeapAlloc() then the block
- is freed using chHeapFree(), must not fail.*/
+ /* [6.2.1] Adding the objects to the pool using
+ chGuardedPoolLoadArray().*/
test_set_step(1);
{
- (void)chHeapStatus(NULL, &total_size, &largest_size);
- p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
- test_assert(p1 != NULL, "allocation failed");
- chHeapFree(p1);
+ chGuardedPoolLoadArray(&gmp1, objects, MEMORY_POOL_SIZE);
}
- /* [6.2.2] Testing allocation failure.*/
+ /* [6.2.2] Emptying the pool using chGuardedPoolAllocTimeout().*/
test_set_step(2);
{
- p1 = chHeapAlloc(NULL, (size_t)-256);
- test_assert(p1 == NULL, "allocation not failed");
+ for (i = 0; i < MEMORY_POOL_SIZE; i++)
+ test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) != NULL, "list empty");
+ }
+
+ /* [6.2.3] Now must be empty.*/
+ test_set_step(3);
+ {
+ test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) == NULL, "list not empty");
+ }
+
+ /* [6.2.4] Adding the objects to the pool using
+ chGuardedPoolFree().*/
+ test_set_step(4);
+ {
+ for (i = 0; i < MEMORY_POOL_SIZE; i++)
+ chGuardedPoolFree(&gmp1, &objects[i]);
+ }
+
+ /* [6.2.5] Emptying the pool using chGuardedPoolAllocTimeout()
+ again.*/
+ test_set_step(5);
+ {
+ for (i = 0; i < MEMORY_POOL_SIZE; i++)
+ test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) != NULL, "list empty");
+ }
+
+ /* [6.2.6] Now must be empty again.*/
+ test_set_step(6);
+ {
+ test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) == NULL, "list not empty");
}
}
static const testcase_t test_006_002 = {
- "Default Heap",
- NULL,
+ "Loading and emptying a guarded memory pool without waiting",
+ test_006_002_setup,
NULL,
test_006_002_execute
};
+#endif /* CH_CFG_USE_SEMAPHORES */
+
+#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
+/**
+ * @page test_006_003 [6.3] Guarded Memory Pools timeout
+ *
+ * <h2>Description</h2>
+ * The timeout features for the Guarded Memory Pools is tested.
+ *
+ * <h2>Conditions</h2>
+ * This test is only executed if the following preprocessor condition
+ * evaluates to true:
+ * - CH_CFG_USE_SEMAPHORES
+ * .
+ *
+ * <h2>Test Steps</h2>
+ * - [6.3.1] Trying to allocate with 100mS timeout, must fail because
+ * the pool is empty.
+ * .
+ */
+
+static void test_006_003_setup(void) {
+ chGuardedPoolObjectInit(&gmp1, sizeof (uint32_t));
+}
+
+static void test_006_003_execute(void) {
+
+ /* [6.3.1] Trying to allocate with 100mS timeout, must fail because
+ the pool is empty.*/
+ test_set_step(1);
+ {
+ test_assert(chGuardedPoolAllocTimeout(&gmp1, MS2ST(100)) == NULL, "list not empty");
+ }
+}
+
+static const testcase_t test_006_003 = {
+ "Guarded Memory Pools timeout",
+ test_006_003_setup,
+ NULL,
+ test_006_003_execute
+};
+#endif /* CH_CFG_USE_SEMAPHORES */
/****************************************************************************
* Exported data.
****************************************************************************/
/**
- * @brief Memory Heaps.
+ * @brief Memory Pools.
*/
const testcase_t * const test_sequence_006[] = {
&test_006_001,
+#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
&test_006_002,
+#endif
+#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
+ &test_006_003,
+#endif
NULL
};
-#endif /* CH_CFG_USE_HEAP */
+#endif /* CH_CFG_USE_MEMPOOLS */
diff --git a/test/nil/source/test/test_sequence_007.c b/test/nil/source/test/test_sequence_007.c
new file mode 100644
index 000000000..4cd0c804e
--- /dev/null
+++ b/test/nil/source/test/test_sequence_007.c
@@ -0,0 +1,273 @@
+/*
+ ChibiOS - Copyright (C) 2006..2016 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.
+*/
+
+#include "hal.h"
+#include "ch_test.h"
+#include "test_root.h"
+
+/**
+ * @file test_sequence_007.c
+ * @brief Test Sequence 007 code.
+ *
+ * @page test_sequence_007 [7] Memory Heaps
+ *
+ * File: @ref test_sequence_007.c
+ *
+ * <h2>Description</h2>
+ * This sequence tests the ChibiOS/NIL functionalities related to
+ * memory heaps.
+ *
+ * <h2>Conditions</h2>
+ * This sequence is only executed if the following preprocessor condition
+ * evaluates to true:
+ * - CH_CFG_USE_HEAP
+ * .
+ *
+ * <h2>Test Cases</h2>
+ * - @subpage test_007_001
+ * - @subpage test_007_002
+ * .
+ */
+
+#if (CH_CFG_USE_HEAP) || defined(__DOXYGEN__)
+
+/****************************************************************************
+ * Shared code.
+ ****************************************************************************/
+
+#define ALLOC_SIZE 16
+#define HEAP_SIZE (ALLOC_SIZE * 8)
+
+static memory_heap_t test_heap;
+static CH_HEAP_AREA(myheap, HEAP_SIZE);
+
+/****************************************************************************
+ * Test cases.
+ ****************************************************************************/
+
+/**
+ * @page test_007_001 [7.1] Allocation and fragmentation
+ *
+ * <h2>Description</h2>
+ * Series of allocations/deallocations are performed in carefully
+ * designed sequences in order to stimulate all the possible code paths
+ * inside the allocator. The test expects to find the heap back to the
+ * initial status after each sequence.
+ *
+ * <h2>Test Steps</h2>
+ * - [7.1.1] Testing initial conditions, the heap must not be
+ * fragmented and one free block present.
+ * - [7.1.2] Trying to allocate an block bigger than available space,
+ * an error is expected.
+ * - [7.1.3] Single block allocation using chHeapAlloc() then the block
+ * is freed using chHeapFree(), must not fail.
+ * - [7.1.4] Using chHeapStatus() to assess the heap state. There must
+ * be at least one free block of sufficient size.
+ * - [7.1.5] Allocating then freeing in the same order.
+ * - [7.1.6] Allocating then freeing in reverse order.
+ * - [7.1.7] Small fragments handling. Checking the behavior when
+ * allocating blocks with size not multiple of alignment unit.
+ * - [7.1.8] Skipping a fragment, the first fragment in the list is too
+ * small so the allocator must pick the second one.
+ * - [7.1.9] Allocating the whole available space.
+ * - [7.1.10] Testing final conditions. The heap geometry must be the
+ * same than the one registered at beginning.
+ * .
+ */
+
+static void test_007_001_setup(void) {
+ chHeapObjectInit(&test_heap, myheap, sizeof(myheap));
+}
+
+static void test_007_001_execute(void) {
+ void *p1, *p2, *p3;
+ size_t n, sz;
+
+ /* [7.1.1] Testing initial conditions, the heap must not be
+ fragmented and one free block present.*/
+ test_set_step(1);
+ {
+ test_assert(chHeapStatus(&test_heap, &sz, NULL) == 1, "heap fragmented");
+ }
+
+ /* [7.1.2] Trying to allocate an block bigger than available space,
+ an error is expected.*/
+ test_set_step(2);
+ {
+ p1 = chHeapAlloc(&test_heap, HEAP_SIZE * 2);
+ test_assert(p1 == NULL, "allocation not failed");
+ }
+
+ /* [7.1.3] Single block allocation using chHeapAlloc() then the block
+ is freed using chHeapFree(), must not fail.*/
+ test_set_step(3);
+ {
+ p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
+ test_assert(p1 != NULL, "allocation failed");
+ chHeapFree(p1);
+ }
+
+ /* [7.1.4] Using chHeapStatus() to assess the heap state. There must
+ be at least one free block of sufficient size.*/
+ test_set_step(4);
+ {
+ size_t total_size, largest_size;
+
+ n = chHeapStatus(&test_heap, &total_size, &largest_size);
+ test_assert(n == 1, "missing free block");
+ test_assert(total_size >= ALLOC_SIZE, "unexpected heap state");
+ test_assert(total_size == largest_size, "unexpected heap state");
+ }
+
+ /* [7.1.5] Allocating then freeing in the same order.*/
+ test_set_step(5);
+ {
+ p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
+ p2 = chHeapAlloc(&test_heap, ALLOC_SIZE);
+ p3 = chHeapAlloc(&test_heap, ALLOC_SIZE);
+ chHeapFree(p1); /* Does not merge.*/
+ chHeapFree(p2); /* Merges backward.*/
+ chHeapFree(p3); /* Merges both sides.*/
+ test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
+ }
+
+ /* [7.1.6] Allocating then freeing in reverse order.*/
+ test_set_step(6);
+ {
+ p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
+ p2 = chHeapAlloc(&test_heap, ALLOC_SIZE);
+ p3 = chHeapAlloc(&test_heap, ALLOC_SIZE);
+ chHeapFree(p3); /* Merges forward.*/
+ chHeapFree(p2); /* Merges forward.*/
+ chHeapFree(p1); /* Merges forward.*/
+ test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
+ }
+
+ /* [7.1.7] Small fragments handling. Checking the behavior when
+ allocating blocks with size not multiple of alignment unit.*/
+ test_set_step(7);
+ {
+ p1 = chHeapAlloc(&test_heap, ALLOC_SIZE + 1);
+ p2 = chHeapAlloc(&test_heap, ALLOC_SIZE);
+ chHeapFree(p1);
+ test_assert(chHeapStatus(&test_heap, &n, NULL) == 2, "invalid state");
+ p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
+ /* Note, the first situation happens when the alignment size is smaller
+ than the header size, the second in the other cases.*/
+ test_assert((chHeapStatus(&test_heap, &n, NULL) == 1) ||
+ (chHeapStatus(&test_heap, &n, NULL) == 2), "heap fragmented");
+ chHeapFree(p2);
+ chHeapFree(p1);
+ test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
+ }
+
+ /* [7.1.8] Skipping a fragment, the first fragment in the list is too
+ small so the allocator must pick the second one.*/
+ test_set_step(8);
+ {
+ p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
+ p2 = chHeapAlloc(&test_heap, ALLOC_SIZE);
+ chHeapFree(p1);
+ test_assert( chHeapStatus(&test_heap, &n, NULL) == 2, "invalid state");
+ p1 = chHeapAlloc(&test_heap, ALLOC_SIZE * 2); /* Skips first fragment.*/
+ chHeapFree(p1);
+ chHeapFree(p2);
+ test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
+ }
+
+ /* [7.1.9] Allocating the whole available space.*/
+ test_set_step(9);
+ {
+ (void)chHeapStatus(&test_heap, &n, NULL);
+ p1 = chHeapAlloc(&test_heap, n);
+ test_assert(p1 != NULL, "allocation failed");
+ test_assert(chHeapStatus(&test_heap, NULL, NULL) == 0, "not empty");
+ chHeapFree(p1);
+ }
+
+ /* [7.1.10] Testing final conditions. The heap geometry must be the
+ same than the one registered at beginning.*/
+ test_set_step(10);
+ {
+ test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
+ test_assert(n == sz, "size changed");
+ }
+}
+
+static const testcase_t test_007_001 = {
+ "Allocation and fragmentation",
+ test_007_001_setup,
+ NULL,
+ test_007_001_execute
+};
+
+/**
+ * @page test_007_002 [7.2] Default Heap
+ *
+ * <h2>Description</h2>
+ * The default heap is pre-allocated in the system. We test base
+ * functionality.
+ *
+ * <h2>Test Steps</h2>
+ * - [7.2.1] Single block allocation using chHeapAlloc() then the block
+ * is freed using chHeapFree(), must not fail.
+ * - [7.2.2] Testing allocation failure.
+ * .
+ */
+
+static void test_007_002_execute(void) {
+ void *p1;
+ size_t total_size, largest_size;
+
+ /* [7.2.1] Single block allocation using chHeapAlloc() then the block
+ is freed using chHeapFree(), must not fail.*/
+ test_set_step(1);
+ {
+ (void)chHeapStatus(NULL, &total_size, &largest_size);
+ p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
+ test_assert(p1 != NULL, "allocation failed");
+ chHeapFree(p1);
+ }
+
+ /* [7.2.2] Testing allocation failure.*/
+ test_set_step(2);
+ {
+ p1 = chHeapAlloc(NULL, (size_t)-256);
+ test_assert(p1 == NULL, "allocation not failed");
+ }
+}
+
+static const testcase_t test_007_002 = {
+ "Default Heap",
+ NULL,
+ NULL,
+ test_007_002_execute
+};
+
+/****************************************************************************
+ * Exported data.
+ ****************************************************************************/
+
+/**
+ * @brief Memory Heaps.
+ */
+const testcase_t * const test_sequence_007[] = {
+ &test_007_001,
+ &test_007_002,
+ NULL
+};
+
+#endif /* CH_CFG_USE_HEAP */
diff --git a/test/nil/source/test/test_sequence_007.h b/test/nil/source/test/test_sequence_007.h
new file mode 100644
index 000000000..18b68a556
--- /dev/null
+++ b/test/nil/source/test/test_sequence_007.h
@@ -0,0 +1,27 @@
+/*
+ ChibiOS - Copyright (C) 2006..2016 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.
+*/
+
+/**
+ * @file test_sequence_007.h
+ * @brief Test Sequence 007 header.
+ */
+
+#ifndef TEST_SEQUENCE_007_H
+#define TEST_SEQUENCE_007_H
+
+extern const testcase_t * const test_sequence_007[];
+
+#endif /* TEST_SEQUENCE_007_H */
diff --git a/test/nil/test.mk b/test/nil/test.mk
index 92c30be25..ac60ee95a 100644
--- a/test/nil/test.mk
+++ b/test/nil/test.mk
@@ -6,7 +6,8 @@ TESTSRC = ${CHIBIOS}/test/lib/ch_test.c \
${CHIBIOS}/test/nil/source/test/test_sequence_003.c \
${CHIBIOS}/test/nil/source/test/test_sequence_004.c \
${CHIBIOS}/test/nil/source/test/test_sequence_005.c \
- ${CHIBIOS}/test/nil/source/test/test_sequence_006.c
+ ${CHIBIOS}/test/nil/source/test/test_sequence_006.c\
+ ${CHIBIOS}/test/nil/source/test/test_sequence_007.c
# Required include directories
TESTINC = ${CHIBIOS}/test/lib \