Create TactilityFreertos subproject (#440)
This commit is contained in:
committed by
GitHub
parent
a4dc633063
commit
7283920def
@@ -4,8 +4,10 @@ set(DOCTESTINC ${PROJECT_SOURCE_DIR}/Include)
|
||||
|
||||
enable_testing()
|
||||
add_subdirectory(TactilityCore)
|
||||
add_subdirectory(TactilityFreeRtos)
|
||||
add_subdirectory(Tactility)
|
||||
|
||||
add_custom_target(build-tests)
|
||||
add_dependencies(build-tests TactilityCoreTests)
|
||||
add_dependencies(build-tests TactilityFreeRtosTests)
|
||||
add_dependencies(build-tests TactilityTests)
|
||||
|
||||
@@ -20,5 +20,6 @@ add_test(NAME TactilityCoreTests
|
||||
|
||||
target_link_libraries(TactilityCoreTests PUBLIC
|
||||
TactilityCore
|
||||
TactilityFreeRtos
|
||||
freertos_kernel
|
||||
)
|
||||
|
||||
@@ -48,6 +48,8 @@ int main(int argc, char** argv) {
|
||||
assert(task_result == pdPASS);
|
||||
|
||||
vTaskStartScheduler();
|
||||
|
||||
return data.result;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
project(TactilityFreeRtosTests)
|
||||
|
||||
enable_language(C CXX ASM)
|
||||
|
||||
set(CMAKE_CXX_COMPILER g++)
|
||||
|
||||
file(GLOB_RECURSE TEST_SOURCES ${PROJECT_SOURCE_DIR}/*.cpp)
|
||||
add_executable(TactilityFreeRtosTests EXCLUDE_FROM_ALL ${TEST_SOURCES})
|
||||
|
||||
add_definitions(-D_Nullable=)
|
||||
add_definitions(-D_Nonnull=)
|
||||
|
||||
target_include_directories(TactilityFreeRtosTests PRIVATE
|
||||
${DOCTESTINC}
|
||||
)
|
||||
|
||||
add_test(NAME TactilityFreeRtosTests
|
||||
COMMAND TactilityFreeRtosTests
|
||||
)
|
||||
|
||||
target_link_libraries(TactilityFreeRtosTests PUBLIC
|
||||
TactilityFreeRtos
|
||||
freertos_kernel
|
||||
)
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "doctest.h"
|
||||
#include <Tactility/TactilityCore.h>
|
||||
#include <Tactility/Dispatcher.h>
|
||||
|
||||
using namespace tt;
|
||||
@@ -24,8 +23,8 @@ TEST_CASE("dispatcher should call callback when consume is called") {
|
||||
int counter = 0;
|
||||
Dispatcher dispatcher;
|
||||
|
||||
dispatcher.dispatch([&counter]() { counter++; });
|
||||
dispatcher.consume(100);
|
||||
CHECK_EQ(dispatcher.dispatch([&counter] { counter++; }), true);
|
||||
CHECK_EQ(dispatcher.consume(100), 1);
|
||||
|
||||
CHECK_EQ(counter, 1);
|
||||
}
|
||||
-1
@@ -1,5 +1,4 @@
|
||||
#include "doctest.h"
|
||||
#include <Tactility/TactilityCore.h>
|
||||
#include <Tactility/DispatcherThread.h>
|
||||
|
||||
using namespace tt;
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "doctest.h"
|
||||
#include <Tactility/Semaphore.h>
|
||||
#include <Tactility/Lock.h>
|
||||
#include <Tactility/Mutex.h>
|
||||
#include <Tactility/Semaphore.h>
|
||||
|
||||
using namespace tt;
|
||||
|
||||
@@ -35,5 +35,5 @@ TEST_CASE("withLock() unlocks correctly on Mutex") {
|
||||
});
|
||||
|
||||
CHECK_EQ(mutex->lock(1), true);
|
||||
CHECK_EQ(mutex->unlock(), true);
|
||||
mutex->unlock();
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
#define DOCTEST_CONFIG_IMPLEMENT
|
||||
#include "doctest.h"
|
||||
#include <cassert>
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
typedef struct {
|
||||
int argc;
|
||||
char** argv;
|
||||
int result;
|
||||
} TestTaskData;
|
||||
|
||||
void test_task(void* parameter) {
|
||||
auto* data = (TestTaskData*)parameter;
|
||||
|
||||
doctest::Context context;
|
||||
|
||||
context.applyCommandLine(data->argc, data->argv);
|
||||
|
||||
// overrides
|
||||
context.setOption("no-breaks", true); // don't break in the debugger when assertions fail
|
||||
|
||||
data->result = context.run();
|
||||
|
||||
if (context.shouldExit()) { // important - query flags (and --exit) rely on the user doing this
|
||||
vTaskEndScheduler();
|
||||
}
|
||||
|
||||
vTaskDelete(nullptr);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
TestTaskData data = {
|
||||
.argc = argc,
|
||||
.argv = argv,
|
||||
.result = 0
|
||||
};
|
||||
|
||||
BaseType_t task_result = xTaskCreate(
|
||||
test_task,
|
||||
"test_task",
|
||||
8192,
|
||||
&data,
|
||||
1,
|
||||
nullptr
|
||||
);
|
||||
assert(task_result == pdPASS);
|
||||
|
||||
vTaskStartScheduler();
|
||||
|
||||
return data.result;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
// Required for FreeRTOS
|
||||
void vAssertCalled(unsigned long line, const char* const file) {
|
||||
__assert_fail("assert failed", file, line, "");
|
||||
}
|
||||
}
|
||||
-15
@@ -3,13 +3,6 @@
|
||||
|
||||
using namespace tt;
|
||||
|
||||
TEST_CASE("message queue capacity should be correct") {
|
||||
MessageQueue queue(10, 1);
|
||||
|
||||
uint32_t capacity = queue.getCapacity();
|
||||
CHECK_EQ(capacity, 10);
|
||||
}
|
||||
|
||||
TEST_CASE("message queue initial count should be 0") {
|
||||
MessageQueue queue(10, 1);
|
||||
|
||||
@@ -17,13 +10,6 @@ TEST_CASE("message queue initial count should be 0") {
|
||||
CHECK_EQ(count, 0);
|
||||
}
|
||||
|
||||
TEST_CASE("message queue message size should be correct") {
|
||||
MessageQueue queue(1, 123);
|
||||
|
||||
uint32_t message_size = queue.getMessageSize();
|
||||
CHECK_EQ(message_size, 123);
|
||||
}
|
||||
|
||||
TEST_CASE("message queue count should increase when message is added") {
|
||||
MessageQueue queue(10, sizeof(uint32_t));
|
||||
|
||||
@@ -83,4 +69,3 @@ TEST_CASE("message queue should make copy of data") {
|
||||
CHECK_EQ(queue.get(&queue_number, 100), true);
|
||||
CHECK_EQ(queue_number, test_value);
|
||||
}
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
#include "doctest.h"
|
||||
#include <Tactility/TactilityCore.h>
|
||||
#include <Tactility/kernel/Kernel.h>
|
||||
#include <Tactility/Mutex.h>
|
||||
#include <Tactility/Thread.h>
|
||||
|
||||
using namespace tt;
|
||||
|
||||
TEST_CASE("a mutex can block a thread") {
|
||||
TEST_CASE("a Mutex can block a thread") {
|
||||
auto mutex = Mutex();
|
||||
mutex.lock(portMAX_DELAY);
|
||||
CHECK_EQ(mutex.lock(kernel::MAX_TICKS), true);
|
||||
|
||||
Thread thread = Thread(
|
||||
"thread",
|
||||
1024,
|
||||
[&mutex]() {
|
||||
mutex.lock(portMAX_DELAY);
|
||||
[&mutex] {
|
||||
mutex.lock(kernel::MAX_TICKS);
|
||||
return 0;
|
||||
}
|
||||
);
|
||||
@@ -33,17 +34,5 @@ TEST_CASE("a Mutex can be locked exactly once") {
|
||||
Mutex mutex;
|
||||
CHECK_EQ(mutex.lock(0), true);
|
||||
CHECK_EQ(mutex.lock(0), false);
|
||||
CHECK_EQ(mutex.unlock(), true);
|
||||
}
|
||||
|
||||
TEST_CASE("unlocking a Mutex without locking returns false") {
|
||||
Mutex mutex;
|
||||
CHECK_EQ(mutex.unlock(), false);
|
||||
}
|
||||
|
||||
TEST_CASE("unlocking a Mutex twice returns false on the second attempt") {
|
||||
Mutex mutex;
|
||||
CHECK_EQ(mutex.lock(0), true);
|
||||
CHECK_EQ(mutex.unlock(), true);
|
||||
CHECK_EQ(mutex.unlock(), false);
|
||||
mutex.unlock();
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "doctest.h"
|
||||
#include <Tactility/TactilityCore.h>
|
||||
#include <Tactility/PubSub.h>
|
||||
|
||||
using namespace tt;
|
||||
@@ -18,6 +17,8 @@ TEST_CASE("PubSub subscription receives published data") {
|
||||
});
|
||||
pubsub.publish(1);
|
||||
|
||||
pubsub.unsubscribe(subscription);
|
||||
|
||||
CHECK_EQ(value, 1);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
#include "doctest.h"
|
||||
#include <Tactility/kernel/Kernel.h>
|
||||
#include <Tactility/RecursiveMutex.h>
|
||||
#include <Tactility/Thread.h>
|
||||
|
||||
using namespace tt;
|
||||
|
||||
TEST_CASE("a RecursiveMutex can block a thread") {
|
||||
auto mutex = RecursiveMutex();
|
||||
CHECK_EQ(mutex.lock(kernel::MAX_TICKS), true);
|
||||
|
||||
Thread thread = Thread(
|
||||
"thread",
|
||||
1024,
|
||||
[&mutex] {
|
||||
mutex.lock(kernel::MAX_TICKS);
|
||||
return 0;
|
||||
}
|
||||
);
|
||||
thread.start();
|
||||
|
||||
kernel::delayMillis(5);
|
||||
CHECK_EQ(thread.getState(), Thread::State::Running);
|
||||
|
||||
mutex.unlock();
|
||||
|
||||
kernel::delayMillis(5);
|
||||
CHECK_EQ(thread.getState(), Thread::State::Stopped);
|
||||
|
||||
thread.join();
|
||||
}
|
||||
|
||||
TEST_CASE("a RecursiveMutex can be locked more than once from the same context") {
|
||||
RecursiveMutex mutex;
|
||||
CHECK_EQ(mutex.lock(0), true);
|
||||
CHECK_EQ(mutex.lock(0), true);
|
||||
mutex.unlock();
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "doctest.h"
|
||||
#include <Tactility/TactilityCore.h>
|
||||
#include <Tactility/Thread.h>
|
||||
|
||||
using namespace tt;
|
||||
@@ -54,12 +53,12 @@ TEST_CASE("thread id should only be set at when thread is started") {
|
||||
return 0;
|
||||
}
|
||||
);
|
||||
CHECK_EQ(thread->getId(), nullptr);
|
||||
CHECK_EQ(thread->getTaskHandle(), nullptr);
|
||||
thread->start();
|
||||
CHECK_NE(thread->getId(), nullptr);
|
||||
CHECK_NE(thread->getTaskHandle(), nullptr);
|
||||
interrupted = true;
|
||||
thread->join();
|
||||
CHECK_EQ(thread->getId(), nullptr);
|
||||
CHECK_EQ(thread->getTaskHandle(), nullptr);
|
||||
delete thread;
|
||||
}
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
#include "doctest.h"
|
||||
#include <Tactility/TactilityCore.h>
|
||||
#include <Tactility/Timer.h>
|
||||
|
||||
using namespace tt;
|
||||
|
||||
TEST_CASE("TimerType::Periodic timers can be stopped and restarted") {
|
||||
int counter = 0;
|
||||
auto* timer = new Timer(Timer::Type::Periodic, [&counter]() { counter++; });
|
||||
timer->start(1);
|
||||
auto* timer = new Timer(Timer::Type::Periodic, 1, [&counter] { counter++; });
|
||||
CHECK_EQ(timer->start(), true);
|
||||
kernel::delayTicks(10);
|
||||
timer->stop();
|
||||
timer->start(1);
|
||||
CHECK_EQ(timer->stop(), true);
|
||||
CHECK_EQ(timer->start(), true);
|
||||
kernel::delayTicks(10);
|
||||
timer->stop();
|
||||
CHECK_EQ(timer->stop(), true);
|
||||
delete timer;
|
||||
|
||||
CHECK_GE(counter, 2);
|
||||
@@ -21,10 +20,10 @@ TEST_CASE("TimerType::Periodic timers can be stopped and restarted") {
|
||||
TEST_CASE("TimerType::Periodic calls the callback periodically") {
|
||||
int ticks_to_run = 10;
|
||||
int counter = 0;
|
||||
auto* timer = new Timer(Timer::Type::Periodic, [&counter]() { counter++; });
|
||||
timer->start(1);
|
||||
auto* timer = new Timer(Timer::Type::Periodic, 1, [&counter] { counter++; });
|
||||
CHECK_EQ(timer->start(), true);
|
||||
kernel::delayTicks(ticks_to_run);
|
||||
timer->stop();
|
||||
CHECK_EQ(timer->stop(), true);
|
||||
delete timer;
|
||||
|
||||
CHECK_EQ(counter, ticks_to_run);
|
||||
@@ -32,13 +31,13 @@ TEST_CASE("TimerType::Periodic calls the callback periodically") {
|
||||
|
||||
TEST_CASE("restarting TimerType::Once timers calls the callback again") {
|
||||
int counter = 0;
|
||||
auto* timer = new Timer(Timer::Type::Once, [&counter]() { counter++; });
|
||||
timer->start(1);
|
||||
auto* timer = new Timer(Timer::Type::Once, 1, [&counter] { counter++; });
|
||||
CHECK_EQ(timer->start(), true);
|
||||
kernel::delayTicks(10);
|
||||
timer->stop();
|
||||
timer->start(1);
|
||||
CHECK_EQ(timer->stop(), true);
|
||||
CHECK_EQ(timer->start(), true);
|
||||
kernel::delayTicks(10);
|
||||
timer->stop();
|
||||
CHECK_EQ(timer->stop(), true);
|
||||
delete timer;
|
||||
|
||||
CHECK_EQ(counter, 2);
|
||||
Reference in New Issue
Block a user