using new xTaskDelayUntil

This commit is contained in:
Robin Müller 2020-12-14 23:55:54 +01:00
parent b8f4d8690b
commit 0c3e87f1de
11 changed files with 98 additions and 92 deletions

View File

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

View File

@ -90,6 +90,7 @@ protected:
TaskHandle_t handle; TaskHandle_t handle;
}; };
#endif #endif /* (tskKERNEL_VERSION_MAJOR == 8 && tskKERNEL_VERSION_MINOR > 2) || \
tskKERNEL_VERSION_MAJOR > 8 */
#endif /* FSFW_OSAL_FREERTOS_BINSEMAPHUSINGTASK_H_ */ #endif /* FSFW_OSAL_FREERTOS_BINSEMAPHUSINGTASK_H_ */

View File

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

View File

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

View File

@ -114,38 +114,24 @@ void FixedTimeslotTask::taskFunctionality() {
intervalMs = this->pst.getIntervalToPreviousSlotMs(); intervalMs = this->pst.getIntervalToPreviousSlotMs();
interval = pdMS_TO_TICKS(intervalMs); interval = pdMS_TO_TICKS(intervalMs);
checkMissedDeadline(xLastWakeTime, interval); #if (tskKERNEL_VERSION_MAJOR == 10 && tskKERNEL_VERSION_MINOR >= 4) || \
tskKERNEL_VERSION_MAJOR > 10
// Wait for the interval. This exits immediately if a deadline was BaseType_t wasDelayed = xTaskDelayUntil(&xLastWakeTime, interval);
// missed while also updating the last wake time. if(wasDelayed == pdFALSE) {
vTaskDelayUntil(&xLastWakeTime, interval); 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() { void FixedTimeslotTask::handleMissedDeadline() {
if(deadlineMissedFunc != nullptr) { if(deadlineMissedFunc != nullptr) {
this->deadlineMissedFunc(); this->deadlineMissedFunc();

View File

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

View File

@ -1,13 +1,41 @@
#ifndef FRAMEWORK_OSAL_FREERTOS_FREERTOSTASKIF_H_ #ifndef FSFW_OSAL_FREERTOS_FREERTOSTASKIF_H_
#define FRAMEWORK_OSAL_FREERTOS_FREERTOSTASKIF_H_ #define FSFW_OSAL_FREERTOS_FREERTOSTASKIF_H_
#include <freertos/FreeRTOS.h> #include <freertos/FreeRTOS.h>
#include <freertos/task.h> #include <freertos/task.h>
class FreeRTOSTaskIF { class FreeRTOSTaskIF {
public: public:
virtual~ FreeRTOSTaskIF() {} virtual~ FreeRTOSTaskIF() {}
virtual TaskHandle_t getTaskHandle() = 0; 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

@ -87,7 +87,9 @@ void PeriodicTask::taskFunctionality() {
handleMissedDeadline(); handleMissedDeadline();
} }
#else #else
checkMissedDeadline(xLastWakeTime, xPeriod); if(checkMissedDeadline(xLastWakeTime, xPeriod)) {
handleMissedDeadline();
}
vTaskDelayUntil(&xLastWakeTime, xPeriod); vTaskDelayUntil(&xLastWakeTime, xPeriod);
#endif #endif
} }
@ -111,30 +113,6 @@ uint32_t PeriodicTask::getPeriodMs() const {
return period * 1000; 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() { TaskHandle_t PeriodicTask::getTaskHandle() {
return handle; return handle;
} }

View File

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

View File

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

View File

@ -26,38 +26,37 @@ enum class CallContext {
}; };
class TaskManagement { namespace TaskManagement {
public: /**
/** * @brief In this function, a function dependant on the portmacro.h header
* @brief In this function, a function dependant on the portmacro.h header * function calls to request a context switch can be specified.
* 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
* This can be used if sending to the queue from an ISR caused a task * to unblock and a context switch is required.
* to unblock and a context switch is required. */
*/ void requestContextSwitch(CallContext callContext);
static void requestContextSwitch(CallContext callContext);
/** /**
* If task preemption in FreeRTOS is disabled, a context switch * If task preemption in FreeRTOS is disabled, a context switch
* can be requested manually by calling this function. * can be requested manually by calling this function.
*/ */
static void vRequestContextSwitchFromTask(void); void vRequestContextSwitchFromTask(void);
/** /**
* @return The current task handle * @return The current task handle
*/ */
static TaskHandle_t getCurrentTaskHandle(); 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_ */ #endif /* FRAMEWORK_OSAL_FREERTOS_TASKMANAGEMENT_H_ */