continued with hk data pool

added deadline missed check for fixed timeslot task,
improved doc for both periodic task and fixed timeslot task
This commit is contained in:
Robin Müller 2020-06-19 14:25:03 +02:00
parent 84b8d733c0
commit 60ae2d4565
20 changed files with 261 additions and 100 deletions

View File

@ -53,6 +53,10 @@ ReturnValue_t DataSetBase::read(uint32_t lockTimeout) {
return result;
}
uint16_t DataSetBase::getFillCount() const {
return fillCount;
}
ReturnValue_t DataSetBase::readVariable(uint16_t count) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
// These checks are often performed by the respective

View File

@ -101,6 +101,8 @@ public:
*/
virtual ReturnValue_t unlockDataPool() override;
virtual uint16_t getFillCount() const;
/* SerializeIF implementations */
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
const size_t maxSize, bool bigEndian) const override;

View File

@ -43,6 +43,7 @@ public:
*/
virtual ReturnValue_t registerVariable(PoolVariableIF* variable) = 0;
virtual uint16_t getFillCount() const = 0;
private:
/**
* @brief Most underlying data structures will have a pool like structure

View File

@ -33,7 +33,7 @@ LocalDataPoolManager::~LocalDataPoolManager() {}
ReturnValue_t LocalDataPoolManager::initializeHousekeepingPoolEntriesOnce() {
if(not mapInitialized) {
ReturnValue_t result =
owner->initializeHousekeepingPoolEntries(localDpMap);
owner->initializePoolEntries(localDpMap);
if(result == HasReturnvaluesIF::RETURN_OK) {
mapInitialized = true;
}
@ -48,6 +48,14 @@ ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage(
HousekeepingMessage& message) {
Command_t command = message.getCommand();
switch(command) {
// I think those are the only commands which can be handled here..
case(HousekeepingMessage::ADD_HK_REPORT_STRUCT):
case(HousekeepingMessage::ADD_DIAGNOSTICS_REPORT_STRUCT):
// We should use OwnsLocalPoolDataIF to specify those functions..
return HasReturnvaluesIF::RETURN_OK;
case(HousekeepingMessage::REPORT_DIAGNOSTICS_REPORT_STRUCTURES):
case(HousekeepingMessage::REPORT_HK_REPORT_STRUCTURES):
return generateSetStructurePacket(message.getSid());
case(HousekeepingMessage::GENERATE_ONE_PARAMETER_REPORT):
case(HousekeepingMessage::GENERATE_ONE_DIAGNOSTICS_REPORT):
return generateHousekeepingPacket(message.getSid());
@ -114,13 +122,41 @@ ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid) {
return result;
}
ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid) {
LocalDataSet* dataSet = dynamic_cast<LocalDataSet*>(
owner->getDataSetHandle(sid));
if(dataSet == nullptr) {
sif::warning << "HousekeepingManager::generateHousekeepingPacket:"
" Set ID not found" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
size_t expectedSize = dataSet->getFillCount() * sizeof(lp_id_t);
uint8_t* storePtr = nullptr;
store_address_t storeId;
ReturnValue_t result = ipcStore->getFreeElement(&storeId,
expectedSize,&storePtr);
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::error << "HousekeepingManager::generateHousekeepingPacket: "
"Could not get free element from IPC store." << std::endl;
return result;
}
size_t size = 0;
result = dataSet->serializeLocalPoolIds(&storePtr, &size,
expectedSize, false);
if(expectedSize != size) {
sif::error << "HousekeepingManager::generateSetStructurePacket: "
"Expected size is not equal to serialized size" << std::endl;
}
return result;
}
ReturnValue_t LocalDataPoolManager::serializeHkPacketIntoStore(
store_address_t *storeId, LocalDataSet* dataSet) {
size_t hkSize = dataSet->getSerializedSize();
uint8_t* storePtr = nullptr;
ReturnValue_t result = ipcStore->getFreeElement(storeId, hkSize,&storePtr);
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "HousekeepingManager::generateHousekeepingPacket: "
sif::error << "HousekeepingManager::generateHousekeepingPacket: "
"Could not get free element from IPC store." << std::endl;
return result;
}

View File

@ -56,6 +56,8 @@ public:
LocalDataPoolManager operator=(const LocalDataPoolManager&) = delete;
ReturnValue_t generateHousekeepingPacket(sid_t sid);
ReturnValue_t generateSetStructurePacket(sid_t sid);
ReturnValue_t handleHousekeepingMessage(HousekeepingMessage& message);
/**

View File

@ -1,5 +1,6 @@
#include <framework/datapoollocal/LocalDataPoolManager.h>
#include <framework/datapoollocal/LocalDataSet.h>
#include <framework/serialize/SerializeAdapter.h>
#include <cmath>
#include <cstring>
@ -67,6 +68,21 @@ ReturnValue_t LocalDataSet::unlockDataPool() {
return mutex->unlockMutex();
}
ReturnValue_t LocalDataSet::serializeLocalPoolIds(uint8_t** buffer,
size_t* size, const size_t maxSize, bool bigEndian) const {
for (uint16_t count = 0; count < fillCount; count++) {
lp_id_t currentPoolId = registeredVariables[count]->getDataPoolId();
auto result = AutoSerializeAdapter::serialize(&currentPoolId, buffer,
size, maxSize, bigEndian);
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "LocalDataSet::serializeLocalPoolIds: Serialization"
" error!" << std::endl;
return result;
}
}
return HasReturnvaluesIF::RETURN_OK;
}
void LocalDataSet::bitSetter(uint8_t* byte, uint8_t position,
bool value) const {
if(position > 7) {

View File

@ -68,7 +68,10 @@ public:
* @return
*/
ReturnValue_t serializeWithValidityBuffer(uint8_t** buffer,
size_t* size, const size_t maxSize, bool bigEndian) const ;
size_t* size, const size_t maxSize, bool bigEndian) const;
ReturnValue_t serializeLocalPoolIds(uint8_t** buffer,
size_t* size, const size_t maxSize, bool bigEndian) const;
protected:
private:
/**

View File

@ -42,12 +42,36 @@ public:
static constexpr uint8_t INTERFACE_ID = CLASS_ID::LOCAL_POOL_OWNER_IF;
/** Command queue for housekeeping messages. */
virtual MessageQueueId_t getCommandQueue() const = 0;
virtual ReturnValue_t initializeHousekeepingPoolEntries(
LocalDataPool& localDataPoolMap) = 0;
//virtual float setMinimalHkSamplingFrequency() = 0;
/** Is used by pool owner to initialize the pool map once */
virtual ReturnValue_t initializePoolEntries(
LocalDataPool& localDataPoolMap) = 0;
/** Can be used to get a handle to the local data pool manager. */
virtual LocalDataPoolManager* getHkManagerHandle() = 0;
/**
* This function is used by the pool manager to get a valid dataset
* from a SID
* @param sid Corresponding structure ID
* @return
*/
virtual DataSetIF* getDataSetHandle(sid_t sid) = 0;
/* These function can be implemented by pool owner, as they are required
* by the housekeeping message interface */
virtual ReturnValue_t addDataSet(sid_t sid) {
return HasReturnvaluesIF::RETURN_FAILED;
};
virtual ReturnValue_t removeDataSet(sid_t sid) {
return HasReturnvaluesIF::RETURN_FAILED;
};
virtual ReturnValue_t changeCollectionInterval(sid_t sid,
dur_seconds_t newInterval) {
return HasReturnvaluesIF::RETURN_FAILED;
};
};
#endif /* FRAMEWORK_DATAPOOL_HASHKPOOLPARAMETERSIF_H_ */

View File

@ -1350,7 +1350,7 @@ void DeviceHandlerBase::changeHK(Mode_t mode, Submode_t submode, bool enable) {
}
void DeviceHandlerBase::setTaskIF(PeriodicTaskIF* task_){
executingTask = task_;
executingTask = task_;
}
// Default implementations empty.
@ -1360,7 +1360,7 @@ void DeviceHandlerBase::debugInterface(uint8_t positionTracker,
void DeviceHandlerBase::performOperationHook() {
}
ReturnValue_t DeviceHandlerBase::initializeHousekeepingPoolEntries(
ReturnValue_t DeviceHandlerBase::initializePoolEntries(
LocalDataPool &localDataPoolMap) {
return RETURN_OK;
}
@ -1369,6 +1369,19 @@ LocalDataPoolManager* DeviceHandlerBase::getHkManagerHandle() {
return &hkManager;
}
ReturnValue_t DeviceHandlerBase::addDataSet(sid_t sid) {
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t DeviceHandlerBase::removeDataSet(sid_t sid) {
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t DeviceHandlerBase::changeCollectionInterval(sid_t sid,
dur_seconds_t newInterval) {
return HasReturnvaluesIF::RETURN_OK;
}
DataSetIF* DeviceHandlerBase::getDataSetHandle(sid_t sid) {
auto iter = deviceReplyMap.find(sid.ownerSetId);
if(iter != deviceReplyMap.end()) {

View File

@ -477,12 +477,17 @@ protected:
* @param localDataPoolMap
* @return
*/
virtual ReturnValue_t initializeHousekeepingPoolEntries(
virtual ReturnValue_t initializePoolEntries(
LocalDataPool& localDataPoolMap) override;
/** Get the HK manager object handle */
virtual LocalDataPoolManager* getHkManagerHandle() override;
virtual ReturnValue_t addDataSet(sid_t sid) override;
virtual ReturnValue_t removeDataSet(sid_t sid) override;
virtual ReturnValue_t changeCollectionInterval(sid_t sid,
dur_seconds_t newInterval) override;
/**
* @brief Hook function for child handlers which is called once per
* performOperation(). Default implementation is empty.
@ -703,7 +708,9 @@ protected:
bool switchOffWasReported; //!< Indicates if SWITCH_WENT_OFF was already thrown.
PeriodicTaskIF* executingTask = nullptr;//!< Pointer to the task which executes this component, is invalid before setTaskIF was called.
//! Pointer to the task which executes this component, is invalid
//! before setTaskIF was called.
PeriodicTaskIF* executingTask = nullptr;
static object_id_t powerSwitcherId; //!< Object which switches power on and off.

View File

@ -8,13 +8,16 @@
const uint16_t EventManager::POOL_SIZES[N_POOLS] = {
sizeof(EventMatchTree::Node), sizeof(EventIdRangeMatcher),
sizeof(ReporterRangeMatcher) };
//If one checks registerListener calls, there are around 40 (to max 50) objects registering for certain events.
//Each listener requires 1 or 2 EventIdMatcher and 1 or 2 ReportRangeMatcher. So a good guess is 75 to a max of 100 pools required for each, which fits well.
// If one checks registerListener calls, there are around 40 (to max 50)
// objects registering for certain events.
// Each listener requires 1 or 2 EventIdMatcher and 1 or 2 ReportRangeMatcher.
// So a good guess is 75 to a max of 100 pools required for each, which fits well.
// SHOULDDO: Shouldn't this be in the config folder and passed via ctor?
const uint16_t EventManager::N_ELEMENTS[N_POOLS] = { 240, 120, 120 };
EventManager::EventManager(object_id_t setObjectId) :
SystemObject(setObjectId), eventReportQueue(NULL), mutex(NULL), factoryBackend(
0, POOL_SIZES, N_ELEMENTS, false, true) {
SystemObject(setObjectId),
factoryBackend(0, POOL_SIZES, N_ELEMENTS, false, true) {
mutex = MutexFactory::instance()->createMutex();
eventReportQueue = QueueFactory::instance()->createMessageQueue(
MAX_EVENTS_PER_CYCLE, EventMessage::EVENT_MESSAGE_SIZE);

View File

@ -36,11 +36,11 @@ public:
ReturnValue_t performOperation(uint8_t opCode);
protected:
MessageQueueIF* eventReportQueue;
MessageQueueIF* eventReportQueue = nullptr;
std::map<MessageQueueId_t, EventMatchTree> listenerList;
MutexIF* mutex;
MutexIF* mutex = nullptr;
static const uint8_t N_POOLS = 3;
LocalPool<N_POOLS> factoryBackend;

View File

@ -1,6 +1,7 @@
#include <framework/serviceinterface/ServiceInterfaceStream.h>
#include "FixedTimeslotTask.h"
#include <framework/serviceinterface/ServiceInterfaceStream.h>
uint32_t FixedTimeslotTask::deadlineMissedCount = 0;
const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = configMINIMAL_STACK_SIZE;
@ -18,16 +19,19 @@ FixedTimeslotTask::~FixedTimeslotTask() {
void FixedTimeslotTask::taskEntryPoint(void* argument) {
//The argument is re-interpreted as FixedTimeslotTask. The Task object is global, so it is found from any place.
// The argument is re-interpreted as FixedTimeslotTask. The Task object is
// global, so it is found from any place.
FixedTimeslotTask *originalTask(reinterpret_cast<FixedTimeslotTask*>(argument));
// Task should not start until explicitly requested
// in FreeRTOS, tasks start as soon as they are created if the scheduler is running
// but not if the scheduler is not running.
// to be able to accommodate both cases we check a member which is set in #startTask()
// if it is not set and we get here, the scheduler was started before #startTask() was called and we need to suspend
// if it is set, the scheduler was not running before #startTask() was called and we can continue
/* Task should not start until explicitly requested,
* but in FreeRTOS, tasks start as soon as they are created if the scheduler
* is running but not if the scheduler is not running.
* To be able to accommodate both cases we check a member which is set in
* #startTask(). If it is not set and we get here, the scheduler was started
* before #startTask() was called and we need to suspend if it is set,
* the scheduler was not running before #startTask() was called and we
* can continue */
if (!originalTask->started) {
if (not originalTask->started) {
vTaskSuspend(NULL);
}
@ -81,7 +85,8 @@ ReturnValue_t FixedTimeslotTask::checkSequence() const {
}
void FixedTimeslotTask::taskFunctionality() {
// A local iterator for the Polling Sequence Table is created to find the start time for the first entry.
// A local iterator for the Polling Sequence Table is created to find the
// start time for the first entry.
SlotListIter slotListIter = pst.current;
//The start time for the first entry is read.
@ -101,17 +106,30 @@ void FixedTimeslotTask::taskFunctionality() {
/* Enter the loop that defines the task behavior. */
for (;;) {
//The component for this slot is executed and the next one is chosen.
this->pst.executeAndAdvance();
if (pst.slotFollowsImmediately()) {
//Do nothing
} else {
// we need to wait before executing the current slot
//this gives us the time to wait:
intervalMs = this->pst.getIntervalToPreviousSlotMs();
interval = pdMS_TO_TICKS(intervalMs);
vTaskDelayUntil(&xLastWakeTime, interval);
//TODO deadline missed check
}
this->pst.executeAndAdvance();
if (not pst.slotFollowsImmediately()) {
/* If all operations are finished and the difference of the
* current time minus the last wake time is larger than the
* expected wait period, a deadline was missed. */
if(xTaskGetTickCount() - xLastWakeTime >=
pdMS_TO_TICKS(this->pst.getIntervalToPreviousSlotMs())) {
#ifdef DEBUG
sif::warning << "PeriodicTask: " << pcTaskGetName(NULL) <<
" missed deadline!\n" << std::flush;
#endif
if(deadlineMissedFunc != nullptr) {
this->deadlineMissedFunc();
}
// Continue immediately, no need to wait.
break;
}
// we need to wait before executing the current slot
//this gives us the time to wait:
intervalMs = this->pst.getIntervalToPreviousSlotMs();
interval = pdMS_TO_TICKS(intervalMs);
vTaskDelayUntil(&xLastWakeTime, interval);
}
}
}

View File

@ -1,12 +1,12 @@
#ifndef POLLINGTASK_H_
#define POLLINGTASK_H_
#ifndef FRAMEWORK_OSAL_FREERTOS_FIXEDTIMESLOTTASK_H_
#define FRAMEWORK_OSAL_FREERTOS_FIXEDTIMESLOTTASK_H_
#include <framework/devicehandlers/FixedSlotSequence.h>
#include <framework/tasks/FixedTimeslotTaskIF.h>
#include <framework/tasks/Typedef.h>
#include <FreeRTOS.h>
#include "task.h"
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
class FixedTimeslotTask: public FixedTimeslotTaskIF {
public:
@ -29,16 +29,18 @@ public:
/**
* @brief The destructor of the class.
*
* @details The destructor frees all heap memory that was allocated on thread initialization for the PST and
* the device handlers. This is done by calling the PST's destructor.
* @details
* The destructor frees all heap memory that was allocated on thread
* initialization for the PST and the device handlers. This is done by
* calling the PST's destructor.
*/
virtual ~FixedTimeslotTask(void);
ReturnValue_t startTask(void);
/**
* This static function can be used as #deadlineMissedFunc.
* It counts missedDeadlines and prints the number of missed deadlines every 10th time.
* It counts missedDeadlines and prints the number of missed deadlines
* every 10th time.
*/
static void missedDeadlineCounter();
/**
@ -62,30 +64,29 @@ protected:
FixedSlotSequence pst;
/**
* @brief This attribute holds a function pointer that is executed when a deadline was missed.
*
* @details Another function may be announced to determine the actions to perform when a deadline was missed.
* Currently, only one function for missing any deadline is allowed.
* If not used, it shall be declared NULL.
* @brief This attribute holds a function pointer that is executed when
* a deadline was missed.
* @details
* Another function may be announced to determine the actions to perform
* when a deadline was missed. Currently, only one function for missing
* any deadline is allowed. If not used, it shall be declared NULL.
*/
void (*deadlineMissedFunc)(void);
/**
* @brief This is the entry point in a new polling thread.
*
* @details This method, that is the generalOSAL::checkAndRestartPeriod( this->periodId, interval ); entry point in the new thread, is here set to generate
* and link the Polling Sequence Table to the thread object and start taskFunctionality()
* on success. If operation of the task is ended for some reason,
* the destructor is called to free allocated memory.
* @brief This is the entry point for a new task.
* @details
* This method starts the task by calling taskFunctionality(), as soon as
* all requirements (task scheduler has started and startTask()
* has been called) are met.
*/
static void taskEntryPoint(void* argument);
/**
* @brief This function holds the main functionality of the thread.
*
*
* @details Holding the main functionality of the task, this method is most important.
* It links the functionalities provided by FixedSlotSequence with the OS's System Calls
* to keep the timing of the periods.
* @details
* Core function holding the main functionality of the task
* It links the functionalities provided by FixedSlotSequence with the
* OS's System Calls to keep the timing of the periods.
*/
void taskFunctionality(void);
};

View File

@ -12,8 +12,8 @@ PeriodicTask::PeriodicTask(const char *name, TaskPriority setPriority,
BaseType_t status = xTaskCreate(taskEntryPoint, name,
setStack, this, setPriority, &handle);
if(status != pdPASS){
sif::debug << "PeriodicTask Insufficient heap memory remaining. Status: "
<< status << std::endl;
sif::debug << "PeriodicTask Insufficient heap memory remaining. "
"Status: " << status << std::endl;
}
}
@ -23,14 +23,17 @@ PeriodicTask::~PeriodicTask(void) {
}
void PeriodicTask::taskEntryPoint(void* argument) {
//The argument is re-interpreted as PeriodicTask. The Task object is global, so it is found from any place.
// The argument is re-interpreted as PeriodicTask. The Task object is
// global, so it is found from any place.
PeriodicTask *originalTask(reinterpret_cast<PeriodicTask*>(argument));
// Task should not start until explicitly requested
// in FreeRTOS, tasks start as soon as they are created if the scheduler is running
// but not if the scheduler is not running.
// to be able to accommodate both cases we check a member which is set in #startTask()
// if it is not set and we get here, the scheduler was started before #startTask() was called and we need to suspend
// if it is set, the scheduler was not running before #startTask() was called and we can continue
/* Task should not start until explicitly requested,
* but in FreeRTOS, tasks start as soon as they are created if the scheduler
* is running but not if the scheduler is not running.
* To be able to accommodate both cases we check a member which is set in
* #startTask(). If it is not set and we get here, the scheduler was started
* before #startTask() was called and we need to suspend if it is set,
* the scheduler was not running before #startTask() was called and we
* can continue */
if (not originalTask->started) {
vTaskSuspend(NULL);
@ -61,9 +64,9 @@ void PeriodicTask::taskFunctionality() {
TickType_t xLastWakeTime;
const TickType_t xPeriod = pdMS_TO_TICKS(this->period * 1000.);
/* The xLastWakeTime variable needs to be initialized with the current tick
count. Note that this is the only time the variable is written to explicitly.
After this assignment, xLastWakeTime is updated automatically internally within
vTaskDelayUntil(). */
count. Note that this is the only time the variable is written to
explicitly. After this assignment, xLastWakeTime is updated automatically
internally within vTaskDelayUntil(). */
xLastWakeTime = xTaskGetTickCount();
/* Enter the loop that defines the task behavior. */
for (;;) {
@ -76,12 +79,15 @@ void PeriodicTask::taskFunctionality() {
* current time minus the last wake time is larger than the
* wait period, a deadline was missed. */
if(xTaskGetTickCount() - xLastWakeTime >= xPeriod) {
#ifdef DEBUG
sif::warning << "PeriodicTask: " << pcTaskGetName(NULL) <<
" missed deadline!\n" << std::flush;
#endif
if(deadlineMissedFunc != nullptr) {
this->deadlineMissedFunc();
}
}
vTaskDelayUntil(&xLastWakeTime, xPeriod);
}

View File

@ -5,10 +5,8 @@
#include <framework/tasks/PeriodicTaskIF.h>
#include <framework/tasks/Typedef.h>
extern "C" {
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
}
#include <vector>
@ -22,7 +20,8 @@ class ExecutableObjectIF;
class PeriodicTask: public PeriodicTaskIF {
public:
/**
* @brief Standard constructor of the class.
* Keep in Mind that you need to call before this vTaskStartScheduler()!
* A lot of task parameters are set in "FreeRTOSConfig.h".
* @details
* The class is initialized without allocated objects.
* These need to be added with #addComponent.
@ -38,8 +37,9 @@ public:
* The function pointer to the deadline missed function that shall
* be assigned.
*/
PeriodicTask(const char *name, TaskPriority setPriority, TaskStackSize setStack,
TaskPeriod setPeriod,void (*setDeadlineMissedFunc)());
PeriodicTask(const char *name, TaskPriority setPriority,
TaskStackSize setStack, TaskPeriod setPeriod,
void (*setDeadlineMissedFunc)());
/**
* @brief Currently, the executed object's lifetime is not coupled with
* the task object's lifetime, so the destructor is empty.
@ -58,7 +58,9 @@ public:
* Adds an object to the list of objects to be executed.
* The objects are executed in the order added.
* @param object Id of the object to add.
* @return RETURN_OK on success, RETURN_FAILED if the object could not be added.
* @return
* -@c RETURN_OK on success
* -@c RETURN_FAILED if the object could not be added.
*/
ReturnValue_t addComponent(object_id_t object);
@ -69,40 +71,47 @@ protected:
bool started;
TaskHandle_t handle;
typedef std::vector<ExecutableObjectIF*> ObjectList; //!< Typedef for the List of objects.
//! Typedef for the List of objects.
typedef std::vector<ExecutableObjectIF*> ObjectList;
/**
* @brief This attribute holds a list of objects to be executed.
*/
ObjectList objectList;
/**
* @brief The period of the task.
* @details The period determines the frequency of the task's execution. It is expressed in clock ticks.
* @details
* The period determines the frequency of the task's execution.
* It is expressed in clock ticks.
*/
TaskPeriod period;
/**
* @brief The pointer to the deadline-missed function.
* @details This pointer stores the function that is executed if the task's deadline is missed.
* So, each may react individually on a timing failure. The pointer may be NULL,
* then nothing happens on missing the deadline. The deadline is equal to the next execution
* of the periodic task.
* @details
* This pointer stores the function that is executed if the task's deadline
* is missed so each may react individually on a timing failure.
* The pointer may be NULL, then nothing happens on missing the deadline.
* The deadline is equal to the next execution of the periodic task.
*/
void (*deadlineMissedFunc)(void);
/**
* @brief This is the function executed in the new task's context.
* @details It converts the argument back to the thread object type and copies the class instance
* to the task context. The taskFunctionality method is called afterwards.
* @details
* It converts the argument back to the thread object type and copies the
* class instance to the task context. The taskFunctionality method is
* called afterwards.
* @param A pointer to the task object itself is passed as argument.
*/
static void taskEntryPoint(void* argument);
/**
* @brief The function containing the actual functionality of the task.
* @details The method sets and starts
* the task's period, then enters a loop that is repeated as long as the isRunning
* attribute is true. Within the loop, all performOperation methods of the added
* objects are called. Afterwards the checkAndRestartPeriod system call blocks the task
* until the next period.
* On missing the deadline, the deadlineMissedFunction is executed.
* @details
* The method sets and starts the task's period, then enters a loop that is
* repeated as long as the isRunning attribute is true. Within the loop,
* all performOperation methods of the added objects are called.
* Afterwards the checkAndRestartPeriod system call blocks the task until
* the next period.
* On missing the deadline, the deadlineMissedFunction is executed.
*/
void taskFunctionality(void);
};

View File

@ -65,6 +65,21 @@
// No type specification necessary here.
class AutoSerializeAdapter {
public:
/**
* Serialize object into buffer.
* @tparam T Type of object.
* @param object Object to serialize
* @param buffer
* Serialize into this buffer, pointer to pointer has to be passed,
* *buffer will be incremented automatically.
* @param size [out]
* Update passed size value, will be incremented by serialized size
* @param max_size
* Maximum size for range checking
* @param bigEndian
* Set to true if host-to-network conversion or vice-versa is needed
* @return
*/
template<typename T>
static ReturnValue_t serialize(const T* object, uint8_t** buffer,
size_t* size, const size_t max_size, bool bigEndian) {

View File

@ -37,8 +37,10 @@ public:
/**
* @brief Function called during setup assignment of object to task
* @details Has to be called from the function that assigns the object to a task and
* enables the object implementation to overwrite this function and get a reference to the executing task
* @details
* Has to be called from the function that assigns the object to a task and
* enables the object implementation to overwrite this function and get
* a reference to the executing task
* @param task_ Pointer to the taskIF of this task
*/
virtual void setTaskIF(PeriodicTaskIF* task_) {

View File

@ -412,5 +412,6 @@ void CommandingServiceBase::checkTimeout() {
}
}
void CommandingServiceBase::setTaskIF(PeriodicTaskIF* task_) {
executingTask = task_;
}

View File

@ -97,9 +97,7 @@ public:
* Used to setup the reference of the task, that executes this component
* @param task_ Pointer to the taskIF of this task
*/
virtual void setTaskIF(PeriodicTaskIF* task_){
executingTask = task_;
};
virtual void setTaskIF(PeriodicTaskIF* task_);
protected:
/**