From fef78a173a32e8529c2e6b7712df2dd1844968bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Betto?= <niccolo.betto@skywarder.eu> Date: Sun, 23 Apr 2023 21:21:50 +0200 Subject: [PATCH] [Test] Add timed wait tests Timed wait tests run a loop that puts a thread into timed wait for 3 seconds. They can either timeout, in which case they will blink once, or they can be waken up by pressing the user button, in which case the led will blink twice. --- CMakeLists.txt | 9 ++ src/tests/timedwait/test-condtimedwait.cpp | 94 +++++++++++++++++ src/tests/timedwait/test-threadtimedwait.cpp | 104 +++++++++++++++++++ 3 files changed, 207 insertions(+) create mode 100644 src/tests/timedwait/test-condtimedwait.cpp create mode 100644 src/tests/timedwait/test-threadtimedwait.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 0772a8044..947d96da0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -392,6 +392,15 @@ sbs_target(test-vn100 stm32f407vg_stm32f4discovery) add_executable(test-lis2mdl src/tests/sensors/test-lis2mdl.cpp) sbs_target(test-lis2mdl stm32f429zi_stm32f4discovery) +#-----------------------------------------------------------------------------# +# Tests - Utils # +#-----------------------------------------------------------------------------# + +add_executable(test-threadtimedwait src/tests/timedwait/test-threadtimedwait.cpp) +sbs_target(test-threadtimedwait stm32f407vg_stm32f4discovery) + +add_executable(test-condtimedwait src/tests/timedwait/test-condtimedwait.cpp) +sbs_target(test-condtimedwait stm32f407vg_stm32f4discovery) #-----------------------------------------------------------------------------# # Tests - Utils # diff --git a/src/tests/timedwait/test-condtimedwait.cpp b/src/tests/timedwait/test-condtimedwait.cpp new file mode 100644 index 000000000..f3929e166 --- /dev/null +++ b/src/tests/timedwait/test-condtimedwait.cpp @@ -0,0 +1,94 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Niccolò Betto + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include <miosix.h> + +#include <functional> + +using namespace miosix; + +namespace +{ +GpioPin button = + GpioPin(GPIOA_BASE, 0); // PA0 for the stm32f407 discovery board + +FastMutex mutex{}; +ConditionVariable condvar{}; + +void blinkLed(int times) +{ + for (int i = 0; i < times; i++) + { + ledOn(); + Thread::sleep(100); + ledOff(); + Thread::sleep(75); + } +} + +bool wasPressed = false; + +void buttonPollingThread(void *argv) +{ + while (true) + { + bool isNowPressed = !button.value(); + + if (isNowPressed && !wasPressed) + { + condvar.signal(); + } + + wasPressed = isNowPressed; + + // 10Hz polling + Thread::sleep(100); + } +} +} // namespace + +int main() +{ + printf("TEST: ConditionVariable::timedWaitFor - No Boardcore dependencies\n"); + + button.mode(Mode::INPUT); + + Thread::create(buttonPollingThread, STACK_MIN, 0, nullptr, + Thread::JOINABLE); + + while (true) + { + Lock<FastMutex> lock{mutex}; + + printf("[%lld] Waiting...\n", getTick()); + if (condvar.timedWaitFor(lock, 3000) == TimedWaitResult::Timeout) + { + printf("[%lld] Timed out, 3 seconds elapsed\n", getTick()); + blinkLed(1); + } + else + { + printf("[%lld] Waken up, user button pressed\n", getTick()); + blinkLed(2); + } + } +} diff --git a/src/tests/timedwait/test-threadtimedwait.cpp b/src/tests/timedwait/test-threadtimedwait.cpp new file mode 100644 index 000000000..f4689e0f3 --- /dev/null +++ b/src/tests/timedwait/test-threadtimedwait.cpp @@ -0,0 +1,104 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Niccolò Betto + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include <miosix.h> + +#include <functional> + +using namespace miosix; + +namespace +{ +GpioPin button = + GpioPin(GPIOA_BASE, 0); // PA0 for the stm32f407 discovery board + +Thread *mainThread = nullptr; + +void blinkLed(int times) +{ + for (int i = 0; i < times; i++) + { + ledOn(); + Thread::sleep(100); + ledOff(); + Thread::sleep(75); + } +} + +bool wasPressed = false; + +void buttonPollingThread(void *argv) +{ + while (true) + { + printf("[%lld] buttonPollingThread: (%p) Polling button...\n", + getTick(), (void *)Thread::getCurrentThread()); + bool isNowPressed = !button.value(); + + if (isNowPressed && !wasPressed) + { + printf("[%lld] buttonPollingThread: (%p) Button pressed\n", + getTick(), (void *)Thread::getCurrentThread()); + mainThread->wakeup(); + } + + wasPressed = isNowPressed; + + // 10Hz polling + Thread::sleep(100); + } +} +} // namespace + +int main() +{ + printf("TEST: Thread::timedWait\n"); + + button.mode(Mode::INPUT); + + Thread *poller = + Thread::create(buttonPollingThread, 1024, 0, nullptr, Thread::JOINABLE); + mainThread = Thread::getCurrentThread(); + printf( + "SUMMARY:\n" + "* mainThread: thread ID (%p)\n" + "* buttonPollingThread: thread ID (%p)\n", + (void *)mainThread, (void *)poller); + + while (true) + { + printf("[%lld] main: (%p) Waiting for button press...\n", getTick(), + (void *)Thread::getCurrentThread()); + if (Thread::timedWaitFor(3000) == TimedWaitResult::Timeout) + { + printf("[%lld] main: (%p) Timed out, 3 seconds elapsed\n", + getTick(), (void *)Thread::getCurrentThread()); + blinkLed(1); + } + else + { + printf("[%lld] main: (%p) Waken up, user button pressed\n", + getTick(), (void *)Thread::getCurrentThread()); + blinkLed(2); + } + } +} -- GitLab