Create TactilityFreertos subproject (#440)

This commit is contained in:
Ken Van Hoeylandt
2026-01-03 00:19:40 +01:00
committed by GitHub
parent a4dc633063
commit 7283920def
154 changed files with 1926 additions and 2676 deletions
+2
View File
@@ -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)
+1
View File
@@ -20,5 +20,6 @@ add_test(NAME TactilityCoreTests
target_link_libraries(TactilityCoreTests PUBLIC
TactilityCore
TactilityFreeRtos
freertos_kernel
)
+2
View File
@@ -48,6 +48,8 @@ int main(int argc, char** argv) {
assert(task_result == pdPASS);
vTaskStartScheduler();
return data.result;
}
extern "C" {
+24
View File
@@ -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,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();
}
+60
View File
@@ -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, "");
}
}
@@ -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);