changes from mueller/master taken over

This commit is contained in:
Robin Müller 2020-12-14 23:56:44 +01:00
parent 313d898aef
commit 3cc053a581
11 changed files with 111 additions and 95 deletions

View File

@ -2,6 +2,9 @@
#include "TaskManagement.h"
#include "../../serviceinterface/ServiceInterfaceStream.h"
#if (tskKERNEL_VERSION_MAJOR == 8 && tskKERNEL_VERSION_MINOR > 2) || \
tskKERNEL_VERSION_MAJOR > 8
BinarySemaphoreUsingTask::BinarySemaphoreUsingTask() {
handle = TaskManagement::getCurrentTaskHandle();
if(handle == nullptr) {
@ -97,3 +100,6 @@ uint8_t BinarySemaphoreUsingTask::getSemaphoreCounterFromISR(
higherPriorityTaskWoken);
return notificationValue;
}
#endif /* (tskKERNEL_VERSION_MAJOR == 8 && tskKERNEL_VERSION_MINOR > 2) || \
tskKERNEL_VERSION_MAJOR > 8 */

View File

@ -7,8 +7,8 @@
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
// todo: does not work for older FreeRTOS version, so we should
// actually check whether tskKERNEL_VERSION_MAJOR is larger than.. 7 or 8 ?
#if (tskKERNEL_VERSION_MAJOR == 8 && tskKERNEL_VERSION_MINOR > 2) || \
tskKERNEL_VERSION_MAJOR > 8
/**
* @brief Binary Semaphore implementation using the task notification value.
@ -90,4 +90,7 @@ protected:
TaskHandle_t handle;
};
#endif /* (tskKERNEL_VERSION_MAJOR == 8 && tskKERNEL_VERSION_MINOR > 2) || \
tskKERNEL_VERSION_MAJOR > 8 */
#endif /* FSFW_OSAL_FREERTOS_BINSEMAPHUSINGTASK_H_ */

View File

@ -3,6 +3,9 @@
#include "../../serviceinterface/ServiceInterfaceStream.h"
#if (tskKERNEL_VERSION_MAJOR == 8 && tskKERNEL_VERSION_MINOR > 2) || \
tskKERNEL_VERSION_MAJOR > 8
CountingSemaphoreUsingTask::CountingSemaphoreUsingTask(const uint8_t maxCount,
uint8_t initCount): maxCount(maxCount) {
if(initCount > maxCount) {
@ -113,3 +116,5 @@ uint8_t CountingSemaphoreUsingTask::getSemaphoreCounterFromISR(
uint8_t CountingSemaphoreUsingTask::getMaxCount() const {
return maxCount;
}
#endif

View File

@ -7,6 +7,9 @@
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#if (tskKERNEL_VERSION_MAJOR == 8 && tskKERNEL_VERSION_MINOR > 2) || \
tskKERNEL_VERSION_MAJOR > 8
/**
* @brief Couting Semaphore implementation which uses the notification value
* of the task. The notification value should therefore not be used
@ -100,4 +103,7 @@ private:
const uint8_t maxCount;
};
#endif /* (tskKERNEL_VERSION_MAJOR == 8 && tskKERNEL_VERSION_MINOR > 2) || \
tskKERNEL_VERSION_MAJOR > 8 */
#endif /* FSFW_OSAL_FREERTOS_COUNTINGSEMAPHUSINGTASK_H_ */

View File

@ -114,38 +114,24 @@ void FixedTimeslotTask::taskFunctionality() {
intervalMs = this->pst.getIntervalToPreviousSlotMs();
interval = pdMS_TO_TICKS(intervalMs);
checkMissedDeadline(xLastWakeTime, interval);
// Wait for the interval. This exits immediately if a deadline was
// missed while also updating the last wake time.
vTaskDelayUntil(&xLastWakeTime, interval);
#if (tskKERNEL_VERSION_MAJOR == 10 && tskKERNEL_VERSION_MINOR >= 4) || \
tskKERNEL_VERSION_MAJOR > 10
BaseType_t wasDelayed = xTaskDelayUntil(&xLastWakeTime, interval);
if(wasDelayed == pdFALSE) {
handleMissedDeadline();
}
#else
if(checkMissedDeadline(xLastWakeTime, interval)) {
handleMissedDeadline();
}
// Wait for the interval. This exits immediately if a deadline was
// missed while also updating the last wake time.
vTaskDelayUntil(&xLastWakeTime, interval);
#endif
}
}
}
void FixedTimeslotTask::checkMissedDeadline(const TickType_t xLastWakeTime,
const TickType_t interval) {
/* Check whether deadline was missed while also taking overflows
* into account. Drawing this on paper with a timeline helps to understand
* it. */
TickType_t currentTickCount = xTaskGetTickCount();
TickType_t timeToWake = xLastWakeTime + interval;
// Time to wake has not overflown.
if(timeToWake > xLastWakeTime) {
/* If the current time has overflown exclusively or the current
* tick count is simply larger than the time to wake, a deadline was
* missed */
if((currentTickCount < xLastWakeTime) or (currentTickCount > timeToWake)) {
handleMissedDeadline();
}
}
/* Time to wake has overflown. A deadline was missed if the current time
* is larger than the time to wake */
else if((timeToWake < xLastWakeTime) and (currentTickCount > timeToWake)) {
handleMissedDeadline();
}
}
void FixedTimeslotTask::handleMissedDeadline() {
if(deadlineMissedFunc != nullptr) {
this->deadlineMissedFunc();

View File

@ -93,8 +93,6 @@ protected:
*/
void taskFunctionality(void);
void checkMissedDeadline(const TickType_t xLastWakeTime,
const TickType_t interval);
void handleMissedDeadline();
};

View File

@ -1,13 +1,41 @@
#ifndef FRAMEWORK_OSAL_FREERTOS_FREERTOSTASKIF_H_
#define FRAMEWORK_OSAL_FREERTOS_FREERTOSTASKIF_H_
#ifndef FSFW_OSAL_FREERTOS_FREERTOSTASKIF_H_
#define FSFW_OSAL_FREERTOS_FREERTOSTASKIF_H_
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
class FreeRTOSTaskIF {
public:
virtual~ FreeRTOSTaskIF() {}
virtual TaskHandle_t getTaskHandle() = 0;
virtual~ FreeRTOSTaskIF() {}
virtual TaskHandle_t getTaskHandle() = 0;
protected:
bool checkMissedDeadline(const TickType_t xLastWakeTime,
const TickType_t interval) {
/* Check whether deadline was missed while also taking overflows
* into account. Drawing this on paper with a timeline helps to understand
* it. */
TickType_t currentTickCount = xTaskGetTickCount();
TickType_t timeToWake = xLastWakeTime + interval;
// Time to wake has not overflown.
if(timeToWake > xLastWakeTime) {
/* If the current time has overflown exclusively or the current
* tick count is simply larger than the time to wake, a deadline was
* missed */
if((currentTickCount < xLastWakeTime) or
(currentTickCount > timeToWake)) {
return true;
}
}
/* Time to wake has overflown. A deadline was missed if the current time
* is larger than the time to wake */
else if((timeToWake < xLastWakeTime) and
(currentTickCount > timeToWake)) {
return true;
}
return false;
}
};
#endif /* FRAMEWORK_OSAL_FREERTOS_FREERTOSTASKIF_H_ */
#endif /* FSFW_OSAL_FREERTOS_FREERTOSTASKIF_H_ */

View File

@ -80,10 +80,18 @@ void PeriodicTask::taskFunctionality() {
object->performOperation();
}
checkMissedDeadline(xLastWakeTime, xPeriod);
vTaskDelayUntil(&xLastWakeTime, xPeriod);
#if (tskKERNEL_VERSION_MAJOR == 10 && tskKERNEL_VERSION_MINOR >= 4) || \
tskKERNEL_VERSION_MAJOR > 10
BaseType_t wasDelayed = xTaskDelayUntil(&xLastWakeTime, xPeriod);
if(wasDelayed == pdFALSE) {
handleMissedDeadline();
}
#else
if(checkMissedDeadline(xLastWakeTime, xPeriod)) {
handleMissedDeadline();
}
vTaskDelayUntil(&xLastWakeTime, xPeriod);
#endif
}
}
@ -105,29 +113,6 @@ uint32_t PeriodicTask::getPeriodMs() const {
return period * 1000;
}
void PeriodicTask::checkMissedDeadline(const TickType_t xLastWakeTime,
const TickType_t interval) {
/* Check whether deadline was missed while also taking overflows
* into account. Drawing this on paper with a timeline helps to understand
* it. */
TickType_t currentTickCount = xTaskGetTickCount();
TickType_t timeToWake = xLastWakeTime + interval;
// Time to wake has not overflown.
if(timeToWake > xLastWakeTime) {
/* If the current time has overflown exclusively or the current
* tick count is simply larger than the time to wake, a deadline was
* missed */
if((currentTickCount < xLastWakeTime) or (currentTickCount > timeToWake)) {
handleMissedDeadline();
}
}
/* Time to wake has overflown. A deadline was missed if the current time
* is larger than the time to wake */
else if((timeToWake < xLastWakeTime) and (currentTickCount > timeToWake)) {
handleMissedDeadline();
}
}
TaskHandle_t PeriodicTask::getTaskHandle() {
return handle;
}

View File

@ -71,6 +71,7 @@ public:
TaskHandle_t getTaskHandle() override;
protected:
bool started;
TaskHandle_t handle;
@ -118,8 +119,6 @@ protected:
*/
void taskFunctionality(void);
void checkMissedDeadline(const TickType_t xLastWakeTime,
const TickType_t interval);
void handleMissedDeadline();
};

View File

@ -22,3 +22,4 @@ size_t TaskManagement::getTaskStackHighWatermark(
TaskHandle_t task) {
return uxTaskGetStackHighWaterMark(task) * sizeof(StackType_t);
}

View File

@ -26,38 +26,37 @@ enum class CallContext {
};
class TaskManagement {
public:
/**
* @brief In this function, a function dependant on the portmacro.h header
* function calls to request a context switch can be specified.
* This can be used if sending to the queue from an ISR caused a task
* to unblock and a context switch is required.
*/
static void requestContextSwitch(CallContext callContext);
namespace TaskManagement {
/**
* @brief In this function, a function dependant on the portmacro.h header
* function calls to request a context switch can be specified.
* This can be used if sending to the queue from an ISR caused a task
* to unblock and a context switch is required.
*/
void requestContextSwitch(CallContext callContext);
/**
* If task preemption in FreeRTOS is disabled, a context switch
* can be requested manually by calling this function.
*/
static void vRequestContextSwitchFromTask(void);
/**
* If task preemption in FreeRTOS is disabled, a context switch
* can be requested manually by calling this function.
*/
void vRequestContextSwitchFromTask(void);
/**
* @return The current task handle
*/
static TaskHandle_t getCurrentTaskHandle();
/**
* @return The current task handle
*/
TaskHandle_t getCurrentTaskHandle();
/**
* Get returns the minimum amount of remaining stack space in words
* that was a available to the task since the task started executing.
* Please note that the actual value in bytes depends
* on the stack depth type.
* E.g. on a 32 bit machine, a value of 200 means 800 bytes.
* @return Smallest value of stack remaining since the task was started in
* words.
*/
size_t getTaskStackHighWatermark(TaskHandle_t task = nullptr);
/**
* Get returns the minimum amount of remaining stack space in words
* that was a available to the task since the task started executing.
* Please note that the actual value in bytes depends
* on the stack depth type.
* E.g. on a 32 bit machine, a value of 200 means 800 bytes.
* @return Smallest value of stack remaining since the task was started in
* words.
*/
static size_t getTaskStackHighWatermark(
TaskHandle_t task = nullptr);
};
#endif /* FRAMEWORK_OSAL_FREERTOS_TASKMANAGEMENT_H_ */