Files
MuditaOS/module-sys/Service/Worker.cpp
pawel-mudita d1665ed3ba [EGD-2855][EGD-2856] Parser for desktop app (#188)
* [EGD-2306] DESKTOP application initial commit

most of this code is foreign and unverified
it's low level magic numbers for the platform

on Linux i used PTY to simulate a serial line

* [EGD-2306] Add contact-list and contact-count commands

* [EGD-2306] Add command for geting contact by id and minor fixes

* [EGD-2856][WIP] Add basic serial parser

* [EGD-2855] Set usb device config buffer property cacheable

* [EGD-2856] Separate handlers from fsms, add status codes

* [EGD-2855] fd passed to state machine for linux renderer support

* [EGD-2856] Fix warnings

* [EGD-2855] New send task added and buffer queque

* [EGD-2856] Add simple ServiceDesktop documentation

* [EGD-2855] rt1051 worker refactor

* [EGD-2855] Added service workers for desktop app.
Changed linux USB driver mock up.
Added queue name mapping for service workers.
Added queue registry support (maybe redundant with mapping)

* [EGD-2855] Added proper message pointer to queue send and memory free
Added bsp driver namespace for linux and rt1051

* [EGD-2856] Major cleanup

* [EGD-2856] Fix typo

* [EGD-2856] Fix warnings

* [EGD-2856] Delete recursive fsm calling to prevent stack overflow

* [EGD-2856] Reduce http codes

* [EGD-2856] Rename serial parser to parser

* [EGD-2855] USB_CDC drives renames and cleanups
Service Worker queue cleanups

* [EGD-2855] Service Worker queue cleanups

* [EGD2855] Fixed external driver import

* [EGD-2856] Remove redundant message type

* [EGD-2856] Switch on enums instead of ints, and other minor changes requested after code review

* [EGD-2855] usb driver moved to bsp directory structure, pull request fixes

* [EGD-2855] clang #include fix

* [EGD-2856] Add tinyfsm as git submodule, update readme and minor fix

Co-authored-by: rkubiak01 <56821808+rkubiak01@users.noreply.github.com>
Co-authored-by: PrzeBrudny <60609703+PrzeBrudny@users.noreply.github.com>
2020-02-27 15:34:42 +01:00

181 lines
4.1 KiB
C++

/*
* @file Worker.cpp
* @author Robert Borzecki (robert.borzecki@mudita.com)
* @date 30 maj 2019
* @brief
* @copyright Copyright (C) 2019 mudita.com
* @details
*/
#include <string.h>
extern "C" {
#include "FreeRTOS.h"
#include "task.h"
}
//module-sys
#include "Worker.hpp"
namespace sys {
void workerTaskFunction(void *ptr)
{
Worker *worker = reinterpret_cast<Worker *>(ptr);
QueueSetMemberHandle_t activeMember;
std::vector<xQueueHandle> queues = worker->queues;
while (1)
{
activeMember = xQueueSelectFromSet(worker->queueSet, portMAX_DELAY);
// find id of the queue that was activated
for (uint32_t i = 0; i < queues.size(); i++)
{
if (queues[i] == activeMember)
{
worker->handleMessage(i);
}
}
}
}
Worker::Worker( sys::Service* service ) : service {service }, serviceQueue{ NULL }, queueSet{ NULL }, taskHandle{ NULL } {
}
Worker::~Worker() {
}
bool Worker::init( std::list<WorkerQueueInfo> queuesList ) {
//initial value is because there is always a queue to communicate with service
uint32_t setSize = SERVICE_QUEUE_LENGTH;
auto addQueueInfo = [&](xQueueHandle q, std::string qName) {
queueNameMap.insert(std::pair<xQueueHandle, std::string>(q, qName));
vQueueAddToRegistry(q, qName.c_str());
queues.push_back(q);
};
// iterate over all entries in the list of queues and summarize queue sizes
for( auto wqi : queuesList ) {
setSize += wqi.length;
}
//create set of queues
queueSet = xQueueCreateSet( setSize );
if( queueSet == NULL )
return false;
//create and add all queues to the set. First service queue is created.
serviceQueue = xQueueCreate(SERVICE_QUEUE_LENGTH, SERVICE_QUEUE_SIZE );
if(serviceQueue == nullptr){
deinit();
return false;
}
addQueueInfo(serviceQueue, SERVICE_QUEUE_NAME);
// create and add all queues provided from service
for (auto wqi : queuesList)
{
auto q = xQueueCreate(wqi.length, wqi.elementSize);
if (q == NULL)
{
LOG_FATAL("xQueueCreate %s failed", wqi.name.c_str());
deinit();
return false;
}
addQueueInfo(q, wqi.name);
};
//iterate over all queues and add them to set
for( uint32_t i=0; i<queues.size(); ++i ) {
if(xQueueAddToSet( queues[i], queueSet ) != pdPASS)
{
// LOG_FATAL("xQueueAddToSet %d failed", i);
deinit();
return false;
}
}
return true;
}
bool Worker::deinit() {
vTaskDelete(taskHandle);
//for all queues - remove from set and delete queue
for( auto q : queues ) {
//remove queues from set
xQueueRemoveFromSet( q, queueSet );
//delete queue
vQueueDelete( q );
}
queues.clear();
//delete queues set
vQueueDelete((QueueHandle_t) queueSet );
queueSet = NULL;
taskHandle = NULL;
return true;
};
/**
* This method starts RTOS thread that waits for incomming queue events.
*/
bool Worker::run() {
static int workerCount = 0;
std::string workerName = service->GetName()+"_w" + std::to_string(workerCount);
BaseType_t task_error = xTaskCreate(workerTaskFunction, workerName.c_str(), 2048, this, service->GetPriority(), &taskHandle);
if ( task_error != pdPASS)
{
LOG_ERROR("Failed to start the task");
return false;
}
return true;
}
bool Worker::stop() {
return send( 0,NULL );
}
bool Worker::handleMessage( uint32_t queueID ) {
QueueHandle_t queue = queues[queueID];
//service queue
if( queueID == 0 ) {
WorkerCommand wcmd;
if( xQueueReceive(queue, &wcmd, 0 ) != pdTRUE ) {
return false;
}
wcmd.command = 1;
//place some code here to handle messages from service
}
return true;
}
bool Worker::send( uint32_t cmd, uint32_t* data ) {
if( serviceQueue != NULL ) {
WorkerCommand wcmd {cmd, data };
if( xQueueSend( serviceQueue, &wcmd, portMAX_DELAY ) == pdTRUE )
return true;
}
return false;
}
xQueueHandle Worker::getQueueByName(std::string qname)
{
for (auto q_handle : this->queues)
{
if (this->queueNameMap[q_handle] == qname)
return q_handle;
}
return nullptr;
}
} /* namespace sys */