implemented deadlien missed print for host
This commit is contained in:
parent
078116c7be
commit
e3c44fd27f
@ -10,6 +10,7 @@
|
||||
|
||||
#if defined(WIN32)
|
||||
#include <processthreadsapi.h>
|
||||
#include <fsfw/osal/windows/winTaskHelpers.h>
|
||||
#elif defined(LINUX)
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
@ -22,33 +23,11 @@ PeriodicTask::PeriodicTask(const char *name, TaskPriority setPriority,
|
||||
// It is propably possible to set task priorities by using the native
|
||||
// task handles for Windows / Linux
|
||||
mainThread = std::thread(&PeriodicTask::taskEntryPoint, this, this);
|
||||
#if defined(WIN32)
|
||||
/* List of possible priority classes:
|
||||
* https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/
|
||||
* nf-processthreadsapi-setpriorityclass
|
||||
* And respective thread priority numbers:
|
||||
* https://docs.microsoft.com/en-us/windows/
|
||||
* win32/procthread/scheduling-priorities */
|
||||
int result = SetPriorityClass(
|
||||
reinterpret_cast<HANDLE>(mainThread.native_handle()),
|
||||
ABOVE_NORMAL_PRIORITY_CLASS);
|
||||
if(result != 0) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "PeriodicTask: Windows SetPriorityClass failed with code "
|
||||
<< GetLastError() << std::endl;
|
||||
#endif
|
||||
}
|
||||
result = SetThreadPriority(
|
||||
reinterpret_cast<HANDLE>(mainThread.native_handle()),
|
||||
THREAD_PRIORITY_NORMAL);
|
||||
if(result != 0) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "PeriodicTask: Windows SetPriorityClass failed with code "
|
||||
<< GetLastError() << std::endl;
|
||||
#endif
|
||||
}
|
||||
#elif defined(LINUX)
|
||||
// we can just copy and paste the code from linux here.
|
||||
#if defined(_WIN32)
|
||||
tasks::setTaskPriority(reinterpret_cast<HANDLE>(mainThread.native_handle()), setPriority);
|
||||
tasks::insertTaskName(mainThread.get_id(), taskName);
|
||||
#elif defined(__unix__)
|
||||
// TODO: We could reuse existing code here.
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,20 @@
|
||||
#include "../../tasks/TaskFactory.h"
|
||||
#include "../../osal/host/FixedTimeslotTask.h"
|
||||
#include "../../osal/host/PeriodicTask.h"
|
||||
#include "../../tasks/TaskFactory.h"
|
||||
#include "../../returnvalues/HasReturnvaluesIF.h"
|
||||
#include "../../tasks/PeriodicTaskIF.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include "../windows/winTaskHelpers.h"
|
||||
|
||||
#endif
|
||||
|
||||
#include <chrono>
|
||||
|
||||
TaskFactory* TaskFactory::factoryInstance = new TaskFactory();
|
||||
|
||||
// Will propably not be used for hosted implementation
|
||||
// Not used for the host implementation for now because C++ thread abstraction is used
|
||||
const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = 0;
|
||||
|
||||
TaskFactory::TaskFactory() {
|
||||
@ -49,8 +55,33 @@ ReturnValue_t TaskFactory::delayTask(uint32_t delayMs){
|
||||
}
|
||||
|
||||
void TaskFactory::printMissedDeadline() {
|
||||
/* TODO: Implement */
|
||||
return;
|
||||
#ifdef __unix__
|
||||
char name[20] = {0};
|
||||
int status = pthread_getname_np(pthread_self(), name, sizeof(name));
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
if(status == 0) {
|
||||
sif::warning << "TaskFactory::printMissedDeadline: " << name << "" << std::endl;
|
||||
}
|
||||
else {
|
||||
sif::warning << "TaskFactory::printMissedDeadline: Unknown task name" << status <<
|
||||
std::endl;
|
||||
}
|
||||
#else
|
||||
if(status == 0) {
|
||||
sif::printWarning("TaskFactory::printMissedDeadline: %s\n", name);
|
||||
}
|
||||
else {
|
||||
sif::printWarning("TaskFactory::printMissedDeadline: Unknown task name\n", name);
|
||||
}
|
||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
||||
#elif defined(_WIN32)
|
||||
std::string name = tasks::getTaskName(std::this_thread::get_id());
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "TaskFactory::printMissedDeadline: " << name << std::endl;
|
||||
#else
|
||||
sif::printWarning("TaskFactory::printMissedDeadline: %s\n", name);
|
||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
||||
#endif /* defined(_WIN32) */
|
||||
}
|
||||
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include <errno.h>
|
||||
|
||||
PosixThread::PosixThread(const char* name_, int priority_, size_t stackSize_):
|
||||
thread(0),priority(priority_),stackSize(stackSize_) {
|
||||
thread(0), priority(priority_), stackSize(stackSize_) {
|
||||
name[0] = '\0';
|
||||
std::strncat(name, name_, PTHREAD_MAX_NAMELEN - 1);
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
target_sources(${LIB_FSFW_NAME} PRIVATE
|
||||
tcpipHelpers.cpp
|
||||
winTaskHelpers.cpp
|
||||
)
|
||||
|
130
osal/windows/winTaskHelpers.cpp
Normal file
130
osal/windows/winTaskHelpers.cpp
Normal file
@ -0,0 +1,130 @@
|
||||
#include <fsfw/osal/windows/winTaskHelpers.h>
|
||||
#include <mutex>
|
||||
|
||||
std::mutex nameMapLock;
|
||||
std::map<std::thread::id, std::string> taskNameMap;
|
||||
|
||||
TaskPriority tasks::makeWinPriority(PriorityClass prioClass, PriorityNumber prioNumber) {
|
||||
return (static_cast<uint16_t>(prioClass) << 16) | static_cast<uint16_t> (prioNumber);
|
||||
}
|
||||
|
||||
void tasks::getWinPriorityParameters(TaskPriority priority,
|
||||
DWORD& priorityClass, int& priorityNumber) {
|
||||
PriorityClass classInternal = static_cast<PriorityClass>(priority >> 16 & 0xff);
|
||||
PriorityNumber numberInternal = static_cast<PriorityNumber>(priority & 0xff);
|
||||
switch(classInternal) {
|
||||
case(CLASS_IDLE): {
|
||||
priorityClass = IDLE_PRIORITY_CLASS;
|
||||
break;
|
||||
}
|
||||
case(CLASS_BELOW_NORMAL): {
|
||||
priorityClass = BELOW_NORMAL_PRIORITY_CLASS;
|
||||
break;
|
||||
}
|
||||
case(CLASS_NORMAL): {
|
||||
priorityClass = NORMAL_PRIORITY_CLASS;
|
||||
break;
|
||||
}
|
||||
case(CLASS_ABOVE_NORMAL): {
|
||||
priorityClass = ABOVE_NORMAL_PRIORITY_CLASS;
|
||||
break;
|
||||
}
|
||||
case(CLASS_HIGH): {
|
||||
priorityClass = HIGH_PRIORITY_CLASS;
|
||||
break;
|
||||
}
|
||||
case(CLASS_REALTIME): {
|
||||
priorityClass = REALTIME_PRIORITY_CLASS;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
priorityClass = NORMAL_PRIORITY_CLASS;
|
||||
}
|
||||
}
|
||||
|
||||
switch(numberInternal) {
|
||||
case(IDLE): {
|
||||
priorityNumber = THREAD_PRIORITY_IDLE;
|
||||
break;
|
||||
}
|
||||
case(LOWEST): {
|
||||
priorityNumber = THREAD_PRIORITY_LOWEST;
|
||||
break;
|
||||
}
|
||||
case(BELOW_NORMAL): {
|
||||
priorityNumber = THREAD_PRIORITY_BELOW_NORMAL;
|
||||
break;
|
||||
}
|
||||
case(NORMAL): {
|
||||
priorityNumber = THREAD_PRIORITY_NORMAL;
|
||||
break;
|
||||
}
|
||||
case(ABOVE_NORMAL): {
|
||||
priorityNumber = THREAD_PRIORITY_ABOVE_NORMAL;
|
||||
break;
|
||||
}
|
||||
case(HIGHEST): {
|
||||
priorityNumber = THREAD_PRIORITY_HIGHEST;
|
||||
break;
|
||||
}
|
||||
case(CRITICAL): {
|
||||
priorityNumber = THREAD_PRIORITY_TIME_CRITICAL;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
priorityNumber = THREAD_PRIORITY_NORMAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t tasks::setTaskPriority(HANDLE nativeHandle, TaskPriority priority) {
|
||||
/* List of possible priority classes:
|
||||
https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setpriorityclass
|
||||
And respective thread priority numbers:
|
||||
https://docs.microsoft.com/en-us/windows/win32/procthread/scheduling-priorities
|
||||
*/
|
||||
DWORD dwPriorityClass = 0;
|
||||
int nPriorityNumber = 0;
|
||||
tasks::getWinPriorityParameters(priority, dwPriorityClass, nPriorityNumber);
|
||||
int result = SetPriorityClass(
|
||||
reinterpret_cast<HANDLE>(nativeHandle),
|
||||
dwPriorityClass);
|
||||
if(result != 0) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "PeriodicTask: Windows SetPriorityClass failed with code "
|
||||
<< GetLastError() << std::endl;
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
#endif
|
||||
}
|
||||
result = SetThreadPriority(
|
||||
reinterpret_cast<HANDLE>(nativeHandle),
|
||||
nPriorityNumber);
|
||||
if(result != 0) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "PeriodicTask: Windows SetPriorityClass failed with code "
|
||||
<< GetLastError() << std::endl;
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
#endif
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t tasks::insertTaskName(std::thread::id threadId, std::string taskName) {
|
||||
std::lock_guard<std::mutex> lg(nameMapLock);
|
||||
auto returnPair = taskNameMap.emplace(threadId, taskName);
|
||||
if(not returnPair.second) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
std::string tasks::getTaskName(std::thread::id threadId) {
|
||||
std::lock_guard<std::mutex> lg(nameMapLock);
|
||||
auto resultIter = taskNameMap.find(threadId);
|
||||
if(resultIter != taskNameMap.end()) {
|
||||
return resultIter->second;
|
||||
}
|
||||
else {
|
||||
return "Unknown task";
|
||||
}
|
||||
}
|
40
osal/windows/winTaskHelpers.h
Normal file
40
osal/windows/winTaskHelpers.h
Normal file
@ -0,0 +1,40 @@
|
||||
#include "../../tasks/TaskFactory.h"
|
||||
|
||||
#include <thread>
|
||||
#include <map>
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
namespace tasks {
|
||||
|
||||
enum PriorityClass: uint16_t {
|
||||
CLASS_IDLE,
|
||||
CLASS_BELOW_NORMAL,
|
||||
CLASS_NORMAL,
|
||||
CLASS_ABOVE_NORMAL,
|
||||
CLASS_HIGH,
|
||||
CLASS_REALTIME
|
||||
};
|
||||
enum PriorityNumber: uint16_t {
|
||||
IDLE,
|
||||
LOWEST,
|
||||
BELOW_NORMAL,
|
||||
NORMAL,
|
||||
ABOVE_NORMAL,
|
||||
HIGHEST,
|
||||
CRITICAL
|
||||
};
|
||||
TaskPriority makeWinPriority(PriorityClass prioClass = PriorityClass::CLASS_NORMAL,
|
||||
PriorityNumber prioNumber = PriorityNumber::NORMAL);
|
||||
void getWinPriorityParameters(TaskPriority priority, DWORD& priorityClass,
|
||||
int& priorityNumber);
|
||||
|
||||
ReturnValue_t setTaskPriority(HANDLE nativeHandle, TaskPriority priority);
|
||||
|
||||
ReturnValue_t insertTaskName(std::thread::id threadId, std::string taskName);
|
||||
std::string getTaskName(std::thread::id threadId);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -22,9 +22,23 @@ public:
|
||||
/**
|
||||
* Creates a new periodic task and returns the interface pointer.
|
||||
* @param name_ Name of the task
|
||||
* @param taskPriority_ Priority of the task
|
||||
* @param taskPriority_
|
||||
* Priority of the task. This value might have different ranges for the various OSALs.
|
||||
* Linux: Value ranging from 0 to 99 with 99 being the highest value.
|
||||
* Host: Value can be retrieved by using the #tasks::makeWinPriority function.
|
||||
* FreeRTOS: Value depends on the FreeRTOS configuration, higher number means higher priority
|
||||
* RTEMS: Values ranging from 0 to 99 with 99 being the highest value.
|
||||
*
|
||||
* @param stackSize_ Stack Size of the task
|
||||
* This value might have different recommended ranges for the various OSALs.
|
||||
* Linux: Lowest limit is the PeriodicTaskIF::MINIMUM_STACK_SIZE value
|
||||
* Host: Value is ignored for now because the C++ threading abstraction layer is used.
|
||||
* FreeRTOS: Stack size in bytes. It is recommended to specify at least 1kB of stack for
|
||||
* FSFW tasks, but the lowest possible size is specified in the FreeRTOSConfig.h file.
|
||||
* RTEMS: Lowest limit is the PeriodicTaskIF::MINIMUM_STACK_SIZE value.
|
||||
*
|
||||
* @param period_ Period of the task
|
||||
*
|
||||
* @param deadLineMissedFunction_ Function to be called if a deadline was missed
|
||||
* @return PeriodicTaskIF* Pointer to the newly created Task
|
||||
*/
|
||||
|
@ -2,7 +2,7 @@
|
||||
#define FRAMEWORK_TASKS_TYPEDEF_H_
|
||||
|
||||
typedef const char* TaskName;
|
||||
typedef uint8_t TaskPriority;
|
||||
typedef uint32_t TaskPriority;
|
||||
typedef size_t TaskStackSize;
|
||||
typedef double TaskPeriod;
|
||||
typedef void (*TaskDeadlineMissedFunction)();
|
||||
|
Loading…
Reference in New Issue
Block a user