Added first implementation

This commit is contained in:
dario 2024-01-07 00:41:32 +01:00
parent b41426feaf
commit 5681411c65
13 changed files with 418 additions and 0 deletions

29
include/sta/config.hpp Normal file
View File

@ -0,0 +1,29 @@
/*
* config.hpp
*
* Created on: Dec 31, 2023
* Author: Dario
*/
#ifndef STA_CONFIG_HPP
#define STA_CONFIG_HPP
#include <sta/devices/stm32/mcu/STM32F411xE.hpp>
// Doesn't really do too much right now. Has to be added for successful compilation.
#define STA_PRINTF_USE_STDLIB
// Enable debug serial output and assertions.
#define STA_ASSERT_FORCE
#define STA_DEBUGGING_ENABLED
// Settings for the rtos-utils
#define STA_RTOS_SYSTEM_EVENTS_ENABLE
// Use the default configs for TACOS
#include <sta/tacos/configs/default.hpp>
#define STA_TACOS_WATCHDOG_FREQUENCY 1000
#define STA_TACOS_NUM_STATES 3
#endif // STA_CONFIG_HPP

View File

@ -0,0 +1,6 @@
#ifndef STA_TASTY_CONFIG_HPP
#define STA_TASTY_CONFIG_HPP
#define TASTY_CASE_1
#endif // STA_TASTY_CONFIG_HPP

View File

@ -0,0 +1,26 @@
/*
* Dummy.hpp
*
* Created on: Dec 31, 2023
* Author: Dario
*/
#ifndef INCLUDE_TASKS_DUMMY_HPP_
#define INCLUDE_TASKS_DUMMY_HPP_
#include <sta/tacos/thread.hpp>
namespace demo
{
class DummyThread : public sta::tacos::TacosThread
{
public:
DummyThread(const char* name);
void init() override;
void func() override;
};
}
#endif /* INCLUDE_TASKS_DUMMY_HPP_ */

View File

@ -0,0 +1,37 @@
/*
* supervisor.hpp
*
* Created on: Jan 6, 2024
* Author: Dario
*/
#ifndef STA_TASTY_TASKS_SUPERVISOR_HPP
#define STA_TASTY_TASKS_SUPERVISOR_HPP
#include <sta/tacos/thread.hpp>
#include <list>
#include <functional>
namespace sta
{
namespace tasty
{
typedef std::function<void(void)> TastyCheck;
class Supervisor : public tacos::TacosThread
{
public:
Supervisor(std::list<TastyCheck> checks);
void func() override;
private:
std::list<TastyCheck> checks_;
};
} // namespace tasty
} // namespace sta
#endif // STA_TASTY_TASKS_SUPERVISOR_HPP

View File

@ -0,0 +1,32 @@
/*
* toggle.hpp
*
* Created on: Jan 1, 2024
* Author: Dario
*/
#ifndef INCLUDE_TASKS_TOGGLE_HPP_
#define INCLUDE_TASKS_TOGGLE_HPP_
#include <sta/tacos/thread.hpp>
namespace sta
{
namespace tasty
{
class ToggleThread : public sta::tacos::TacosThread
{
public:
ToggleThread(uint32_t ticks, uint32_t lockout = 0, const char* name = "toggle");
void init() override;
void func() override;
private:
uint32_t ticks_;
uint32_t lockout_;
};
} // namespace tasty
} // namespace sta
#endif /* INCLUDE_TASKS_TOGGLE_HPP_ */

View File

@ -0,0 +1,34 @@
#ifndef STA_TASTY_UTILS_HPP
#define STA_TASTY_UTILS_HPP
#include <sta/config.hpp>
#ifdef STA_DEBUGGING_ENABLED
#include <cstdint>
namespace sta
{
namespace tasty
{
/**
* @brief Print a test result via serial.
*
* @param file The file the test case was in.
* @param line The line of the test case.
* @param rslt The result of the test case.
*/
void test_case(const char * file, uint32_t line, bool rslt);
} // namespace tasty
} // namespace sta
/**
* @brief Assert statement for automatic testing using tasty. Sends the test result to the host via serial.
*
*/
#define STA_TASTY_ASSERT(expr) ( (void)( sta::tasty::test_case(__FILE__, __LINE__, expr) ) )
#endif // STA_DEBUGGING_ENABLED
#endif // STA_TASTY_UTILS_HPP

81
src/cases/case1.cpp Normal file
View File

@ -0,0 +1,81 @@
/**
* A simple testcase that checks if threads are correctly terminated after state transitions
* by creating the following threads:
*
* - DummyThread: A thread that does nothing and runs only for state 0.
* - ToggleThread: A thread that switches between states 0 and 1.
* - Supervisor: A thread which supervises the system's behavior.
*
* This test case fails if Dummy doesn't run in state 0 or runs in state 1.
*/
#include <sta/tasty/config.hpp>
#ifdef TASTY_CASE_1
#include <memory>
#include <sta/tacos.hpp>
#include <sta/debug/debug.hpp>
#include <sta/tasty/utils.hpp>
#include <sta/tasty/tasks/toggle.hpp>
#include <sta/tasty/tasks/supervisor.hpp>
namespace sta
{
namespace tasty
{
class DummyThread : public tacos::TacosThread
{
public:
DummyThread()
: tacos::TacosThread("Dummy", osPriorityNormal)
{}
void func() override
{
// Nothing to do here.
}
};
/**
* @brief Global pointer to the dummy thread.
*
*/
std::shared_ptr<DummyThread> dummy;
/**
* @brief Checker function that is called repeatedly by the supervisor thread.
*
*/
void checkDummy()
{
// Wait for the next state change to happen
tacos::Statemachine::stateChangeEvent.wait(tacos::EventFlags::ALL, osWaitForever);
// Wait a little bit longer because Dummy needs time to terminate.
osDelay(10);
// Test if dummy is only running if the state is 0.
if (tacos::getState() == 0)
{
STA_TASTY_ASSERT(dummy->isRunning());
}
else
{
STA_TASTY_ASSERT(!dummy->isRunning());
}
}
void onTastyInit()
{
std::list<TastyCheck> checks = { &checkDummy };
dummy = tacos::addThread<DummyThread>({0});
tacos::addThread<Supervisor>({0, 1}, checks);
tacos::addThread<ToggleThread>({0, 1}, 1000);
}
}
} // namespace sta
#endif // TASTY_CASE_1

18
src/cases/case2.cpp Normal file
View File

@ -0,0 +1,18 @@
#include <sta/tasty/config.hpp>
#ifdef TASTY_CASE_2
#include <sta/tacos.hpp>
namespace sta
{
namespace tasty
{
void onTastyInit()
{
}
} // namespace tasty
} // namespace sta
#endif // TASTY_CASE_2

32
src/startup.cpp Normal file
View File

@ -0,0 +1,32 @@
/*
* startup.cpp
*
* Created on: Jan 6, 2024
* Author: Dario
*/
#include <sta/tacos.hpp>
#include <sta/lang.hpp>
#include <sta/debug/debug.hpp>
#include <sta/tasty/utils.hpp>
namespace sta
{
namespace tasty
{
STA_WEAK
void onTastyInit()
{
}
}
namespace tacos
{
void onManagerInit()
{
tasty::onTastyInit();
}
} // namespace tacos
} // namespace sta

32
src/tasks/dummy.cpp Normal file
View File

@ -0,0 +1,32 @@
/*
* dummy.cpp
*
* Created on: 22 Sep 2023
* Author: Dario
*/
#include <sta/tasty/tasks/dummy.hpp>
#include <sta/debug/debug.hpp>
#include <cmsis_os2.h>
namespace demo
{
DummyThread::DummyThread(const char* name)
: sta::tacos::TacosThread(name, osPriorityNormal)
{
}
void DummyThread::init()
{
STA_DEBUG_PRINTF("Thread %s was initialized", this->getName());
}
void DummyThread::func()
{
STA_DEBUG_PRINTLN(this->getName());
osDelay(1000);
}
} // namespace demo

27
src/tasks/supervisor.cpp Normal file
View File

@ -0,0 +1,27 @@
#include <sta/tasty/tasks/supervisor.hpp>
#include <list>
#include <functional>
namespace sta
{
namespace tasty
{
Supervisor::Supervisor(std::list<TastyCheck> checks)
: tacos::TacosThread{"Supervisor", osPriorityNormal},
checks_{checks}
{}
void Supervisor::func()
{
for (TastyCheck check : checks_)
{
blocking(
check();
);
}
}
} // namespace tasty
} // namespace sta

46
src/tasks/toggle.cpp Normal file
View File

@ -0,0 +1,46 @@
/*
* toggle.cpp
*
* Created on: Jan 1, 2024
* Author: Dario
*/
#include <sta/tasty/tasks/toggle.hpp>
#include <sta/tacos.hpp>
namespace sta
{
namespace tasty
{
ToggleThread::ToggleThread(uint32_t ticks, uint32_t lockout /* = 0 */, const char* name /* = "toggle" */)
: sta::tacos::TacosThread(name, osPriorityNormal),
ticks_{ticks},
lockout_{lockout}
{
}
void ToggleThread::init()
{
}
void ToggleThread::func()
{
blocking(
this->sleep(ticks_);
)
uint16_t state = sta::tacos::getState();
uint16_t next = 1 - state;
sta::tacos::setState(state, next, lockout_);
}
} // namespace tasty
} // namespace sta

18
src/utils.cpp Normal file
View File

@ -0,0 +1,18 @@
#include <sta/tasty/utils.hpp>
#ifdef STA_DEBUGGING_ENABLED
#include <sta/debug/debug.hpp>
namespace sta
{
namespace tasty
{
void test_case(const char * file, uint32_t line, bool rslt)
{
STA_DEBUG_PRINTF("[%s|%d|%d]", file, line, rslt);
}
} // namespace tasty
} // namespace sta
#endif // STA_DEBUGGING_ENABLED