updating code from Flying Laptop
This is the framework of Flying Laptop OBSW version A.13.0.
This commit is contained in:
@ -12,12 +12,13 @@
|
||||
#define EXECUTABLEOBJECTIF_H_
|
||||
|
||||
|
||||
#include <framework/osal/OSAL.h>
|
||||
#include <framework/osal/OperatingSystemIF.h>
|
||||
class PeriodicTaskIF;
|
||||
|
||||
/**
|
||||
* @brief The interface provides a method to execute objects within a task.
|
||||
* @details The performOperation method, that is required by the interface is
|
||||
* executed cyclically within the ObjectTask's context.
|
||||
* executed cyclically within a task context.
|
||||
*/
|
||||
class ExecutableObjectIF {
|
||||
public:
|
||||
@ -26,12 +27,14 @@ public:
|
||||
*/
|
||||
virtual ~ExecutableObjectIF() { }
|
||||
/**
|
||||
* @brief The performOperation method is executed in the ObjectTask context.
|
||||
* @brief The performOperation method is executed in a task.
|
||||
* @details There are no restrictions for calls within this method, so any
|
||||
* other member of the class can be used.
|
||||
* @return Currently, the return value is ignored.
|
||||
*/
|
||||
virtual ReturnValue_t performOperation() = 0;
|
||||
virtual ReturnValue_t performOperation(uint8_t operationCode = 0) = 0;
|
||||
|
||||
virtual void setTaskIF(PeriodicTaskIF* interface) {};
|
||||
};
|
||||
|
||||
#endif /* EXECUTABLEOBJECTIF_H_ */
|
||||
|
19
tasks/FixedTimeslotTaskIF.h
Normal file
19
tasks/FixedTimeslotTaskIF.h
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef FRAMEWORK_TASKS_FIXEDTIMESLOTTASKIF_H_
|
||||
#define FRAMEWORK_TASKS_FIXEDTIMESLOTTASKIF_H_
|
||||
|
||||
#include <framework/objectmanager/ObjectManagerIF.h>
|
||||
#include <framework/tasks/PeriodicTaskIF.h>
|
||||
|
||||
/**
|
||||
* Following the same principle as the base class IF. This is the interface for a Fixed timeslot task
|
||||
*/
|
||||
class FixedTimeslotTaskIF : public PeriodicTaskIF {
|
||||
public:
|
||||
virtual ~FixedTimeslotTaskIF() {}
|
||||
virtual ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs, int8_t executionStep) = 0;
|
||||
virtual ReturnValue_t checkSequence() const = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* FRAMEWORK_TASKS_FIXEDTIMESLOTTASKIF_H_ */
|
@ -1,24 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# OSAL makefile
|
||||
#
|
||||
# Created on: Mar 04, 2010
|
||||
# Author: ziemke
|
||||
# Author: Claas Ziemke
|
||||
# Copyright 2010, Claas Ziemke <claas.ziemke@gmx.net>
|
||||
#
|
||||
|
||||
BASEDIR=../../
|
||||
include $(BASEDIR)options.mk
|
||||
|
||||
OBJ = $(BUILDDIR)/PeriodicTask.o \
|
||||
$(BUILDDIR)/ObjectTask.o \
|
||||
$(BUILDDIR)/TaskBase.o
|
||||
|
||||
all: $(OBJ)
|
||||
|
||||
$(BUILDDIR)/%.o: %.cpp %.h
|
||||
$(CPP) $(CFLAGS) $(DEFINES) $(CCOPT) ${INCLUDE} -c $< -o $@
|
||||
|
||||
clean:
|
||||
$(RM) *.o *.gcno *.gcda
|
@ -1,99 +0,0 @@
|
||||
/**
|
||||
* @file MultiObjectTask.cpp
|
||||
* @brief This file defines the MultiObjectTask class.
|
||||
* @date 30.01.2014
|
||||
* @author baetz
|
||||
*/
|
||||
|
||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||
#include <framework/tasks/MultiObjectTask.h>
|
||||
|
||||
MultiObjectTask::MultiObjectTask(const char *name, TaskPriority_t setPriority,
|
||||
size_t setStack, Interval_t setPeriod, void (*setDeadlineMissedFunc)()) :
|
||||
TaskBase(setPriority, setStack, name), period(setPeriod), periodId(0), deadlineMissedFunc(
|
||||
setDeadlineMissedFunc) {
|
||||
|
||||
}
|
||||
|
||||
MultiObjectTask::~MultiObjectTask(void) {
|
||||
//Do not delete objects!
|
||||
}
|
||||
TaskReturn_t MultiObjectTask::taskEntryPoint(TaskArgument_t argument) {
|
||||
//The argument is re-interpreted as ObjectTask. The Task object is global, so it is found from any place.
|
||||
MultiObjectTask *originalTask(reinterpret_cast<MultiObjectTask*>(argument));
|
||||
originalTask->taskFunctionality();
|
||||
debug << "MultiObjectTask " << originalTask->getId()
|
||||
<< " returned from taskFunctionality. Deleting task." << std::endl;
|
||||
}
|
||||
|
||||
ReturnValue_t MultiObjectTask::startTask() {
|
||||
this->setRunning( true);
|
||||
ReturnValue_t status;
|
||||
status = OSAL::startTask(&(this->id), MultiObjectTask::taskEntryPoint,
|
||||
TaskArgument_t((void *) this));
|
||||
if (status != RETURN_OK) {
|
||||
//TODO: Call any FDIR routine?
|
||||
error << "MultiObjectTask::startTask for " << std::hex << this->getId()
|
||||
<< std::dec << " failed." << std::endl;
|
||||
} else {
|
||||
// debug << "ObjectTask::startTask for " << std::hex << this->getId() << std::dec << " successful" << std::endl;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
void MultiObjectTask::taskFunctionality() {
|
||||
ReturnValue_t status = OSAL::TIMEOUT;
|
||||
//The period is set up and started with the system call.
|
||||
if (objectList.begin() != objectList.end()) {
|
||||
status = OSAL::setAndStartPeriod(this->period, &(this->periodId));
|
||||
if (status == RETURN_OK) {
|
||||
//The task's "infinite" inner loop is entered.
|
||||
while (this->isRunning) {
|
||||
for (ObjectList::iterator it = objectList.begin();
|
||||
it != objectList.end(); ++it) {
|
||||
(*it)->performOperation();
|
||||
}
|
||||
if (OSAL::checkAndRestartPeriod(this->periodId, this->period)
|
||||
== OSAL::TIMEOUT) {
|
||||
char nameSpace[8] = { 0 };
|
||||
char* ptr = rtems_object_get_name(getId(),
|
||||
sizeof(nameSpace), nameSpace);
|
||||
error << "MultiObjectTask: " << ptr << " Deadline missed."
|
||||
<< std::endl;
|
||||
if (this->deadlineMissedFunc != NULL) {
|
||||
this->deadlineMissedFunc();
|
||||
}
|
||||
}
|
||||
}
|
||||
debug << "MultiObjectTask: Returned from taskFunctionality()-Loop."
|
||||
<< std::endl;
|
||||
} else {
|
||||
error << "MultiObjectTask::setAndStartPeriod failed with status "
|
||||
<< status << std::endl;
|
||||
}
|
||||
} else {
|
||||
error << "MultiObjectTask::taskFunctionality. No object assigned."
|
||||
<< std::endl;
|
||||
}
|
||||
//Any operating system object for periodic execution is deleted.
|
||||
debug << "Deleting the ObjectTask's period." << std::endl;
|
||||
OSAL::deletePeriod(&(this->id));
|
||||
}
|
||||
|
||||
ReturnValue_t MultiObjectTask::addObject(object_id_t object) {
|
||||
ExecutableObjectIF* newObject = objectManager->get<ExecutableObjectIF>(
|
||||
object);
|
||||
if (newObject == NULL) {
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
objectList.push_back(newObject);
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t MultiObjectTask::addObject(ExecutableObjectIF* object) {
|
||||
if (object == NULL) {
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
objectList.push_back(object);
|
||||
return RETURN_OK;
|
||||
}
|
@ -1,113 +0,0 @@
|
||||
/**
|
||||
* @file MultiObjectTask.h
|
||||
* @brief This file defines the MultiObjectTask class.
|
||||
* @date 30.01.2014
|
||||
* @author baetz
|
||||
*/
|
||||
#ifndef MULTIOBJECTTASK_H_
|
||||
#define MULTIOBJECTTASK_H_
|
||||
|
||||
#include <framework/objectmanager/ObjectManagerIF.h>
|
||||
#include <framework/tasks/ExecutableObjectIF.h>
|
||||
#include <framework/tasks/TaskBase.h>
|
||||
#include <list>
|
||||
/**
|
||||
* @brief This class represents a specialized task for periodic activities of multiple objects.
|
||||
*
|
||||
* @details MultiObjectTask is an extension to ObjectTask in the way that it is able to execute
|
||||
* multiple objects that implement the ExecutableObjectIF interface. The objects must be
|
||||
* added prior to starting the task.
|
||||
*
|
||||
* @ingroup task_handling
|
||||
*/
|
||||
class MultiObjectTask: public TaskBase {
|
||||
protected:
|
||||
typedef std::list<ExecutableObjectIF*> ObjectList; //!< Typedef for the List of objects.
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
Interval_t period;
|
||||
/**
|
||||
* @brief id of the associated OS period
|
||||
*/
|
||||
PeriodId_t periodId;
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
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.
|
||||
* @param A pointer to the task object itself is passed as argument.
|
||||
*/
|
||||
static TaskReturn_t taskEntryPoint(TaskArgument_t 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.
|
||||
*/
|
||||
void taskFunctionality(void);
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Standard constructor of the class.
|
||||
* @details The class is initialized without allocated objects. These need to be added
|
||||
* with #addObject.
|
||||
* In the underlying TaskBase class, a new operating system task is created.
|
||||
* In addition to the TaskBase parameters, the period, the pointer to the
|
||||
* aforementioned initialization function and an optional "deadline-missed"
|
||||
* function pointer is passed.
|
||||
* @param priority Sets the priority of a task. Values range from a low 0 to a high 99.
|
||||
* @param stack_size The stack size reserved by the operating system for the task.
|
||||
* @param setPeriod The length of the period with which the task's functionality will be
|
||||
* executed. It is expressed in clock ticks.
|
||||
* @param setDeadlineMissedFunc The function pointer to the deadline missed function
|
||||
* that shall be assigned.
|
||||
*/
|
||||
MultiObjectTask(const char *name, TaskPriority_t setPriority, size_t setStack, Interval_t setPeriod,
|
||||
void (*setDeadlineMissedFunc)());
|
||||
/**
|
||||
* @brief Currently, the executed object's lifetime is not coupled with the task object's
|
||||
* lifetime, so the destructor is empty.
|
||||
*/
|
||||
virtual ~MultiObjectTask(void);
|
||||
|
||||
/**
|
||||
* @brief The method to start the task.
|
||||
* @details The method starts the task with the respective system call.
|
||||
* Entry point is the taskEntryPoint method described below.
|
||||
* The address of the task object is passed as an argument
|
||||
* to the system call.
|
||||
*/
|
||||
ReturnValue_t startTask(void);
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
ReturnValue_t addObject(object_id_t object);
|
||||
/**
|
||||
* Variant to add objects with known location directly.
|
||||
* @param object Reference to a persistant executable object.
|
||||
* @return RETURN_OK on success, RETURN_FAILED if the object could not be added.
|
||||
*/
|
||||
ReturnValue_t addObject(ExecutableObjectIF* object);
|
||||
|
||||
};
|
||||
|
||||
#endif /* MULTIOBJECTTASK_H_ */
|
@ -1,78 +0,0 @@
|
||||
/*
|
||||
* ObjectTask.cpp
|
||||
*
|
||||
* Created on: 03.02.2012
|
||||
* Author: baetz
|
||||
*/
|
||||
|
||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||
#include <framework/tasks/ObjectTask.h>
|
||||
|
||||
ObjectTask::ObjectTask( const char *name, TaskPriority_t setPriority, size_t setStack, Interval_t setPeriod, void (*setDeadlineMissedFunc)(), ExecutableObjectIF* (*initFunction)() ) :
|
||||
TaskBase( setPriority, setStack, name ), period(setPeriod), periodId(0), deadlineMissedFunc(setDeadlineMissedFunc) {
|
||||
// All additional attributes are applied to the object.
|
||||
this->executingObject = initFunction();
|
||||
|
||||
}
|
||||
|
||||
ObjectTask::ObjectTask(const char *name, TaskPriority_t setPriority, size_t setStack,
|
||||
Interval_t setPeriod, void (*setDeadlineMissedFunc)(),
|
||||
object_id_t object_id) : TaskBase( setPriority, setStack, name ), period(setPeriod), periodId(0), deadlineMissedFunc(setDeadlineMissedFunc) {
|
||||
this->executingObject = objectManager->get<ExecutableObjectIF>( object_id );
|
||||
}
|
||||
|
||||
ObjectTask::~ObjectTask() {
|
||||
}
|
||||
|
||||
TaskReturn_t ObjectTask::taskEntryPoint( TaskArgument_t argument ) {
|
||||
//The argument is re-interpreted as ObjectTask. The Task object is global, so it is found from any place.
|
||||
ObjectTask *originalTask( reinterpret_cast<ObjectTask*>( argument ) );
|
||||
originalTask->taskFunctionality();
|
||||
debug << "Object task " << originalTask->getId() << " returned from taskFunctionality. Deleting task." << std::endl;
|
||||
//TODO: destroy the task object?
|
||||
}
|
||||
|
||||
ReturnValue_t ObjectTask::startTask() {
|
||||
this->setRunning( true );
|
||||
ReturnValue_t status;
|
||||
status = OSAL::startTask( &( this->id ), ObjectTask::taskEntryPoint, TaskArgument_t( ( void *)this ) );
|
||||
if( status != RETURN_OK ) {
|
||||
//TODO: Call any FDIR routine?
|
||||
error << "ObjectTask::startTask for " << std::hex << this->getId() << std::dec << " failed." << std::endl;
|
||||
} else {
|
||||
// debug << "ObjectTask::startTask for " << std::hex << this->getId() << std::dec << " successful" << std::endl;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
void ObjectTask::taskFunctionality() {
|
||||
ReturnValue_t status = OSAL::TIMEOUT;
|
||||
//The period is set up and started with the system call.
|
||||
if ( this->executingObject != NULL ) {
|
||||
status = OSAL::setAndStartPeriod( this->period, &(this->periodId) );
|
||||
if( status == RETURN_OK ) {
|
||||
//The task's "infinite" inner loop is entered.
|
||||
while( this->isRunning ) {
|
||||
|
||||
this->executingObject->performOperation();
|
||||
|
||||
if( OSAL::checkAndRestartPeriod( this->periodId, this->period ) == OSAL::TIMEOUT ) {
|
||||
char nameSpace[8] = {0};
|
||||
char* ptr = rtems_object_get_name(getId(), sizeof(nameSpace), nameSpace);
|
||||
error << "ObjectTask: " << ptr << " Deadline missed." << std::endl;
|
||||
if( this->deadlineMissedFunc != NULL ) {
|
||||
this->deadlineMissedFunc();
|
||||
}
|
||||
}
|
||||
}
|
||||
debug << "Returned from taskFunctionality()-Loop." << std::endl;
|
||||
} else {
|
||||
error << "ObjectTask::setAndStartPeriod failed with status " << status << std::endl;
|
||||
}
|
||||
} else {
|
||||
error << "ObjectTask::taskFunctionality. Object not found." << std::endl;
|
||||
}
|
||||
//Any operating system object for periodic execution is deleted.
|
||||
debug << "Deleting the ObjectTask's period." << std::endl;
|
||||
OSAL::deletePeriod( &(this->id) );
|
||||
}
|
@ -1,129 +0,0 @@
|
||||
|
||||
/**
|
||||
* @file ObjectTask.h
|
||||
*
|
||||
* @brief This file contains the definition for the ObjectTask class.
|
||||
*
|
||||
* @author Bastian Baetz
|
||||
*
|
||||
* @date 02/03/2012
|
||||
*
|
||||
*/
|
||||
#ifndef OBJECTTASK_H_
|
||||
#define OBJECTTASK_H_
|
||||
|
||||
#include <framework/objectmanager/ObjectManagerIF.h>
|
||||
#include <framework/tasks/ExecutableObjectIF.h>
|
||||
#include <framework/tasks/TaskBase.h>
|
||||
|
||||
/**
|
||||
* @brief This class represents a specialized task for periodic activities of objects.
|
||||
*
|
||||
* @details For object-oriented embedded systems, simple periodic tasks executing a single function
|
||||
* are not very useful. An object method, representing some kind of activity to be performed,
|
||||
* would either be instantiated in each execution, thus loosing all attribute information, or
|
||||
* must be known globally. To address this issue, the ObjectTask class is used.
|
||||
* It implements the TaskBase prototype and provides additional means to make use of any
|
||||
* object that implements the ExecutableObjectIF interface. The required performOperation
|
||||
* method is then called periodically. Attributes of the executed object are persistent
|
||||
* during the task's lifetime.
|
||||
* Functionally, the class works similar to PeriodicTask.
|
||||
*
|
||||
* @author Bastian Baetz
|
||||
*
|
||||
* @date 02/03/2012
|
||||
*
|
||||
* @ingroup task_handling
|
||||
*/
|
||||
class ObjectTask: public TaskBase {
|
||||
protected:
|
||||
/**
|
||||
* @brief This attribute holds a pointer to the object to be executed.
|
||||
*/
|
||||
ExecutableObjectIF* executingObject;
|
||||
/**
|
||||
* @brief The period of the task.
|
||||
* @details The period determines the frequency of the task's execution. It is expressed in clock ticks.
|
||||
*/
|
||||
Interval_t period;
|
||||
/**
|
||||
* @brief id of the associated OS period
|
||||
*/
|
||||
PeriodId_t periodId;
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
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.
|
||||
* @param A pointer to the task object itself is passed as argument.
|
||||
*/
|
||||
static TaskReturn_t taskEntryPoint( TaskArgument_t 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, the object's performFunction method is called, and
|
||||
* afterwards the checkAndRestartPeriod system call to block the task until the next
|
||||
* period. On missing the deadline, the deadlineMissedFunction is executed.
|
||||
*/
|
||||
void taskFunctionality( void );
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief The first of the two standard constructors of the class.
|
||||
* @details This constructor initializes the object to be executed with the aid of an
|
||||
* initialization function that returns the pointer to the object.
|
||||
* In the underlying TaskBase class, a new operating system task is created.
|
||||
* In addition to the TaskBase parameters, the period, the pointer to the
|
||||
* aforementioned initialization function and an optional "deadline-missed"
|
||||
* function pointer is passed.
|
||||
* @param priority Sets the priority of a task. Values range from a low 0 to a high 99.
|
||||
* @param stack_size The stack size reserved by the operating system for the task.
|
||||
* @param setPeriod The length of the period with which the task's functionality will be
|
||||
* executed. It is expressed in clock ticks.
|
||||
* @param setDeadlineMissedFunc The function pointer to the deadline missed function
|
||||
* that shall be assigned.
|
||||
* @param initFunction A pointer to the initialization function that returns the object to be executed.
|
||||
*/
|
||||
ObjectTask( const char *name, TaskPriority_t setPriority, size_t setStack, Interval_t setPeriod, void (*setDeadlineMissedFunc)(), ExecutableObjectIF* (*initFunction)() );
|
||||
/**
|
||||
* @brief The second of the two standard constructors of the class.
|
||||
* @details This constructor initializes the object to be executed with the aid of an
|
||||
* object id and the global ObjectManager class.
|
||||
* In the underlying TaskBase class, a new operating system task is created.
|
||||
* In addition to the TaskBase parameters, the period, the object_id of the
|
||||
* object to be executed and an optional "deadline-missed" function pointer is passed.
|
||||
* @param priority Sets the priority of a task. Values range from a low 0 to a high 99.
|
||||
* @param stack_size The stack size reserved by the operating system for the task.
|
||||
* @param setPeriod The length of the period with which the task's functionality will be
|
||||
* executed. It is expressed in clock ticks.
|
||||
* @param setDeadlineMissedFunc The function pointer to the deadline missed function
|
||||
* that shall be assigned.
|
||||
* @param object_id The object id of the object to be executed.
|
||||
*/
|
||||
ObjectTask( const char *name, TaskPriority_t setPriority, size_t setStack, Interval_t setPeriod, void (*setDeadlineMissedFunc)(), object_id_t object_id );
|
||||
/**
|
||||
* @brief Currently, the executed object's lifetime is not coupled with the task object's
|
||||
* lifetime, so the destructor is empty.
|
||||
*/
|
||||
virtual ~ObjectTask( void );
|
||||
|
||||
/**
|
||||
* @brief The method to start the task.
|
||||
* @details The method starts the task with the respective system call.
|
||||
* Entry point is the taskEntryPoint method described below.
|
||||
* The address of the task object is passed as an argument
|
||||
* to the system call.
|
||||
*/
|
||||
ReturnValue_t startTask( void );
|
||||
|
||||
};
|
||||
|
||||
#endif /* OBJECTTASK_H_ */
|
@ -1,81 +0,0 @@
|
||||
/**
|
||||
* \file PeriodicTask.cpp
|
||||
*
|
||||
* \brief This file contains the implementation for the PeriodicTask class.
|
||||
*
|
||||
* \author Bastian Baetz
|
||||
*
|
||||
* \date 21.07.2010
|
||||
*
|
||||
* Copyright 2010, Bastian Baetz <bastianbaetz@homail.com>
|
||||
* All rights reserved
|
||||
*
|
||||
*/
|
||||
|
||||
//#include <framework/osal/object_manager.h>
|
||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||
#include <framework/tasks/PeriodicTask.h>
|
||||
|
||||
//TODO: Check if isRunning flag is useful. Shall tasks be restartable?
|
||||
TaskReturn_t PeriodicTask::taskEntryPoint( TaskArgument_t argument ) {
|
||||
|
||||
//The argument is re-interpreted as PeriodicTask
|
||||
PeriodicTask *originalTask( reinterpret_cast<PeriodicTask*>(argument) );
|
||||
originalTask->taskFunctionality();
|
||||
debug << "Object task " << originalTask->getId() << " returned from taskFunctionality." << std::endl;
|
||||
//TODO: destroy the task object?
|
||||
}
|
||||
|
||||
PeriodicTask::PeriodicTask( const char *name, TaskPriority_t setPriority, size_t setStack, Interval_t setPeriod,
|
||||
void (*setDeadlineMissedFunc)(), ReturnValue_t ( *setTaskFunction )( TaskBase* ) ) :
|
||||
TaskBase( setPriority, setStack, name ), period(setPeriod), periodId(0), deadlineMissedFunc(setDeadlineMissedFunc),
|
||||
taskFunction(setTaskFunction) {
|
||||
}
|
||||
|
||||
PeriodicTask::~PeriodicTask() {
|
||||
}
|
||||
|
||||
ReturnValue_t PeriodicTask::startTask() {
|
||||
debug << "PeriodicTask::startTask. TaskId: " << this->getId() << std::endl;
|
||||
this->setRunning( true );
|
||||
ReturnValue_t status;
|
||||
status = OSAL::startTask( &( this->id ), PeriodicTask::taskEntryPoint, TaskArgument_t( ( void *)this ) );
|
||||
if( status != RETURN_OK ) {
|
||||
//TODO: Call any FDIR routine?
|
||||
error << "PeriodicTask::startTask for " << this->getId() << " failed." << std::endl;
|
||||
} else {
|
||||
debug << "PeriodicTask::startTask for " << this->getId() << " successful" << std::endl;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
void PeriodicTask::taskFunctionality() {
|
||||
|
||||
ReturnValue_t status = RETURN_OK;
|
||||
|
||||
//The period is set up and started with the system call.
|
||||
status = OSAL::setAndStartPeriod( this->period, &(this->periodId) );
|
||||
if( status == RETURN_OK ) {
|
||||
//The task's "infinite" inner loop is entered.
|
||||
while( this->isRunning ) {
|
||||
//If a functionality is announced, it is started.
|
||||
if( this->taskFunction != NULL ) {
|
||||
this->taskFunction( this );
|
||||
}
|
||||
//The period is checked and restarted.
|
||||
//If the deadline was missed, the deadlineMissedFunc is called.
|
||||
if( OSAL::checkAndRestartPeriod( this->periodId, this->period ) == OSAL::TIMEOUT ) {
|
||||
error << "PeriodicTask: " << std::hex << this->getId() << " Deadline missed." << std::endl;
|
||||
if( this->deadlineMissedFunc != NULL ) {
|
||||
this->deadlineMissedFunc();
|
||||
}
|
||||
}
|
||||
}
|
||||
debug << "Returned from taskFunctionality()-Loop." << std::endl;
|
||||
} else {
|
||||
error << "PeriodicTask::setAndStartPeriod failed with status " << status << std::endl;
|
||||
}
|
||||
//Any operating system object for periodic execution is deleted.
|
||||
debug << "Deleting the PeriodicThread's period." << std::endl;
|
||||
OSAL::deletePeriod( &(this->id) );
|
||||
}
|
@ -1,113 +0,0 @@
|
||||
/**
|
||||
* @file PeriodicTask.h
|
||||
*
|
||||
* @brief This file contains the definition for the PeriodicTask class.
|
||||
*
|
||||
* @author Bastian Baetz
|
||||
*
|
||||
* @date 07/21/2010
|
||||
*
|
||||
*/
|
||||
#ifndef OPUSPERIODICTASK_H_
|
||||
#define OPUSPERIODICTASK_H_
|
||||
|
||||
#include <framework/tasks/TaskBase.h>
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief This class represents a specialized task for periodic activities.
|
||||
*
|
||||
* @details A simple, but very important task type is the periodic task. Each task of this type has
|
||||
* a certain period assigned. When started, the task's functionality (a simple function)
|
||||
* is executed. On finishing, the task is blocked for the rest of the period and restarted
|
||||
* afterwards. A missed deadline is detected and a function to perform necessary failure
|
||||
* detection may be called.
|
||||
*
|
||||
* @author Bastian Baetz
|
||||
*
|
||||
* @date 07/21/2010
|
||||
*
|
||||
* @ingroup task_handling
|
||||
*/
|
||||
class PeriodicTask: public TaskBase {
|
||||
protected:
|
||||
|
||||
/**
|
||||
* @brief The period of the task.
|
||||
* @details The period determines the frequency of the task's execution. It is expressed in clock ticks.
|
||||
*/
|
||||
Interval_t period;
|
||||
|
||||
/**
|
||||
* @brief id of the associated OS period
|
||||
*/
|
||||
PeriodId_t periodId;
|
||||
|
||||
/**
|
||||
* @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.
|
||||
* @param A pointer to the task object itself is passed as argument.
|
||||
*/
|
||||
static TaskReturn_t taskEntryPoint( TaskArgument_t argument );
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
void ( *deadlineMissedFunc )( void );
|
||||
|
||||
/**
|
||||
* @brief The function containing the actual functionality of the task.
|
||||
* @image latex act_OPUSPeriodicThread.eps "Activity diagram of the PeriodicThread functionality." width=0.6@textwidth
|
||||
* @image html act_OPUSPeriodicThread.png "Activity diagram of the PeriodicThread functionality."
|
||||
* @details The figure above shows the functional execution of this method. It 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, the taskFunction is called, and
|
||||
* afterwards the checkAndRestartPeriod system call to block the task until the next
|
||||
* period. On missing the deadline, the deadlineMissedFunction is executed.
|
||||
*/
|
||||
void taskFunctionality( void );
|
||||
/**
|
||||
* @brief In this attribute the pointer to the function which shall be executed periodically
|
||||
* is stored.
|
||||
*/
|
||||
ReturnValue_t ( *taskFunction )( TaskBase* );
|
||||
public:
|
||||
/**
|
||||
* @brief The standard constructor of the class.
|
||||
* @details This is the general constructor of the class. In the underlying TaskBase class,
|
||||
* a new operating system task is created. In addition to the TaskBase parameters,
|
||||
* the period, the actual function to be executed and an optional "deadline-missed"
|
||||
* function pointer is passed.
|
||||
* @param priority Sets the priority of a task. Values range from a low 0 to a high 99.
|
||||
* @param stack_size The stack size reserved by the operating system for the task.
|
||||
* @param setPeriod The length of the period with which the task's functionality will be
|
||||
* executed. It is expressed in clock ticks.
|
||||
* @param (*setDeadlineMissedFunc)() The function pointer to the deadline missed function
|
||||
* that shall be assigned.
|
||||
* @param ( *setTaskFunction )( TaskBase* ) A pointer to the actual function to be executed.
|
||||
*/
|
||||
PeriodicTask( const char *name, TaskPriority_t setPriority, size_t setStack, Interval_t setPeriod, void ( *setDeadlineMissedFunc )(), ReturnValue_t ( *setTaskFunction )( TaskBase* ) );
|
||||
|
||||
/**
|
||||
* @brief The destructor of the class.
|
||||
* @details Similar to the destructor in the parent class, no memory clean-ups are necessary.
|
||||
* Thus, the destructor is empty.
|
||||
*/
|
||||
virtual ~PeriodicTask( void );
|
||||
|
||||
/**
|
||||
* @brief The method to start the task.
|
||||
* @details The method starts the task with the respective system call.
|
||||
* Entry point is the taskEntryPoint method described below.
|
||||
* The address of the task object is passed as an argument
|
||||
* to the system call.
|
||||
*/
|
||||
virtual ReturnValue_t startTask( void );
|
||||
};
|
||||
|
||||
#endif /* OPUSPERIODICTASK_H_ */
|
31
tasks/PeriodicTaskIF.h
Normal file
31
tasks/PeriodicTaskIF.h
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef PERIODICTASKIF_H_
|
||||
#define PERIODICTASKIF_H_
|
||||
|
||||
#include <framework/objectmanager/SystemObjectIF.h>
|
||||
class ExecutableObjectIF;
|
||||
/**
|
||||
* New version of TaskIF
|
||||
* Follows RAII principles, i.e. there's no create or delete method.
|
||||
* Minimalistic.
|
||||
*/
|
||||
class PeriodicTaskIF {
|
||||
public:
|
||||
static const uint64_t MINIMUM_STACK_SIZE;
|
||||
/**
|
||||
* @brief A virtual destructor as it is mandatory for interfaces.
|
||||
*/
|
||||
virtual ~PeriodicTaskIF() { }
|
||||
/**
|
||||
* @brief With the startTask method, a created task can be started for the first time.
|
||||
*/
|
||||
virtual ReturnValue_t startTask() = 0;
|
||||
|
||||
virtual ReturnValue_t addComponent(object_id_t) {return HasReturnvaluesIF::RETURN_FAILED;};
|
||||
|
||||
virtual ReturnValue_t sleepFor(uint32_t ms) = 0;
|
||||
|
||||
virtual uint32_t getPeriodMs() const = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif /* PERIODICTASKIF_H_ */
|
@ -1,50 +0,0 @@
|
||||
/*
|
||||
* TaskBase.cpp
|
||||
*
|
||||
* Created on: Nov 5, 2012
|
||||
* Author: baetz
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||
#include <framework/tasks/TaskBase.h>
|
||||
|
||||
TaskBase::TaskBase( TaskPriority_t set_priority, size_t stack_size , const char *name) : isRunning(false) {
|
||||
Name_t osalName = 0;
|
||||
for (uint8_t i = 0; i < 4; i++){
|
||||
if (name[i] == 0){
|
||||
break;
|
||||
}
|
||||
osalName += name[i] << (8*(3-i));
|
||||
}
|
||||
//The task is created with the operating system's system call.
|
||||
ReturnValue_t status = OSAL::createTask(
|
||||
osalName, set_priority,
|
||||
stack_size,
|
||||
OSAL::PREEMPT | OSAL::NO_TIMESLICE | OSAL::NO_ASR, OSAL::FLOATING_POINT,
|
||||
&( this->id )
|
||||
);
|
||||
//TODO: Safe system halt or FDIR call on failed task creation?
|
||||
if( status != RETURN_OK ) {
|
||||
error << "TaskBase::TaskBase: createTask with name " << std::hex << osalName << std::dec << " failed with return code " << (uint32_t)status << std::endl;
|
||||
this->id = 0;
|
||||
} else {
|
||||
// debug << "TaskBase::TaskBase: createTask successful. Name: " << std::hex << new_name << ", ID: " << this->id << std::dec << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
TaskBase::~TaskBase() {
|
||||
OSAL::deleteTask( &(this->id) );
|
||||
}
|
||||
|
||||
TaskId_t TaskBase::getId() {
|
||||
return this->id;
|
||||
}
|
||||
|
||||
void TaskBase::setRunning( bool set ) {
|
||||
this->isRunning = set;
|
||||
}
|
||||
|
||||
uint8_t TaskBase::taskCounter = 0;
|
@ -1,86 +0,0 @@
|
||||
/**
|
||||
* @file TaskBase.h
|
||||
*
|
||||
* @date 11/05/2012
|
||||
* @author Bastian Baetz
|
||||
*
|
||||
* @brief This file contains the definition of the TaskBase class.
|
||||
* It is a reviewed and updated version of a file originally created
|
||||
* by Claas Ziemke in 2010.
|
||||
*/
|
||||
|
||||
#ifndef TASKBASE_H_
|
||||
#define TASKBASE_H_
|
||||
|
||||
|
||||
|
||||
#include <framework/osal/OSAL.h>
|
||||
#include <framework/returnvalues/HasReturnvaluesIF.h>
|
||||
#include <framework/tasks/TaskIF.h>
|
||||
/**
|
||||
* @brief This is the basic task handling class.
|
||||
*
|
||||
* @details The virtual parent class contains attributes and methods to perform basic task operations.
|
||||
* The task is created in the constructor. Next to the main methods to set the functionality
|
||||
* and start the task, it also contains methods to stop execution safely and to return its
|
||||
* identifier.
|
||||
* The whole class was undergoing a major redesign by Bastian Baetz in November 2012 where
|
||||
* unnecessary attributes were removed and task creation was simplified. Also, the class
|
||||
* implements the TaskIF now.
|
||||
*
|
||||
* @author Claas Ziemke
|
||||
*
|
||||
* @date 07/23/2010
|
||||
*
|
||||
* @ingroup task_handling
|
||||
*/
|
||||
class TaskBase : public TaskIF, public HasReturnvaluesIF {
|
||||
protected:
|
||||
/**
|
||||
* @brief The task's name -a user specific information for the operating system- is
|
||||
* generated automatically with the help of this static counter.
|
||||
*/
|
||||
static uint8_t taskCounter;
|
||||
/**
|
||||
* @brief The class stores the task id it got assigned from the operating system in this attribute.
|
||||
* If initialization fails, the id is set to zero.
|
||||
*/
|
||||
TaskId_t id;
|
||||
/**
|
||||
* @brief The isRunning information can be used by child classes to change its operational behavior.
|
||||
* @details It is not used in the TaskBase class itself, but for example in periodic tasks to leave
|
||||
* the periodic activity.
|
||||
*/
|
||||
bool isRunning;
|
||||
public:
|
||||
/**
|
||||
* @brief The constructor creates and initializes a task.
|
||||
* @details This is accomplished by using the operating system call to create a task. The name is
|
||||
* created automatically with the help od taskCounter. Priority and stack size are
|
||||
* adjustable, all other attributes are set with default values.
|
||||
* @param priority Sets the priority of a task. Values range from a low 0 to a high 99.
|
||||
* @param stack_size The stack size reserved by the operating system for the task.
|
||||
* @param nam The name of the Task, as a null-terminated String. Currently max 4 chars supported (excluding Null-terminator), rest will be truncated
|
||||
*/
|
||||
TaskBase( TaskPriority_t priority, size_t stack_size, const char *name);
|
||||
/**
|
||||
* @brief In the destructor, the created task is deleted.
|
||||
*/
|
||||
virtual ~TaskBase();
|
||||
/**
|
||||
* @brief This abstract method must be implemented by child classes to successfully start a task.
|
||||
*/
|
||||
virtual ReturnValue_t startTask() = 0;
|
||||
/**
|
||||
* @brief This method returns the task id of this class.
|
||||
*/
|
||||
TaskId_t getId();
|
||||
/**
|
||||
* @brief With this method, the task "running" state can be set.
|
||||
* @details This typically involves leaving any kind of periodic activity.
|
||||
*/
|
||||
void setRunning( bool set );
|
||||
};
|
||||
|
||||
|
||||
#endif /* TASKBASE_H_ */
|
65
tasks/TaskFactory.h
Normal file
65
tasks/TaskFactory.h
Normal file
@ -0,0 +1,65 @@
|
||||
#ifndef FRAMEWORK_TASKS_TASKFACTORY_H_
|
||||
#define FRAMEWORK_TASKS_TASKFACTORY_H_
|
||||
|
||||
#include <framework/tasks/FixedTimeslotTaskIF.h>
|
||||
#include <framework/tasks/Typedef.h>
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Singleton Class that produces Tasks.
|
||||
*/
|
||||
class TaskFactory{
|
||||
public:
|
||||
virtual ~TaskFactory();
|
||||
/**
|
||||
* Returns the single instance of TaskFactory.
|
||||
* The implementation of #instance is found in its subclasses.
|
||||
* Thus, we choose link-time variability of the instance.
|
||||
*/
|
||||
static TaskFactory* instance();
|
||||
|
||||
/**
|
||||
* Creates a new periodic task and returns the interface pointer.
|
||||
* @param name_ Name of the task
|
||||
* @param taskPriority_ Priority of the task
|
||||
* @param stackSize_ Stack Size of the task
|
||||
* @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
|
||||
*/
|
||||
PeriodicTaskIF* createPeriodicTask(OSAL::TaskName name_,OSAL::TaskPriority taskPriority_,OSAL::TaskStackSize stackSize_,OSAL::TaskPeriod periodInSeconds_,OSAL::TaskDeadlineMissedFunction deadLineMissedFunction_);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param name_ Name of the task
|
||||
* @param taskPriority_ Priority of the task
|
||||
* @param stackSize_ Stack Size of the task
|
||||
* @param period_ Period of the task
|
||||
* @param deadLineMissedFunction_ Function to be called if a deadline was missed
|
||||
* @return FixedTimeslotTaskIF* Pointer to the newly created Task
|
||||
*/
|
||||
FixedTimeslotTaskIF* createFixedTimeslotTask(OSAL::TaskName name_,OSAL::TaskPriority taskPriority_,OSAL::TaskStackSize stackSize_,OSAL::TaskPeriod periodInSeconds_,OSAL::TaskDeadlineMissedFunction deadLineMissedFunction_);
|
||||
|
||||
|
||||
/**
|
||||
* Function to be called to delete a task
|
||||
* @param task The pointer to the task that shall be deleted
|
||||
* @return Success of deletion
|
||||
*/
|
||||
ReturnValue_t deleteTask(PeriodicTaskIF* task);
|
||||
|
||||
private:
|
||||
/**
|
||||
* External instantiation is not allowed.
|
||||
*/
|
||||
TaskFactory();
|
||||
static TaskFactory* factoryInstance;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* FRAMEWORK_TASKS_TASKFACTORY_H_ */
|
@ -1,42 +0,0 @@
|
||||
#ifndef TASKIF_H_
|
||||
#define TASKIF_H_
|
||||
|
||||
/**
|
||||
* \defgroup task_handling Task Handling
|
||||
* This is the group, where all classes associated with Task Handling belong to.
|
||||
* Task handling is based on the task handling methods which the operating system
|
||||
* provides (currently RTEMS).
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This interface provides all basic methods to handle task operations.
|
||||
* @details To uniformly operate different types of tasks, this interface provides methods to
|
||||
* start and stop created tasks and to return the operating system's identifier.
|
||||
*
|
||||
* @date 11/05/2012
|
||||
* @ingroup task_handling
|
||||
* author Bastian Baetz
|
||||
*/
|
||||
class TaskIF {
|
||||
public:
|
||||
/**
|
||||
* @brief A virtual destructor as it is mandatory for interfaces.
|
||||
*/
|
||||
virtual ~TaskIF() { }
|
||||
/**
|
||||
* @brief With the startTask method, a created task can be started for the first time.
|
||||
*/
|
||||
virtual ReturnValue_t startTask() = 0;
|
||||
/**
|
||||
* @brief The getId method returns the task's operating system identifier.
|
||||
*/
|
||||
virtual TaskId_t getId() = 0;
|
||||
/**
|
||||
* @brief With this method, the task "running" state can be set.
|
||||
* @details This typically involves leaving any kind of periodic activity.
|
||||
*/
|
||||
virtual void setRunning( bool set ) = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif /* TASKIF_H_ */
|
21
tasks/Typedef.h
Normal file
21
tasks/Typedef.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef FRAMEWORK_TASKS_TYPEDEF_H_
|
||||
#define FRAMEWORK_TASKS_TYPEDEF_H_
|
||||
|
||||
|
||||
#ifndef API
|
||||
#error Please specify Operating System API. Supported: API=RTEMS_API
|
||||
#elif API == RTEMS_API
|
||||
#include <framework/osal/rtems/RtemsBasic.h>
|
||||
namespace OSAL{
|
||||
typedef const char* TaskName;
|
||||
typedef rtems_task_priority TaskPriority;
|
||||
typedef size_t TaskStackSize;
|
||||
typedef double TaskPeriod;
|
||||
typedef void (*TaskDeadlineMissedFunction)();
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* FRAMEWORK_TASKS_TYPEDEF_H_ */
|
Reference in New Issue
Block a user