aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--demos/nil/NIL-STM32F303-DISCOVERY/main.c2
-rw-r--r--os/nil/include/nil.h8
-rw-r--r--os/nil/src/nil.c37
-rw-r--r--test/nil/test_root.c6
-rw-r--r--test/nil/test_sequence_002.c108
5 files changed, 144 insertions, 17 deletions
diff --git a/demos/nil/NIL-STM32F303-DISCOVERY/main.c b/demos/nil/NIL-STM32F303-DISCOVERY/main.c
index 2b648ff29..b928874f3 100644
--- a/demos/nil/NIL-STM32F303-DISCOVERY/main.c
+++ b/demos/nil/NIL-STM32F303-DISCOVERY/main.c
@@ -111,7 +111,7 @@ THD_FUNCTION(Thread3, arg) {
THD_TABLE_BEGIN
THD_TABLE_ENTRY(waThread1, "blinker1", Thread1, NULL)
THD_TABLE_ENTRY(waThread2, "blinker2", Thread2, NULL)
- THD_TABLE_ENTRY(wa_test_support, "test_support", test_support, NULL)
+ THD_TABLE_ENTRY(wa_test_support, "test_support", test_support, (void *)&nil.threads[3])
THD_TABLE_ENTRY(waThread3, "tester", Thread3, NULL)
THD_TABLE_END
diff --git a/os/nil/include/nil.h b/os/nil/include/nil.h
index 7ba088dac..161c79a6d 100644
--- a/os/nil/include/nil.h
+++ b/os/nil/include/nil.h
@@ -597,6 +597,13 @@ typedef struct {
#define chSchIsRescRequiredI() ((bool)(nil.current != nil.next))
/**
+ * @brief Returns a pointer to the current @p thread_t.
+ *
+ * @xclass
+ */
+#define chThdGetSelfX() nil.current
+
+/**
* @brief Delays the invoking thread for the specified number of seconds.
* @note The specified time is rounded up to a value allowed by the real
* system clock.
@@ -802,6 +809,7 @@ extern "C" {
void chEvtSignal(thread_t *tp, eventmask_t mask);
void chEvtSignalI(thread_t *tp, eventmask_t mask);
eventmask_t chEvtWaitAnyTimeout(eventmask_t mask, systime_t timeout);
+ eventmask_t chEvtWaitAnyTimeoutS(eventmask_t mask, systime_t timeout);
#ifdef __cplusplus
}
#endif
diff --git a/os/nil/src/nil.c b/os/nil/src/nil.c
index 9141129cb..edd717600 100644
--- a/os/nil/src/nil.c
+++ b/os/nil/src/nil.c
@@ -489,7 +489,9 @@ msg_t chSemWaitTimeout(semaphore_t *sp, systime_t timeout) {
msg_t msg;
chSysLock();
+
msg = chSemWaitTimeoutS(sp, timeout);
+
chSysUnlock();
return msg;
}
@@ -599,8 +601,10 @@ void chSemSignalI(semaphore_t *sp) {
void chSemReset(semaphore_t *sp, cnt_t n) {
chSysLock();
+
chSemResetI(sp, n);
chSchRescheduleS();
+
chSysUnlock();
}
@@ -654,8 +658,10 @@ void chSemResetI(semaphore_t *sp, cnt_t n) {
void chEvtSignal(thread_t *tp, eventmask_t mask) {
chSysLock();
+
chEvtSignalI(tp, mask);
chSchRescheduleS();
+
chSysUnlock();
}
@@ -697,11 +703,38 @@ void chEvtSignalI(thread_t *tp, eventmask_t mask) {
* @api
*/
eventmask_t chEvtWaitAnyTimeout(eventmask_t mask, systime_t timeout) {
- thread_t *ctp = nil.current;
eventmask_t m;
chSysLock();
+ m = chEvtWaitAnyTimeoutS(mask, timeout);
+
+ chSysUnlock();
+ return m;
+}
+
+/**
+ * @brief Waits for any of the specified events.
+ * @details The function waits for any event among those specified in
+ * @p mask to become pending then the events are cleared and
+ * returned.
+ *
+ * @param[in] mask mask of the event flags that the function should wait
+ * for, @p ALL_EVENTS enables all the events
+ * @param[in] timeout the number of ticks before the operation timeouts,
+ * the following special values are allowed:
+ * - @a TIME_IMMEDIATE immediate timeout.
+ * - @a TIME_INFINITE no timeout.
+ * .
+ * @return The mask of the served and cleared events.
+ * @retval 0 if the operation has timed out.
+ *
+ * @sclass
+ */
+eventmask_t chEvtWaitAnyTimeoutS(eventmask_t mask, systime_t timeout) {
+ thread_t *ctp = nil.current;
+ eventmask_t m;
+
if ((m = (ctp->epmask & mask)) == 0) {
if (TIME_IMMEDIATE == timeout) {
chSysUnlock();
@@ -715,8 +748,6 @@ eventmask_t chEvtWaitAnyTimeout(eventmask_t mask, systime_t timeout) {
m = ctp->epmask & mask;
}
ctp->epmask &= ~m;
-
- chSysUnlock();
return m;
}
diff --git a/test/nil/test_root.c b/test/nil/test_root.c
index 49c1d7862..a8efacba7 100644
--- a/test/nil/test_root.c
+++ b/test/nil/test_root.c
@@ -51,8 +51,7 @@ thread_reference_t gtr1;
*/
THD_WORKING_AREA(wa_test_support, 128);
THD_FUNCTION(test_support, arg) {
-
- (void)arg;
+ thread_t *tp = (thread_t *)arg;
/* Initializing global resources.*/
chSemObjectInit(&gsem1, 0);
@@ -65,10 +64,11 @@ THD_FUNCTION(test_support, arg) {
chSemSignalI(&gsem1);
chSemResetI(&gsem2, 0);
chThdResumeI(&gtr1, MSG_OK);
+ chEvtSignalI(tp, 0x55);
chSchRescheduleS();
chSysUnlock();
- chThdSleepMilliseconds(500);
+ chThdSleepMilliseconds(250);
}
}
diff --git a/test/nil/test_sequence_002.c b/test/nil/test_sequence_002.c
index ddb6379ff..a687e7f0f 100644
--- a/test/nil/test_sequence_002.c
+++ b/test/nil/test_sequence_002.c
@@ -222,9 +222,9 @@ static void test_002_003_execute(void) {
test_set_step(1);
{
time = chVTGetSystemTimeX();
- msg = chSemWaitTimeout(&sem1, 100);
- test_assert_time_window(time + 100,
- time + 100 + 1,
+ 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");
@@ -237,9 +237,9 @@ static void test_002_003_execute(void) {
test_set_step(2);
{
time = chVTGetSystemTimeX();
- msg = chSemWaitTimeout(&sem1, 100);
- test_assert_time_window(time + 100,
- time + 100 + 1,
+ 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");
@@ -304,11 +304,11 @@ static void test_002_004_execute(void) {
test_set_step(2);
{
time = chVTGetSystemTimeX();
- msg = chThdSuspendTimeoutS(&gtr1, 100);
- test_assert_time_window(time + 100,
- time + 100 + 1,
+ msg = chThdSuspendTimeoutS(&tr1, MS2ST(1000));
+ test_assert_time_window(time + MS2ST(1000),
+ time + MS2ST(1000) + 1,
"out of time window");
- test_assert(NULL == gtr1,
+ test_assert(NULL == tr1,
"not NULL");
test_assert(MSG_TIMEOUT == msg,
"wrong returned message");
@@ -323,6 +323,91 @@ static const testcase_t test_002_004 = {
};
#endif /* TRUE */
+#if TRUE || defined(__DOXYGEN__)
+/**
+ * @page test_002_005 Events functionality
+ *
+ * <h2>Description</h2>
+ * Event flags functionality is tested.
+ *
+ * <h2>Conditions</h2>
+ * None.
+ *
+ * <h2>Test Steps</h2>
+ * - A set of event flags are set on the current thread then the
+ * function chVTGetSystemTimeX() is invoked, the function is supposed to
+ * return immediately because the event flags are already pending,
+ * after return the events mask is tested.
+ * - The pending event flags mask is cleared then the function
+ * chVTGetSystemTimeX() is invoked, after return the events
+ * mask is tested. The thread is signaled by another thread.
+ * -
+ * . The function chVTGetSystemTimeX() is invoked, no event can
+ * wakeup the thread, the function must return because timeout.
+ */
+
+static void test_002_005_setup(void) {
+
+ chSemObjectInit(&sem1, 0);
+}
+
+static void test_002_005_execute(void) {
+ systime_t time;
+ eventmask_t events;
+
+ /* A set of event flags are set on the current thread then the
+ function chVTGetSystemTimeX() 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);
+ {
+ time = chVTGetSystemTimeX();
+ chEvtSignalI(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");
+ }
+
+ /* The pending event flags mask is cleared then the function
+ chVTGetSystemTimeX() is invoked, after return the events
+ mask is tested. The thread is signaled by another thread.*/
+ test_set_step(2);
+ {
+ 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");
+ }
+
+ /* The function chVTGetSystemTimeX() is invoked, no event can
+ wakeup the thread, the function must return because timeout.*/
+ test_set_step(3);
+ {
+ chSysLock();
+ time = chVTGetSystemTimeX();
+ events = chEvtWaitAnyTimeoutS(0, MS2ST(1000));
+ chSysUnlock();
+ 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_002_005 = {
+ "events functionality",
+ test_002_005_setup,
+ NULL,
+ test_002_005_execute
+};
+#endif /* TRUE */
+
/****************************************************************************
* Exported data.
****************************************************************************/
@@ -343,5 +428,8 @@ const testcase_t * const test_sequence_002[] = {
#if TRUE || defined(__DOXYGEN__)
&test_002_004,
#endif
+#if TRUE || defined(__DOXYGEN__)
+ &test_002_005,
+#endif
NULL
};