From 58008c8db5c2310806833997f7fd5b354e0d433a Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 6 Apr 2020 11:19:05 +0200 Subject: [PATCH 1/8] all fixed slot sequence improvenements, freeRTOS fix --- devicehandlers/FixedSequenceSlot.h | 19 +++--- devicehandlers/FixedSlotSequence.cpp | 87 ++++++++++++++-------------- devicehandlers/FixedSlotSequence.h | 63 ++++++++++++-------- osal/FreeRTOS/FixedTimeslotTask.cpp | 23 +++++--- osal/FreeRTOS/FixedTimeslotTask.h | 1 + 5 files changed, 112 insertions(+), 81 deletions(-) diff --git a/devicehandlers/FixedSequenceSlot.h b/devicehandlers/FixedSequenceSlot.h index 5aff0f4f..b3bac08f 100644 --- a/devicehandlers/FixedSequenceSlot.h +++ b/devicehandlers/FixedSequenceSlot.h @@ -19,29 +19,34 @@ class PeriodicTaskIF; */ class FixedSequenceSlot { public: - FixedSequenceSlot( object_id_t handlerId, uint32_t setTimeMs, int8_t setSequenceId, PeriodicTaskIF* executingTask ); + FixedSequenceSlot( object_id_t handlerId, uint32_t setTimeMs, + int8_t setSequenceId, PeriodicTaskIF* executingTask ); virtual ~FixedSequenceSlot(); /** - * \brief \c handler identifies which device handler object is executed in this slot. + * @brief Handler identifies which device handler object is executed in this slot. */ ExecutableObjectIF* handler; /** - * \brief This attribute defines when a device handler object is executed. + * @brief This attribute defines when a device handler object is executed. * - * \details The pollingTime attribute identifies the time the handler is executed in ms. It must be - * smaller than the period length of the polling sequence, what is ensured by automated calculation - * from a database. + * @details The pollingTime attribute identifies the time the handler is executed in ms. + * It must be smaller than the period length of the polling sequence. */ uint32_t pollingTimeMs; /** * \brief This value defines the type of device communication. * - * \details The state of this value decides what communication routine is called in the PST executable or the device handler object. + * \details The state of this value decides what communication routine is + * called in the PST executable or the device handler object. */ uint8_t opcode; + + bool operator <(const FixedSequenceSlot & fixedSequenceSlot) const { + return pollingTimeMs < fixedSequenceSlot.pollingTimeMs; + } }; diff --git a/devicehandlers/FixedSlotSequence.cpp b/devicehandlers/FixedSlotSequence.cpp index a65dd929..23bb0e78 100644 --- a/devicehandlers/FixedSlotSequence.cpp +++ b/devicehandlers/FixedSlotSequence.cpp @@ -2,22 +2,23 @@ #include FixedSlotSequence::FixedSlotSequence(uint32_t setLengthMs) : - lengthMs(setLengthMs) { + slotLengthMs(setLengthMs) { current = slotList.begin(); } FixedSlotSequence::~FixedSlotSequence() { - std::list::iterator slotIt; - //Iterate through slotList and delete all entries. - slotIt = this->slotList.begin(); - while (slotIt != this->slotList.end()) { - delete (*slotIt); - slotIt++; - } + // This should call the destructor on each list entry. + slotList.clear(); +// SlotListIter slotListIter = this->slotList.begin(); +// //Iterate through slotList and delete all entries. +// while (slotListIter != this->slotList.end()) { +// delete (*slotIt); +// slotIt++; +// } } void FixedSlotSequence::executeAndAdvance() { - (*this->current)->handler->performOperation((*this->current)->opcode); + current->handler->performOperation(current->opcode); // if (returnValue != RETURN_OK) { // this->sendErrorMessage( returnValue ); // } @@ -31,53 +32,50 @@ void FixedSlotSequence::executeAndAdvance() { uint32_t FixedSlotSequence::getIntervalToNextSlotMs() { uint32_t oldTime; - std::list::iterator it; - it = current; + SlotListIter slotListIter = current; // Get the pollingTimeMs of the current slot object. - oldTime = (*it)->pollingTimeMs; + oldTime = slotListIter->pollingTimeMs; // Advance to the next object. - it++; + slotListIter++; // Find the next interval which is not 0. - while (it != slotList.end()) { - if (oldTime != (*it)->pollingTimeMs) { - return (*it)->pollingTimeMs - oldTime; + while (slotListIter != slotList.end()) { + if (oldTime != slotListIter->pollingTimeMs) { + return slotListIter->pollingTimeMs - oldTime; } else { - it++; + slotListIter++; } } // If the list end is reached (this is definitely an interval != 0), // the interval is calculated by subtracting the remaining time of the PST // and adding the start time of the first handler in the list. - it = slotList.begin(); - return lengthMs - oldTime + (*it)->pollingTimeMs; + slotListIter = slotList.begin(); + return slotLengthMs - oldTime + slotListIter->pollingTimeMs; } uint32_t FixedSlotSequence::getIntervalToPreviousSlotMs() { uint32_t currentTime; - std::list::iterator it; - it = current; + SlotListIter slotListIter = current; // Get the pollingTimeMs of the current slot object. - currentTime = (*it)->pollingTimeMs; + currentTime = slotListIter->pollingTimeMs; //if it is the first slot, calculate difference to last slot - if (it == slotList.begin()){ - return lengthMs - (*(--slotList.end()))->pollingTimeMs + currentTime; + if (slotListIter == slotList.begin()){ + return slotLengthMs - (--slotList.end())->pollingTimeMs + currentTime; } // get previous slot - it--; + slotListIter--; - return currentTime - (*it)->pollingTimeMs; + return currentTime - slotListIter->pollingTimeMs; } bool FixedSlotSequence::slotFollowsImmediately() { - uint32_t currentTime = (*current)->pollingTimeMs; - std::list::iterator it; - it = this->current; + uint32_t currentTime = current->pollingTimeMs; + SlotListIter fixedSequenceIter = this->current; // Get the pollingTimeMs of the current slot object. - if (it == slotList.begin()) + if (fixedSequenceIter == slotList.begin()) return false; - it--; - if ((*it)->pollingTimeMs == currentTime) { + fixedSequenceIter--; + if (fixedSequenceIter->pollingTimeMs == currentTime) { return true; } else { return false; @@ -85,31 +83,35 @@ bool FixedSlotSequence::slotFollowsImmediately() { } uint32_t FixedSlotSequence::getLengthMs() const { - return this->lengthMs; + return this->slotLengthMs; } ReturnValue_t FixedSlotSequence::checkSequence() const { - //Iterate through slotList and check successful creation. Checks if timing is ok (must be ascending) and if all handlers were found. + // Iterate through slotList and check successful creation. + // Checks if timing is ok (must be ascending) and if all handlers were found. auto slotIt = slotList.begin(); uint32_t count = 0; uint32_t time = 0; while (slotIt != slotList.end()) { - if ((*slotIt)->handler == NULL) { + if (slotIt->handler == NULL) { error << "FixedSlotSequene::initialize: ObjectId does not exist!" << std::endl; count++; - } else if ((*slotIt)->pollingTimeMs < time) { + } else if (slotIt->pollingTimeMs < time) { error << "FixedSlotSequence::initialize: Time: " - << (*slotIt)->pollingTimeMs + << slotIt->pollingTimeMs << " is smaller than previous with " << time << std::endl; count++; } else { - //All ok, print slot. -// (*slotIt)->print(); + // All ok, print slot. + //info << "Current slot polling time: " << std::endl; + //info << std::dec << slotIt->pollingTimeMs << std::endl; } - time = (*slotIt)->pollingTimeMs; + time = slotIt->pollingTimeMs; slotIt++; } + //info << "Number of elements in slot list: " + // << slotList.size() << std::endl; if (count > 0) { return HasReturnvaluesIF::RETURN_FAILED; } @@ -118,8 +120,7 @@ ReturnValue_t FixedSlotSequence::checkSequence() const { void FixedSlotSequence::addSlot(object_id_t componentId, uint32_t slotTimeMs, int8_t executionStep, PeriodicTaskIF* executingTask) { - this->slotList.push_back( - new FixedSequenceSlot(componentId, slotTimeMs, executionStep, - executingTask)); + this->slotList.insert(FixedSequenceSlot(componentId, slotTimeMs, executionStep, + executingTask)); this->current = slotList.begin(); } diff --git a/devicehandlers/FixedSlotSequence.h b/devicehandlers/FixedSlotSequence.h index f8fd9a36..813d2fce 100644 --- a/devicehandlers/FixedSlotSequence.h +++ b/devicehandlers/FixedSlotSequence.h @@ -4,11 +4,15 @@ #include #include #include +#include + +using SlotList = std::multiset; +using SlotListIter = std::multiset::iterator; /** - * \brief This class is the representation of a Polling Sequence Table in software. + * @brief This class is the representation of a Polling Sequence Table in software. * - * \details The FixedSlotSequence object maintains the dynamic execution of device handler objects. + * @details The FixedSlotSequence object maintains the dynamic execution of device handler objects. * The main idea is to create a list of device handlers, to announce all handlers to the * polling sequence and to maintain a list of polling slot objects. This slot list represents the * Polling Sequence Table in software. Each polling slot contains information to indicate when and @@ -19,29 +23,37 @@ class FixedSlotSequence { public: + /** - * \brief The constructor of the FixedSlotSequence object. + * @brief The constructor of the FixedSlotSequence object. * - * \details The constructor takes two arguments, the period length and the init function. + * @details The constructor takes two arguments, the period length and the init function. * - * \param setLength The period length, expressed in ms. + * @param setLength The period length, expressed in ms. */ FixedSlotSequence(uint32_t setLengthMs); /** - * \brief The destructor of the FixedSlotSequence object. + * @brief The destructor of the FixedSlotSequence object. * - * \details The destructor frees all allocated memory by iterating through the slotList + * @details The destructor frees all allocated memory by iterating through the slotList * and deleting all allocated resources. */ virtual ~FixedSlotSequence(); /** - * \brief This is a method to add an PollingSlot object to slotList. + * @brief This is a method to add an PollingSlot object to slotList. * - * \details Here, a polling slot object is added to the slot list. It is appended + * @details Here, a polling slot object is added to the slot list. It is appended * to the end of the list. The list is currently NOT reordered. * Afterwards, the iterator current is set to the beginning of the list. + * @param Object ID of the object to add + * @param setTime Value between (0 to 1) * slotLengthMs, when a FixedTimeslotTask + * will be called inside the slot period. + * @param setSequenceId ID which can be used to distinguish + * different task operations + * @param + * @param */ void addSlot(object_id_t handlerId, uint32_t setTime, int8_t setSequenceId, PeriodicTaskIF* executingTask); @@ -57,11 +69,14 @@ public: /** * \brief This method returns the time until the next software component is invoked. * - * \details This method is vitally important for the operation of the PST. By fetching the polling time - * of the current slot and that of the next one (or the first one, if the list end is reached) - * it calculates and returns the interval in milliseconds within which the handler execution - * shall take place. If the next slot has the same time as the current one, it is ignored until - * a slot with different time or the end of the PST is found. + * \details + * This method is vitally important for the operation of the PST. + * By fetching the polling time of the current slot and that of the + * next one (or the first one, if the list end is reached) + * it calculates and returns the interval in milliseconds within + * which the handler execution shall take place. + * If the next slot has the same time as the current one, it is ignored + * until a slot with different time or the end of the PST is found. */ uint32_t getIntervalToNextSlotMs(); @@ -75,12 +90,12 @@ public: uint32_t getIntervalToPreviousSlotMs(); /** - * \brief This method returns the length of this FixedSlotSequence instance. + * @brief This method returns the length of this FixedSlotSequence instance. */ uint32_t getLengthMs() const; /** - * \brief The method to execute the device handler entered in the current OPUSPollingSlot object. + * \brief The method to execute the device handler entered in the current PollingSlot object. * * \details Within this method the device handler object to be executed is chosen by looking up the * handler address of the current slot in the handlerMap. Either the device handler's @@ -91,27 +106,27 @@ public: void executeAndAdvance(); /** - * \brief An iterator that indicates the current polling slot to execute. + * @brief An iterator that indicates the current polling slot to execute. * - * \details This is an iterator for slotList and always points to the polling slot which is executed next. + * @details This is an iterator for slotList and always points to the polling slot which is executed next. */ - std::list::iterator current; + SlotListIter current; - ReturnValue_t checkSequence() const; + virtual ReturnValue_t checkSequence() const; protected: /** - * \brief This list contains all OPUSPollingSlot objects, defining order and execution time of the + * @brief This list contains all PollingSlot objects, defining order and execution time of the * device handler objects. * - * \details The slot list is a std:list object that contains all created OPUSPollingSlot instances. + * @details The slot list is a std:list object that contains all created PollingSlot instances. * They are NOT ordered automatically, so by adding entries, the correct order needs to be ensured. * By iterating through this list the polling sequence is executed. Two entries with identical * polling times are executed immediately one after another. */ - std::list slotList; + SlotList slotList; - uint32_t lengthMs; + uint32_t slotLengthMs; }; #endif /* FIXEDSLOTSEQUENCE_H_ */ diff --git a/osal/FreeRTOS/FixedTimeslotTask.cpp b/osal/FreeRTOS/FixedTimeslotTask.cpp index 00fd73d3..b1c97420 100644 --- a/osal/FreeRTOS/FixedTimeslotTask.cpp +++ b/osal/FreeRTOS/FixedTimeslotTask.cpp @@ -19,8 +19,7 @@ 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. - FixedTimeslotTask *originalTask( - reinterpret_cast(argument)); + FixedTimeslotTask *originalTask(reinterpret_cast(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. @@ -58,8 +57,19 @@ ReturnValue_t FixedTimeslotTask::startTask() { ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId, uint32_t slotTimeMs, int8_t executionStep) { - pst.addSlot(componentId, slotTimeMs, executionStep, this); - return HasReturnvaluesIF::RETURN_OK; + if (objectManager->get(componentId) != NULL) { + if(slotTimeMs == 0) { + // TODO: FreeRTOS throws errors for zero values. + // maybe there is a better solution than this. + slotTimeMs = 1; + } + pst.addSlot(componentId, slotTimeMs, executionStep, this); + return HasReturnvaluesIF::RETURN_OK; + } + + error << "Component " << std::hex << componentId + << " not found, not adding it to pst" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; } uint32_t FixedTimeslotTask::getPeriodMs() const { @@ -72,10 +82,10 @@ 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. - std::list::iterator it = pst.current; + SlotListIter slotListIter = pst.current; //The start time for the first entry is read. - uint32_t intervalMs = (*it)->pollingTimeMs; + uint32_t intervalMs = slotListIter->pollingTimeMs; TickType_t interval = pdMS_TO_TICKS(intervalMs); TickType_t xLastWakeTime; @@ -110,4 +120,3 @@ ReturnValue_t FixedTimeslotTask::sleepFor(uint32_t ms) { vTaskDelay(pdMS_TO_TICKS(ms)); return HasReturnvaluesIF::RETURN_OK; } - diff --git a/osal/FreeRTOS/FixedTimeslotTask.h b/osal/FreeRTOS/FixedTimeslotTask.h index bed13051..1ab8724f 100644 --- a/osal/FreeRTOS/FixedTimeslotTask.h +++ b/osal/FreeRTOS/FixedTimeslotTask.h @@ -51,6 +51,7 @@ public: ReturnValue_t checkSequence() const; ReturnValue_t sleepFor(uint32_t ms); + protected: bool started; TaskHandle_t handle; From cee8b4dc37eb897fa2bedd44c07fd26781cc0c38 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 19 Apr 2020 21:37:55 +0200 Subject: [PATCH 2/8] name slotLengthMs reverted to lengthMs --- devicehandlers/FixedSlotSequence.cpp | 8 ++++---- devicehandlers/FixedSlotSequence.h | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/devicehandlers/FixedSlotSequence.cpp b/devicehandlers/FixedSlotSequence.cpp index 23bb0e78..07439e5d 100644 --- a/devicehandlers/FixedSlotSequence.cpp +++ b/devicehandlers/FixedSlotSequence.cpp @@ -2,7 +2,7 @@ #include FixedSlotSequence::FixedSlotSequence(uint32_t setLengthMs) : - slotLengthMs(setLengthMs) { + lengthMs(setLengthMs) { current = slotList.begin(); } @@ -49,7 +49,7 @@ uint32_t FixedSlotSequence::getIntervalToNextSlotMs() { // the interval is calculated by subtracting the remaining time of the PST // and adding the start time of the first handler in the list. slotListIter = slotList.begin(); - return slotLengthMs - oldTime + slotListIter->pollingTimeMs; + return lengthMs - oldTime + slotListIter->pollingTimeMs; } uint32_t FixedSlotSequence::getIntervalToPreviousSlotMs() { @@ -60,7 +60,7 @@ uint32_t FixedSlotSequence::getIntervalToPreviousSlotMs() { //if it is the first slot, calculate difference to last slot if (slotListIter == slotList.begin()){ - return slotLengthMs - (--slotList.end())->pollingTimeMs + currentTime; + return lengthMs - (--slotList.end())->pollingTimeMs + currentTime; } // get previous slot slotListIter--; @@ -83,7 +83,7 @@ bool FixedSlotSequence::slotFollowsImmediately() { } uint32_t FixedSlotSequence::getLengthMs() const { - return this->slotLengthMs; + return this->lengthMs; } ReturnValue_t FixedSlotSequence::checkSequence() const { diff --git a/devicehandlers/FixedSlotSequence.h b/devicehandlers/FixedSlotSequence.h index 813d2fce..a198421f 100644 --- a/devicehandlers/FixedSlotSequence.h +++ b/devicehandlers/FixedSlotSequence.h @@ -23,7 +23,6 @@ using SlotListIter = std::multiset::iterator; class FixedSlotSequence { public: - /** * @brief The constructor of the FixedSlotSequence object. * @@ -126,7 +125,7 @@ protected: */ SlotList slotList; - uint32_t slotLengthMs; + uint32_t lengthMs; }; #endif /* FIXEDSLOTSEQUENCE_H_ */ From e39d669ed863a4ba7fc754c738ffb479ea7d9d00 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 30 Apr 2020 22:03:16 +0200 Subject: [PATCH 3/8] put linux prinouts in namespace --- osal/linux/FixedTimeslotTask.cpp | 14 +++++++--- osal/linux/MessageQueue.cpp | 44 ++++++++++++++++++++------------ osal/linux/Mutex.cpp | 8 +++--- osal/linux/PeriodicPosixTask.cpp | 4 +-- osal/linux/PeriodicPosixTask.h | 3 ++- osal/linux/PosixThread.cpp | 42 +++++++++++++++++++----------- osal/linux/Timer.cpp | 3 ++- 7 files changed, 76 insertions(+), 42 deletions(-) diff --git a/osal/linux/FixedTimeslotTask.cpp b/osal/linux/FixedTimeslotTask.cpp index 99cbf818..04ceb4e6 100644 --- a/osal/linux/FixedTimeslotTask.cpp +++ b/osal/linux/FixedTimeslotTask.cpp @@ -9,7 +9,9 @@ uint32_t FixedTimeslotTask::deadlineMissedCount = 0; const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = PTHREAD_STACK_MIN; -FixedTimeslotTask::FixedTimeslotTask(const char* name_, int priority_, size_t stackSize_, uint32_t periodMs_):PosixThread(name_,priority_,stackSize_),pst(periodMs_),started(false) { +FixedTimeslotTask::FixedTimeslotTask(const char* name_, int priority_, + size_t stackSize_, uint32_t periodMs_): + PosixThread(name_,priority_,stackSize_),pst(periodMs_),started(false) { } FixedTimeslotTask::~FixedTimeslotTask() { @@ -40,6 +42,12 @@ uint32_t FixedTimeslotTask::getPeriodMs() const { ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId, uint32_t slotTimeMs, int8_t executionStep) { + if (!objectManager->get(componentId)) { + sif::error << "Component " << std::hex << componentId + << " not found, not adding it to pst" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + pst.addSlot(componentId, slotTimeMs, executionStep, this); return HasReturnvaluesIF::RETURN_OK; } @@ -80,7 +88,7 @@ void FixedTimeslotTask::taskFunctionality() { void FixedTimeslotTask::missedDeadlineCounter() { FixedTimeslotTask::deadlineMissedCount++; if (FixedTimeslotTask::deadlineMissedCount % 10 == 0) { - error << "PST missed " << FixedTimeslotTask::deadlineMissedCount - << " deadlines." << std::endl; + sif::error << "PST missed " << FixedTimeslotTask::deadlineMissedCount + << " deadlines." << std::endl; } } diff --git a/osal/linux/MessageQueue.cpp b/osal/linux/MessageQueue.cpp index a2e87875..edabe946 100644 --- a/osal/linux/MessageQueue.cpp +++ b/osal/linux/MessageQueue.cpp @@ -17,11 +17,11 @@ MessageQueue::MessageQueue(size_t message_depth, size_t max_message_size) : attributes.mq_maxmsg = message_depth; attributes.mq_msgsize = max_message_size; attributes.mq_flags = 0; //Flags are ignored on Linux during mq_open - //Set the name of the queue sprintf(name, "/Q%u\n", queueCounter++); - //Create a nonblocking queue if the name is available (the queue is Read and writable for the owner as well as the group) + //Create a nonblocking queue if the name is available (the queue is Read and + // writable for the owner as well as the group) mqd_t tempId = mq_open(name, O_NONBLOCK | O_RDWR | O_CREAT | O_EXCL, S_IWUSR | S_IREAD | S_IWGRP | S_IRGRP | S_IROTH | S_IWOTH, &attributes); if (tempId == -1) { @@ -32,8 +32,8 @@ MessageQueue::MessageQueue(size_t message_depth, size_t max_message_size) : //We unlink the other queue int status = mq_unlink(name); if (status != 0) { - error << "mq_unlink Failed with status: " << strerror(errno) - << std::endl; + sif::error << "mq_unlink Failed with status: " << strerror(errno) + << std::endl; } else { //Successful unlinking, try to open again mqd_t tempId = mq_open(name, @@ -47,7 +47,7 @@ MessageQueue::MessageQueue(size_t message_depth, size_t max_message_size) : } } //Failed either the first time or the second time - error << "MessageQueue::MessageQueue: Creating Queue " << std::hex + sif::error << "MessageQueue::MessageQueue: Creating Queue " << std::hex << name << std::dec << " failed with status: " << strerror(errno) << std::endl; } else { @@ -59,11 +59,13 @@ MessageQueue::MessageQueue(size_t message_depth, size_t max_message_size) : MessageQueue::~MessageQueue() { int status = mq_close(this->id); if(status != 0){ - error << "MessageQueue::Destructor: mq_close Failed with status: " << strerror(errno) <(message->getBuffer()),message->MAX_MESSAGE_SIZE,&messagePriority); + int status = mq_receive(id,reinterpret_cast(message->getBuffer()), + message->MAX_MESSAGE_SIZE,&messagePriority); if (status > 0) { this->lastPartner = message->getSender(); //Check size of incoming message. @@ -114,7 +117,8 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message) { return MessageQueueIF::EMPTY; case EBADF: //mqdes doesn't represent a valid queue open for reading. - error << "MessageQueue::receive: configuration error " << strerror(errno) << std::endl; + sif::error << "MessageQueue::receive: configuration error " + << strerror(errno) << std::endl; /*NO BREAK*/ case EINVAL: /* @@ -123,7 +127,8 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message) { * * The number of bytes requested, msg_len is less than zero. * * msg_len is anything other than the mq_msgsize of the specified queue, and the QNX extended option MQ_READBUF_DYNAMIC hasn't been set in the queue's mq_flags. */ - error << "MessageQueue::receive: configuration error " << strerror(errno) << std::endl; + sif::error << "MessageQueue::receive: configuration error " + << strerror(errno) << std::endl; /*NO BREAK*/ case EMSGSIZE: /* @@ -131,7 +136,8 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message) { * * the QNX extended option MQ_READBUF_DYNAMIC hasn't been set, and the given msg_len is shorter than the mq_msgsize for the given queue. * * the extended option MQ_READBUF_DYNAMIC has been set, but the given msg_len is too short for the message that would have been received. */ - error << "MessageQueue::receive: configuration error " << strerror(errno) << std::endl; + sif::error << "MessageQueue::receive: configuration error " + << strerror(errno) << std::endl; /*NO BREAK*/ case EINTR: //The operation was interrupted by a signal. @@ -154,7 +160,8 @@ ReturnValue_t MessageQueue::flush(uint32_t* count) { switch(errno){ case EBADF: //mqdes doesn't represent a valid message queue. - error << "MessageQueue::flush configuration error, called flush with an invalid queue ID" << std::endl; + sif::error << "MessageQueue::flush configuration error, " + "called flush with an invalid queue ID" << std::endl; /*NO BREAK*/ case EINVAL: //mq_attr is NULL @@ -169,7 +176,8 @@ ReturnValue_t MessageQueue::flush(uint32_t* count) { switch(errno){ case EBADF: //mqdes doesn't represent a valid message queue. - error << "MessageQueue::flush configuration error, called flush with an invalid queue ID" << std::endl; + sif::error << "MessageQueue::flush configuration error, " + "called flush with an invalid queue ID" << std::endl; /*NO BREAK*/ case EINVAL: /* @@ -237,7 +245,9 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, return MessageQueueIF::FULL; case EBADF: //mq_des doesn't represent a valid message queue descriptor, or mq_des wasn't opened for writing. - error << "MessageQueue::sendMessage: Configuration error " << strerror(errno) << " in mq_send mqSendTo: " << sendTo << " sent from " << sentFrom << std::endl; + sif::error << "MessageQueue::sendMessage: Configuration error " + << strerror(errno) << " in mq_send mqSendTo: " << sendTo + << " sent from " << sentFrom << std::endl; /*NO BREAK*/ case EINTR: //The call was interrupted by a signal. @@ -248,9 +258,11 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, * * msg_len is negative. * * msg_prio is greater than MQ_PRIO_MAX. * * msg_prio is less than 0. - * * MQ_PRIO_RESTRICT is set in the mq_attr of mq_des, and msg_prio is greater than the priority of the calling process. + * * MQ_PRIO_RESTRICT is set in the mq_attr of mq_des, + * and msg_prio is greater than the priority of the calling process. * */ - error << "MessageQueue::sendMessage: Configuration error " << strerror(errno) << " in mq_send" << std::endl; + sif::error << "MessageQueue::sendMessage: Configuration error " + << strerror(errno) << " in mq_send" << std::endl; /*NO BREAK*/ case EMSGSIZE: //The msg_len is greater than the msgsize associated with the specified queue. diff --git a/osal/linux/Mutex.cpp b/osal/linux/Mutex.cpp index 055270b3..36bb3ce4 100644 --- a/osal/linux/Mutex.cpp +++ b/osal/linux/Mutex.cpp @@ -13,22 +13,22 @@ Mutex::Mutex() { pthread_mutexattr_t mutexAttr; int status = pthread_mutexattr_init(&mutexAttr); if (status != 0) { - error << "Mutex: Attribute init failed with: " << strerror(status) << std::endl; + sif::error << "Mutex: Attribute init failed with: " << strerror(status) << std::endl; } status = pthread_mutexattr_setprotocol(&mutexAttr, PTHREAD_PRIO_INHERIT); if (status != 0) { - error << "Mutex: Attribute set PRIO_INHERIT failed with: " << strerror(status) + sif::error << "Mutex: Attribute set PRIO_INHERIT failed with: " << strerror(status) << std::endl; } status = pthread_mutex_init(&mutex, &mutexAttr); if (status != 0) { - error << "Mutex: creation with name, id " << mutex.__data.__count + sif::error << "Mutex: creation with name, id " << mutex.__data.__count << ", " << " failed with " << strerror(status) << std::endl; } //After a mutex attributes object has been used to initialize one or more mutexes, any function affecting the attributes object (including destruction) shall not affect any previously initialized mutexes. status = pthread_mutexattr_destroy(&mutexAttr); if (status != 0) { - error << "Mutex: Attribute destroy failed with " << strerror(status) << std::endl; + sif::error << "Mutex: Attribute destroy failed with " << strerror(status) << std::endl; } } diff --git a/osal/linux/PeriodicPosixTask.cpp b/osal/linux/PeriodicPosixTask.cpp index ee3c5c4a..b754c3f4 100644 --- a/osal/linux/PeriodicPosixTask.cpp +++ b/osal/linux/PeriodicPosixTask.cpp @@ -56,9 +56,9 @@ void PeriodicPosixTask::taskFunctionality(void){ char name[20] = {0}; int status = pthread_getname_np(pthread_self(),name,sizeof(name)); if(status==0){ - error << "ObjectTask: " << name << " Deadline missed." << std::endl; + sif::error << "ObjectTask: " << name << " Deadline missed." << std::endl; }else{ - error << "ObjectTask: X Deadline missed. " << status << std::endl; + sif::error << "ObjectTask: X Deadline missed. " << status << std::endl; } if (this->deadlineMissedFunc != NULL) { this->deadlineMissedFunc(); diff --git a/osal/linux/PeriodicPosixTask.h b/osal/linux/PeriodicPosixTask.h index e3fa5722..43647eda 100644 --- a/osal/linux/PeriodicPosixTask.h +++ b/osal/linux/PeriodicPosixTask.h @@ -9,7 +9,8 @@ class PeriodicPosixTask: public PosixThread, public PeriodicTaskIF { public: - PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_, uint32_t period_, void(*deadlineMissedFunc_)()); + PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_, + uint32_t period_, void(*deadlineMissedFunc_)()); virtual ~PeriodicPosixTask(); /** * @brief The method to start the task. diff --git a/osal/linux/PosixThread.cpp b/osal/linux/PosixThread.cpp index 2f0176c9..899700f0 100644 --- a/osal/linux/PosixThread.cpp +++ b/osal/linux/PosixThread.cpp @@ -22,7 +22,8 @@ ReturnValue_t PosixThread::sleep(uint64_t ns) { //The nanosleep() function was interrupted by a signal. return HasReturnvaluesIF::RETURN_FAILED; case EINVAL: - //The rqtp argument specified a nanosecond value less than zero or greater than or equal to 1000 million. + //The rqtp argument specified a nanosecond value less than zero or + // greater than or equal to 1000 million. return HasReturnvaluesIF::RETURN_FAILED; default: return HasReturnvaluesIF::RETURN_FAILED; @@ -40,8 +41,8 @@ void PosixThread::suspend() { sigaddset(&waitSignal, SIGUSR1); sigwait(&waitSignal, &caughtSig); if (caughtSig != SIGUSR1) { - error << "FixedTimeslotTask: Unknown Signal received: " << caughtSig - << std::endl; + sif::error << "FixedTimeslotTask: Unknown Signal received: " << + caughtSig << std::endl; } } @@ -112,14 +113,15 @@ uint64_t PosixThread::getCurrentMonotonicTimeMs(){ return currentTime_ms; } -PosixThread::PosixThread(const char* name_, int priority_, size_t stackSize_):thread(0),priority(priority_),stackSize(stackSize_) { +PosixThread::PosixThread(const char* name_, int priority_, size_t stackSize_): + thread(0),priority(priority_),stackSize(stackSize_) { strcpy(name,name_); } void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) { - debug << "PosixThread::createTask" << std::endl; + //sif::debug << "PosixThread::createTask" << std::endl; /* * The attr argument points to a pthread_attr_t structure whose contents are used at thread creation time to determine attributes for the new @@ -130,35 +132,41 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) { pthread_attr_t attributes; int status = pthread_attr_init(&attributes); if(status != 0){ - error << "Posix Thread attribute init failed with: " << strerror(status) << std::endl; + sif::error << "Posix Thread attribute init failed with: " << + strerror(status) << std::endl; } void* sp; status = posix_memalign(&sp, sysconf(_SC_PAGESIZE), stackSize); if(status != 0){ - error << "Posix Thread stack init failed with: " << strerror(status) << std::endl; + sif::error << "Posix Thread stack init failed with: " << + strerror(status) << std::endl; } status = pthread_attr_setstack(&attributes, sp, stackSize); if(status != 0){ - error << "Posix Thread attribute setStack failed with: " << strerror(status) << std::endl; + sif::error << "Posix Thread attribute setStack failed with: " << + strerror(status) << std::endl; } status = pthread_attr_setinheritsched(&attributes, PTHREAD_EXPLICIT_SCHED); if(status != 0){ - error << "Posix Thread attribute setinheritsched failed with: " << strerror(status) << std::endl; + sif::error << "Posix Thread attribute setinheritsched failed with: " << + strerror(status) << std::endl; } //TODO FIFO -> This needs root privileges for the process status = pthread_attr_setschedpolicy(&attributes,SCHED_FIFO); if(status != 0){ - error << "Posix Thread attribute schedule policy failed with: " << strerror(status) << std::endl; + sif::error << "Posix Thread attribute schedule policy failed with: " << + strerror(status) << std::endl; } sched_param scheduleParams; scheduleParams.__sched_priority = priority; status = pthread_attr_setschedparam(&attributes, &scheduleParams); if(status != 0){ - error << "Posix Thread attribute schedule params failed with: " << strerror(status) << std::endl; + sif::error << "Posix Thread attribute schedule params failed with: " << + strerror(status) << std::endl; } //Set Signal Mask for suspend until startTask is called @@ -167,22 +175,26 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) { sigaddset(&waitSignal, SIGUSR1); status = pthread_sigmask(SIG_BLOCK, &waitSignal, NULL); if(status != 0){ - error << "Posix Thread sigmask failed failed with: " << strerror(status) << " errno: " << strerror(errno) << std::endl; + sif::error << "Posix Thread sigmask failed failed with: " << + strerror(status) << " errno: " << strerror(errno) << std::endl; } status = pthread_create(&thread,&attributes,fnc_,arg_); if(status != 0){ - error << "Posix Thread create failed with: " << strerror(status) << std::endl; + sif::error << "Posix Thread create failed with: " << + strerror(status) << std::endl; } status = pthread_setname_np(thread,name); if(status != 0){ - error << "Posix Thread setname failed with: " << strerror(status) << std::endl; + sif::error << "Posix Thread setname failed with: " << + strerror(status) << std::endl; } status = pthread_attr_destroy(&attributes); if(status!=0){ - error << "Posix Thread attribute destroy failed with: " << strerror(status) << std::endl; + sif::error << "Posix Thread attribute destroy failed with: " << + strerror(status) << std::endl; } } diff --git a/osal/linux/Timer.cpp b/osal/linux/Timer.cpp index 2347e39d..5e27c328 100644 --- a/osal/linux/Timer.cpp +++ b/osal/linux/Timer.cpp @@ -9,7 +9,8 @@ Timer::Timer() { sigEvent.sigev_value.sival_ptr = &timerId; int status = timer_create(CLOCK_MONOTONIC, &sigEvent, &timerId); if(status!=0){ - error << "Timer creation failed with: " << status << " errno: " << errno << std::endl; + sif::error << "Timer creation failed with: " << status << + " errno: " << errno << std::endl; } } From 3b63dd72e3a6fc2dd0bebabe89073de9d49d8789 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 7 May 2020 19:41:42 +0200 Subject: [PATCH 4/8] added missing sif prefixes --- devicehandlers/FixedSlotSequence.cpp | 2 +- osal/FreeRTOS/FixedTimeslotTask.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/devicehandlers/FixedSlotSequence.cpp b/devicehandlers/FixedSlotSequence.cpp index 74a242cd..2fa13fae 100644 --- a/devicehandlers/FixedSlotSequence.cpp +++ b/devicehandlers/FixedSlotSequence.cpp @@ -90,7 +90,7 @@ uint32_t FixedSlotSequence::getLengthMs() const { ReturnValue_t FixedSlotSequence::checkSequence() const { if(slotList.empty()) { - error << "Fixed Slot Sequence: Slot list is empty!" << std::endl; + sif::error << "Fixed Slot Sequence: Slot list is empty!" << std::endl; return HasReturnvaluesIF::RETURN_FAILED; } auto slotIt = slotList.begin(); diff --git a/osal/FreeRTOS/FixedTimeslotTask.cpp b/osal/FreeRTOS/FixedTimeslotTask.cpp index 64152ab7..fb3c3b03 100644 --- a/osal/FreeRTOS/FixedTimeslotTask.cpp +++ b/osal/FreeRTOS/FixedTimeslotTask.cpp @@ -67,7 +67,7 @@ ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId, return HasReturnvaluesIF::RETURN_OK; } - error << "Component " << std::hex << componentId << + sif::error << "Component " << std::hex << componentId << " not found, not adding it to pst" << std::endl; return HasReturnvaluesIF::RETURN_FAILED; } From 3d8a152496cb05b1675f5f1bf4ee1a8e579e18c0 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 11 May 2020 17:14:12 +0200 Subject: [PATCH 5/8] removed newline --- osal/FreeRTOS/FixedTimeslotTask.h | 1 - 1 file changed, 1 deletion(-) diff --git a/osal/FreeRTOS/FixedTimeslotTask.h b/osal/FreeRTOS/FixedTimeslotTask.h index 1ab8724f..bed13051 100644 --- a/osal/FreeRTOS/FixedTimeslotTask.h +++ b/osal/FreeRTOS/FixedTimeslotTask.h @@ -51,7 +51,6 @@ public: ReturnValue_t checkSequence() const; ReturnValue_t sleepFor(uint32_t ms); - protected: bool started; TaskHandle_t handle; From eb376318c3ad8a415649fd8062db35506635b73a Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 11 May 2020 17:20:10 +0200 Subject: [PATCH 6/8] comment format --- devicehandlers/FixedSlotSequence.h | 50 ++++++++++++++++++------------ 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/devicehandlers/FixedSlotSequence.h b/devicehandlers/FixedSlotSequence.h index 2fd866ac..fa4c4aeb 100644 --- a/devicehandlers/FixedSlotSequence.h +++ b/devicehandlers/FixedSlotSequence.h @@ -3,7 +3,6 @@ #include #include -#include #include using SlotList = std::multiset; @@ -72,9 +71,10 @@ public: bool slotFollowsImmediately(); /** - * \brief This method returns the time until the next software component is invoked. + * @brief This method returns the time until the next software + * component is invoked. * - * \details + * @details * This method is vitally important for the operation of the PST. * By fetching the polling time of the current slot and that of the * next one (or the first one, if the list end is reached) @@ -86,11 +86,15 @@ public: uint32_t getIntervalToNextSlotMs(); /** - * \brief This method returns the time difference between the current slot and the previous slot + * @brief This method returns the time difference between the current + * slot and the previous slot * - * \details This method is vitally important for the operation of the PST. By fetching the polling time - * of the current slot and that of the prevous one (or the last one, if the slot is the first one) - * it calculates and returns the interval in milliseconds that the handler execution shall be delayed. + * @details + * This method is vitally important for the operation of the PST. + * By fetching the polling time of the current slot and that of the previous + * one (or the last one, if the slot is the first one) it calculates and + * returns the interval in milliseconds that the handler execution shall + * be delayed. */ uint32_t getIntervalToPreviousSlotMs(); @@ -100,20 +104,24 @@ public: uint32_t getLengthMs() const; /** - * \brief The method to execute the device handler entered in the current PollingSlot object. + * @brief The method to execute the device handler entered in the current + * PollingSlot object. * - * \details Within this method the device handler object to be executed is chosen by looking up the - * handler address of the current slot in the handlerMap. Either the device handler's - * talkToInterface or its listenToInterface method is invoked, depending on the isTalking flag - * of the polling slot. After execution the iterator current is increased or, by reaching the - * end of slotList, reset to the beginning. + * @details + * Within this method the device handler object to be executed is chosen by + * looking up the handler address of the current slot in the handlerMap. + * Either the device handler's talkToInterface or its listenToInterface + * method is invoked, depending on the isTalking flag of the polling slot. + * After execution the iterator current is increased or, by reaching the + * end of slotList, reset to the beginning. */ void executeAndAdvance(); /** * @brief An iterator that indicates the current polling slot to execute. * - * @details This is an iterator for slotList and always points to the polling slot which is executed next. + * @details This is an iterator for slotList and always points to the + * polling slot which is executed next. */ SlotListIter current; @@ -127,13 +135,15 @@ public: protected: /** - * @brief This list contains all PollingSlot objects, defining order and execution time of the - * device handler objects. + * @brief This list contains all PollingSlot objects, defining order and + * execution time of the device handler objects. * - * @details The slot list is a std:list object that contains all created PollingSlot instances. - * They are NOT ordered automatically, so by adding entries, the correct order needs to be ensured. - * By iterating through this list the polling sequence is executed. Two entries with identical - * polling times are executed immediately one after another. + * @details + * The slot list is a std:list object that contains all created + * PollingSlot instances. They are NOT ordered automatically, so by + * adding entries, the correct order needs to be ensured. By iterating + * through this list the polling sequence is executed. Two entries with + * identical polling times are executed immediately one after another. */ SlotList slotList; From 26103aa8ccd15ca347ee885cd34c98cebdeeaa10 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 11 May 2020 17:21:24 +0200 Subject: [PATCH 7/8] fixed sequence slot comments --- devicehandlers/FixedSequenceSlot.cpp | 3 +-- devicehandlers/FixedSequenceSlot.h | 9 +++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/devicehandlers/FixedSequenceSlot.cpp b/devicehandlers/FixedSequenceSlot.cpp index 29e7ee6a..bb97a8e5 100644 --- a/devicehandlers/FixedSequenceSlot.cpp +++ b/devicehandlers/FixedSequenceSlot.cpp @@ -16,6 +16,5 @@ FixedSequenceSlot::FixedSequenceSlot(object_id_t handlerId, uint32_t setTime, handler->setTaskIF(executingTask); } -FixedSequenceSlot::~FixedSequenceSlot() { -} +FixedSequenceSlot::~FixedSequenceSlot() {} diff --git a/devicehandlers/FixedSequenceSlot.h b/devicehandlers/FixedSequenceSlot.h index b3bac08f..b18d2768 100644 --- a/devicehandlers/FixedSequenceSlot.h +++ b/devicehandlers/FixedSequenceSlot.h @@ -13,9 +13,10 @@ class PeriodicTaskIF; /** - * \brief This class is the representation of a single polling sequence table entry. + * @brief This class is the representation of a single polling sequence table entry. * - * \details The PollingSlot class is the representation of a single polling sequence table entry. + * @details The PollingSlot class is the representation of a single polling + * sequence table entry. */ class FixedSequenceSlot { public: @@ -37,9 +38,9 @@ public: uint32_t pollingTimeMs; /** - * \brief This value defines the type of device communication. + * @brief This value defines the type of device communication. * - * \details The state of this value decides what communication routine is + * @details The state of this value decides what communication routine is * called in the PST executable or the device handler object. */ uint8_t opcode; From 77565c741245a936cbbb7504aa8d432bd7b5d71e Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 11 May 2020 19:20:21 +0200 Subject: [PATCH 8/8] additional comment for oprator overload --- devicehandlers/FixedSequenceSlot.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/devicehandlers/FixedSequenceSlot.h b/devicehandlers/FixedSequenceSlot.h index b18d2768..7868cce3 100644 --- a/devicehandlers/FixedSequenceSlot.h +++ b/devicehandlers/FixedSequenceSlot.h @@ -45,6 +45,12 @@ public: */ uint8_t opcode; + /** + * @brief Operator overload for the comparison operator to + * allow sorting by polling time. + * @param fixedSequenceSlot + * @return + */ bool operator <(const FixedSequenceSlot & fixedSequenceSlot) const { return pollingTimeMs < fixedSequenceSlot.pollingTimeMs; }