Updated FreeRTOS Osal
CommandingServiceBase is no longer a template
This commit is contained in:
@ -2,6 +2,7 @@
|
||||
#include "FixedTimeslotTask.h"
|
||||
|
||||
uint32_t FixedTimeslotTask::deadlineMissedCount = 0;
|
||||
const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = configMINIMAL_STACK_SIZE;
|
||||
|
||||
FixedTimeslotTask::FixedTimeslotTask(const char *name, TaskPriority setPriority,
|
||||
TaskStackSize setStack, TaskPeriod overallPeriod,
|
||||
|
@ -5,11 +5,10 @@
|
||||
// TODO I guess we should have a way of checking if we are in an ISR and then use the "fromISR" versions of all calls
|
||||
|
||||
MessageQueue::MessageQueue(size_t message_depth, size_t max_message_size) :
|
||||
lastPartner(0), defaultDestination(0) {
|
||||
defaultDestination(0),lastPartner(0) {
|
||||
handle = xQueueCreate(message_depth, max_message_size);
|
||||
if (handle == NULL) {
|
||||
//TODO
|
||||
;
|
||||
error << "MessageQueue creation failed" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,8 +31,7 @@ ReturnValue_t MessageQueue::reply(MessageQueueMessage* message) {
|
||||
if (this->lastPartner != 0) {
|
||||
return sendMessageFrom(this->lastPartner, message, this->getId());
|
||||
} else {
|
||||
//TODO: Good returnCode
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
return NO_REPLY_PARTNER;
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,8 +43,9 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message,
|
||||
}
|
||||
|
||||
ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message) {
|
||||
BaseType_t result = xQueueReceive(handle, message, 0);
|
||||
BaseType_t result = xQueueReceive(handle,reinterpret_cast<void*>(message->getBuffer()), 0);
|
||||
if (result == pdPASS){
|
||||
this->lastPartner = message->getSender();
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
} else {
|
||||
return MessageQueueIF::EMPTY;
|
||||
@ -75,16 +74,7 @@ void MessageQueue::setDefaultDestination(MessageQueueId_t defaultDestination) {
|
||||
ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo,
|
||||
MessageQueueMessage* message, MessageQueueId_t sentFrom,
|
||||
bool ignoreFault) {
|
||||
message->setSender(sentFrom);
|
||||
|
||||
BaseType_t result = xQueueSendToBack((void * )sendTo, message, 0);
|
||||
if (result != pdPASS) {
|
||||
if (!ignoreFault) {
|
||||
//TODO errr reporter
|
||||
}
|
||||
return MessageQueueIF::FULL;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return sendMessageFromMessageQueue(sendTo,message,sentFrom,ignoreFault);
|
||||
}
|
||||
|
||||
ReturnValue_t MessageQueue::sendToDefaultFrom(MessageQueueMessage* message,
|
||||
@ -99,4 +89,23 @@ MessageQueueId_t MessageQueue::getDefaultDestination() const {
|
||||
bool MessageQueue::isDefaultDestinationSet() const {
|
||||
return 0;
|
||||
}
|
||||
ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
|
||||
MessageQueueMessage *message, MessageQueueId_t sentFrom,
|
||||
bool ignoreFault) {
|
||||
message->setSender(sentFrom);
|
||||
|
||||
BaseType_t result = xQueueSendToBack(reinterpret_cast<void*>(sendTo),reinterpret_cast<const void*>(message->getBuffer()), 0);
|
||||
if (result != pdPASS) {
|
||||
if (!ignoreFault) {
|
||||
InternalErrorReporterIF* internalErrorReporter = objectManager->get<InternalErrorReporterIF>(
|
||||
objects::INTERNAL_ERROR_REPORTER);
|
||||
if (internalErrorReporter != NULL) {
|
||||
internalErrorReporter->queueMessageNotSent();
|
||||
}
|
||||
}
|
||||
return MessageQueueIF::FULL;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
* \ingroup message_queue
|
||||
*/
|
||||
class MessageQueue : public MessageQueueIF {
|
||||
friend class MessageQueueSenderIF;
|
||||
public:
|
||||
/**
|
||||
* @brief The constructor initializes and configures the message queue.
|
||||
@ -136,6 +137,19 @@ public:
|
||||
MessageQueueId_t getDefaultDestination() const;
|
||||
|
||||
bool isDefaultDestinationSet() const;
|
||||
protected:
|
||||
/**
|
||||
* Implementation to be called from any send Call within MessageQueue and MessageQueueSenderIF
|
||||
* \details This method takes the message provided, adds the sentFrom information and passes
|
||||
* it on to the destination provided with an operating system call. The OS's return
|
||||
* value is returned.
|
||||
* \param sendTo This parameter specifies the message queue id to send the message to.
|
||||
* \param message This is a pointer to a previously created message, which is sent.
|
||||
* \param sentFrom The sentFrom information can be set to inject the sender's queue id into the message.
|
||||
* This variable is set to zero by default.
|
||||
* \param ignoreFault If set to true, the internal software fault counter is not incremented if queue is full.
|
||||
*/
|
||||
static ReturnValue_t sendMessageFromMessageQueue(MessageQueueId_t sendTo,MessageQueueMessage* message, MessageQueueId_t sentFrom = NO_QUEUE,bool ignoreFault=false);
|
||||
private:
|
||||
QueueHandle_t handle;
|
||||
MessageQueueId_t defaultDestination;
|
||||
|
@ -8,7 +8,10 @@ PeriodicTask::PeriodicTask(const char *name, TaskPriority setPriority,
|
||||
started(false), handle(NULL), period(setPeriod), deadlineMissedFunc(
|
||||
setDeadlineMissedFunc) {
|
||||
|
||||
xTaskCreate(taskEntryPoint, name, setStack, this, setPriority, &handle);
|
||||
BaseType_t status = xTaskCreate(taskEntryPoint, name, setStack, this, setPriority, &handle);
|
||||
if(status != pdPASS){
|
||||
debug << "PeriodicTask Insufficient heap memory remaining. Status: " << status << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -7,9 +7,8 @@ QueueFactory* QueueFactory::factoryInstance = NULL;
|
||||
|
||||
|
||||
ReturnValue_t MessageQueueSenderIF::sendMessage(MessageQueueId_t sendTo,
|
||||
MessageQueueMessage* message, MessageQueueId_t sentFrom) {
|
||||
|
||||
return 0;
|
||||
MessageQueueMessage* message, MessageQueueId_t sentFrom,bool ignoreFault) {
|
||||
return MessageQueue::sendMessageFromMessageQueue(sendTo,message,sentFrom,ignoreFault);
|
||||
}
|
||||
|
||||
QueueFactory* QueueFactory::instance() {
|
||||
|
14
osal/FreeRTOS/README.md
Normal file
14
osal/FreeRTOS/README.md
Normal file
@ -0,0 +1,14 @@
|
||||
FreeRTOS Readme
|
||||
=
|
||||
|
||||
## Main.cpp Notices
|
||||
|
||||
### Tasks
|
||||
|
||||
A FreeRTOS application needs to start
|
||||
|
||||
> vTaskStartScheduler()
|
||||
|
||||
before creating Tasks.
|
||||
Keep this in mind for the mission dependent code!
|
||||
This has to be done before the Task Factory is used.
|
@ -4,7 +4,7 @@
|
||||
#include "PeriodicTask.h"
|
||||
#include "FixedTimeslotTask.h"
|
||||
|
||||
//TODO: Different variant than the lazy loading in QueueFactory. What's better and why?
|
||||
|
||||
TaskFactory* TaskFactory::factoryInstance = new TaskFactory();
|
||||
|
||||
TaskFactory::~TaskFactory() {
|
||||
@ -13,7 +13,9 @@ TaskFactory::~TaskFactory() {
|
||||
TaskFactory* TaskFactory::instance() {
|
||||
return TaskFactory::factoryInstance;
|
||||
}
|
||||
|
||||
/***
|
||||
* Keep in Mind that you need to call before this vTaskStartScheduler()!
|
||||
*/
|
||||
PeriodicTaskIF* TaskFactory::createPeriodicTask(TaskName name_,
|
||||
TaskPriority taskPriority_, TaskStackSize stackSize_,
|
||||
TaskPeriod period_,
|
||||
@ -21,7 +23,9 @@ PeriodicTaskIF* TaskFactory::createPeriodicTask(TaskName name_,
|
||||
return (PeriodicTaskIF*) (new PeriodicTask(name_, taskPriority_, stackSize_,
|
||||
period_, deadLineMissedFunction_));
|
||||
}
|
||||
|
||||
/***
|
||||
* Keep in Mind that you need to call before this vTaskStartScheduler()!
|
||||
*/
|
||||
FixedTimeslotTaskIF* TaskFactory::createFixedTimeslotTask(TaskName name_,
|
||||
TaskPriority taskPriority_, TaskStackSize stackSize_,
|
||||
TaskPeriod period_,
|
||||
|
@ -1,32 +0,0 @@
|
||||
//entry point into "bsp"
|
||||
//TODO This can be done mission dependent and some low level calls before vTaskStartScheduler might be important
|
||||
//void init(void);
|
||||
//
|
||||
//#include <FreeRTOS.h>
|
||||
//#include <FreeRTOSConfig.h>
|
||||
//#include "task.h"
|
||||
//
|
||||
//
|
||||
//void initTask(void *parameters) {
|
||||
// init();
|
||||
//}
|
||||
//
|
||||
//int main(void) {
|
||||
//
|
||||
// if ( pdPASS
|
||||
// != xTaskCreate(initTask, "init", 512, NULL,
|
||||
// configMAX_PRIORITIES - 1, NULL)) {
|
||||
// //print_uart0("Could not create task1\r\n");
|
||||
// }
|
||||
//
|
||||
// vTaskStartScheduler();
|
||||
//
|
||||
// //Scheduler should never return
|
||||
//
|
||||
// //print_uart0("This is bad\n");
|
||||
//
|
||||
// for (;;)
|
||||
// ;
|
||||
//
|
||||
// return 0;
|
||||
//}
|
@ -53,9 +53,6 @@ void FixedTimeslotTask::taskFunctionality() {
|
||||
if (!started) {
|
||||
suspend();
|
||||
}
|
||||
// A local iterator for the Polling Sequence Table is created to find the start time for the first entry.
|
||||
std::list<FixedSequenceSlot*>::iterator it = pst.current;
|
||||
|
||||
//The start time for the first entry is read.
|
||||
uint64_t lastWakeTime = getCurrentMonotonicTimeMs();
|
||||
uint64_t interval = pst.getIntervalToNextSlotMs();
|
||||
|
@ -8,8 +8,7 @@
|
||||
|
||||
|
||||
MessageQueue::MessageQueue(size_t message_depth, size_t max_message_size) :
|
||||
id(0), lastPartner(0), defaultDestination(NO_QUEUE), internalErrorReporter(
|
||||
NULL) {
|
||||
id(0), lastPartner(0), defaultDestination(NO_QUEUE) {
|
||||
//debug << "MessageQueue::MessageQueue: Creating a queue" << std::endl;
|
||||
mq_attr attributes;
|
||||
this->id = 0;
|
||||
@ -81,8 +80,7 @@ ReturnValue_t MessageQueue::reply(MessageQueueMessage* message) {
|
||||
if (this->lastPartner != 0) {
|
||||
return sendMessageFrom(this->lastPartner, message, this->getId());
|
||||
} else {
|
||||
//TODO: Good returnCode
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
return NO_REPLY_PARTNER;
|
||||
}
|
||||
}
|
||||
|
||||
@ -198,19 +196,40 @@ void MessageQueue::setDefaultDestination(MessageQueueId_t defaultDestination) {
|
||||
ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo,
|
||||
MessageQueueMessage* message, MessageQueueId_t sentFrom,
|
||||
bool ignoreFault) {
|
||||
return sendMessageFromMessageQueue(sendTo,message,sentFrom,ignoreFault);
|
||||
|
||||
}
|
||||
|
||||
ReturnValue_t MessageQueue::sendToDefaultFrom(MessageQueueMessage* message,
|
||||
MessageQueueId_t sentFrom, bool ignoreFault) {
|
||||
return sendMessageFrom(defaultDestination, message, sentFrom, ignoreFault);
|
||||
}
|
||||
|
||||
MessageQueueId_t MessageQueue::getDefaultDestination() const {
|
||||
return this->defaultDestination;
|
||||
}
|
||||
|
||||
bool MessageQueue::isDefaultDestinationSet() const {
|
||||
return (defaultDestination != NO_QUEUE);
|
||||
}
|
||||
|
||||
uint16_t MessageQueue::queueCounter = 0;
|
||||
|
||||
ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
|
||||
MessageQueueMessage *message, MessageQueueId_t sentFrom,
|
||||
bool ignoreFault) {
|
||||
message->setSender(sentFrom);
|
||||
int result = mq_send(sendTo,
|
||||
reinterpret_cast<const char*>(message->getBuffer()), message->messageSize,0);
|
||||
|
||||
//TODO: Check if we're in ISR.
|
||||
if (result != 0 && !ignoreFault) {
|
||||
if (internalErrorReporter == NULL) {
|
||||
internalErrorReporter = objectManager->get<InternalErrorReporterIF>(
|
||||
objects::INTERNAL_ERROR_REPORTER);
|
||||
}
|
||||
if (internalErrorReporter != NULL) {
|
||||
internalErrorReporter->queueMessageNotSent();
|
||||
if (result != 0) {
|
||||
if(!ignoreFault){
|
||||
InternalErrorReporterIF* internalErrorReporter = objectManager->get<InternalErrorReporterIF>(
|
||||
objects::INTERNAL_ERROR_REPORTER);
|
||||
if (internalErrorReporter != NULL) {
|
||||
internalErrorReporter->queueMessageNotSent();
|
||||
}
|
||||
}
|
||||
switch(errno){
|
||||
case EAGAIN:
|
||||
@ -241,18 +260,3 @@ ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo,
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t MessageQueue::sendToDefaultFrom(MessageQueueMessage* message,
|
||||
MessageQueueId_t sentFrom, bool ignoreFault) {
|
||||
return sendMessageFrom(defaultDestination, message, sentFrom, ignoreFault);
|
||||
}
|
||||
|
||||
MessageQueueId_t MessageQueue::getDefaultDestination() const {
|
||||
return this->defaultDestination;
|
||||
}
|
||||
|
||||
bool MessageQueue::isDefaultDestinationSet() const {
|
||||
return (defaultDestination != NO_QUEUE);
|
||||
}
|
||||
|
||||
uint16_t MessageQueue::queueCounter = 0;
|
||||
|
@ -21,6 +21,7 @@
|
||||
* \ingroup message_queue
|
||||
*/
|
||||
class MessageQueue : public MessageQueueIF {
|
||||
friend class MessageQueueSenderIF;
|
||||
public:
|
||||
/**
|
||||
* @brief The constructor initializes and configures the message queue.
|
||||
@ -101,9 +102,6 @@ public:
|
||||
MessageQueueId_t getId() const;
|
||||
/**
|
||||
* \brief With the sendMessage call, a queue message is sent to a receiving queue.
|
||||
* \details This method takes the message provided, adds the sentFrom information and passes
|
||||
* it on to the destination provided with an operating system call. The OS's return
|
||||
* value is returned.
|
||||
* \param sendTo This parameter specifies the message queue id to send the message to.
|
||||
* \param message This is a pointer to a previously created message, which is sent.
|
||||
* \param sentFrom The sentFrom information can be set to inject the sender's queue id into the message.
|
||||
@ -129,6 +127,19 @@ public:
|
||||
MessageQueueId_t getDefaultDestination() const;
|
||||
|
||||
bool isDefaultDestinationSet() const;
|
||||
protected:
|
||||
/**
|
||||
* Implementation to be called from any send Call within MessageQueue and MessageQueueSenderIF
|
||||
* \details This method takes the message provided, adds the sentFrom information and passes
|
||||
* it on to the destination provided with an operating system call. The OS's return
|
||||
* value is returned.
|
||||
* \param sendTo This parameter specifies the message queue id to send the message to.
|
||||
* \param message This is a pointer to a previously created message, which is sent.
|
||||
* \param sentFrom The sentFrom information can be set to inject the sender's queue id into the message.
|
||||
* This variable is set to zero by default.
|
||||
* \param ignoreFault If set to true, the internal software fault counter is not incremented if queue is full.
|
||||
*/
|
||||
static ReturnValue_t sendMessageFromMessageQueue(MessageQueueId_t sendTo,MessageQueueMessage* message, MessageQueueId_t sentFrom = NO_QUEUE,bool ignoreFault=false);
|
||||
private:
|
||||
/**
|
||||
* @brief The class stores the queue id it got assigned from the operating system in this attribute.
|
||||
@ -151,13 +162,6 @@ private:
|
||||
*/
|
||||
MessageQueueId_t defaultDestination;
|
||||
|
||||
/**
|
||||
* \brief This attribute stores a reference to the internal error reporter for reporting full queues.
|
||||
* \details In the event of a full destination queue, the reporter will be notified. The reference is set
|
||||
* by lazy loading
|
||||
*/
|
||||
InternalErrorReporterIF *internalErrorReporter;
|
||||
|
||||
/**
|
||||
* The name of the message queue, stored for unlinking
|
||||
*/
|
||||
|
@ -9,40 +9,8 @@ QueueFactory* QueueFactory::factoryInstance = NULL;
|
||||
|
||||
|
||||
ReturnValue_t MessageQueueSenderIF::sendMessage(MessageQueueId_t sendTo,
|
||||
MessageQueueMessage* message, MessageQueueId_t sentFrom) {
|
||||
message->setSender(sentFrom);
|
||||
int result = mq_send(sendTo,
|
||||
reinterpret_cast<const char*>(message->getBuffer()), message->messageSize,0);
|
||||
|
||||
//TODO: Check if we're in ISR.
|
||||
if (result != 0) {
|
||||
//TODO Translate error
|
||||
switch(errno){
|
||||
case EAGAIN:
|
||||
//The O_NONBLOCK flag was set when opening the queue, or the MQ_NONBLOCK flag was set in its attributes, and the specified queue is full.
|
||||
return MessageQueueIF::FULL;
|
||||
case EBADF:
|
||||
//mq_des doesn't represent a valid message queue descriptor, or mq_des wasn't opened for writing.
|
||||
error << "MessageQueueSenderIF::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.
|
||||
case EINVAL:
|
||||
/*
|
||||
* This value indicates one of the following:
|
||||
* * msg_ptr is NULL.
|
||||
* * 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.
|
||||
* */
|
||||
case EMSGSIZE:
|
||||
//The msg_len is greater than the msgsize associated with the specified queue.
|
||||
default:
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
MessageQueueMessage* message, MessageQueueId_t sentFrom,bool ignoreFault) {
|
||||
return MessageQueue::sendMessageFromMessageQueue(sendTo,message,sentFrom,ignoreFault);
|
||||
}
|
||||
|
||||
QueueFactory* QueueFactory::instance() {
|
||||
|
@ -14,8 +14,8 @@ ReturnValue_t InternalErrorCodes::translate(uint8_t code) {
|
||||
return TOO_LITTLE_WORKSPACE;
|
||||
case INTERNAL_ERROR_WORKSPACE_ALLOCATION:
|
||||
return WORKSPACE_ALLOCATION;
|
||||
case INTERNAL_ERROR_INTERRUPT_STACK_TOO_SMALL:
|
||||
return INTERRUPT_STACK_TOO_SMALL;
|
||||
// case INTERNAL_ERROR_INTERRUPT_STACK_TOO_SMALL:
|
||||
// return INTERRUPT_STACK_TOO_SMALL;
|
||||
case INTERNAL_ERROR_THREAD_EXITTED:
|
||||
return THREAD_EXITTED;
|
||||
case INTERNAL_ERROR_INCONSISTENT_MP_INFORMATION:
|
||||
|
@ -32,8 +32,7 @@ ReturnValue_t MessageQueue::reply(MessageQueueMessage* message) {
|
||||
if (this->lastPartner != 0) {
|
||||
return sendMessage(this->lastPartner, message, this->getId());
|
||||
} else {
|
||||
//TODO: Good returnCode
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
return NO_REPLY_PARTNER;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,8 @@ QueueFactory* QueueFactory::factoryInstance = NULL;
|
||||
|
||||
|
||||
ReturnValue_t MessageQueueSenderIF::sendMessage(MessageQueueId_t sendTo,
|
||||
MessageQueueMessage* message, MessageQueueId_t sentFrom) {
|
||||
MessageQueueMessage* message, MessageQueueId_t sentFrom,bool ignoreFault) {
|
||||
//TODO add ignoreFault functionality
|
||||
message->setSender(sentFrom);
|
||||
rtems_status_code result = rtems_message_queue_send(sendTo, message->getBuffer(),
|
||||
message->messageSize);
|
||||
|
Reference in New Issue
Block a user