Added new queues for inter task communication

This commit is contained in:
Thomas Bittner 2023-08-25 12:08:49 +02:00 committed by MatthewColvin
parent 628ae37b9d
commit 47ccc214a0
13 changed files with 321 additions and 2 deletions

View file

@ -21,4 +21,5 @@ class wifiHandlerInterface{
virtual void connect(std::shared_ptr<std::string> ssid, std::shared_ptr<std::string> password) = 0;
virtual void onScanDone(std::function<void (std::shared_ptr<std::vector<WifiInfo>>)> function) = 0;
virtual void onStatusUpdate(std::function<void (std::shared_ptr<wifiStatus>)> function) = 0;
virtual void begin() = 0;
};

View file

@ -0,0 +1,9 @@
#pragma once
#include "SPSCQueueInterface.hpp"
template <typename T>
class MPMCQueueInterface: public SPSCQueueInterface<T>
{
public:
bool push(T obj, bool overwrite = false);
};

View file

@ -0,0 +1,12 @@
#pragma once
#include <optional>
template <typename T>
class SPSCQueueInterface {
public:
virtual bool push(T obj) = 0;
virtual std::optional<T> pop() = 0;
virtual std::optional<T> peek() = 0;
virtual bool isFull() = 0;
virtual bool isEmpty() = 0;
};

View file

@ -0,0 +1,70 @@
#include "freeRTOSMPMCQueue.hpp"
template <typename T>
freeRTOSMPMCQueue<T>::freeRTOSMPMCQueue(uint32_t size)
{
this->queue = xQueueCreate(size, sizeof(T));
}
template <typename T>
freeRTOSMPMCQueue<T>::~freeRTOSMPMCQueue()
{
vQueueDelete(this->queue);
}
template <typename T>
bool freeRTOSMPMCQueue<T>::push(T obj)
{
return xQueueSendToBack(this->queue, &obj, 0) == pdTRUE;
}
template <typename T>
bool freeRTOSMPMCQueue<T>::push(T obj, bool overwrite)
{
if (overwrite == true)
{
xQueueOverwrite(this->queue, obj);
return true;
}
else
{
return this->push(obj);
}
}
template <typename T>
std::optional<T> freeRTOSMPMCQueue<T>::pop()
{
T retval;
if (xQueueReceive(this->queue, &retval, 0) == pdTRUE)
{
return retval;
}
return std::nullopt;
}
template <typename T>
std::optional<T> freeRTOSMPMCQueue<T>::peek()
{
T retval;
if (xQueuePeek(this->queue, &retval, 0) == pdTRUE)
{
return retval;
}
return std::nullopt;
}
template <typename T>
bool freeRTOSMPMCQueue<T>::isFull()
{
return (xQueueIsQueueFullFromISR(this->queue) == pdTRUE);
}
template <typename T>
bool freeRTOSMPMCQueue<T>::isEmpty()
{
return (xQueueIsQueueEmptyFromISR(this->queue) == pdTRUE);
}

View file

@ -0,0 +1,18 @@
#pragma once
#include "MPMCQueueInterface.hpp"
#include "Arduino.h"
template <typename T>
class freeRTOSMPMCQueue: public MPMCQueueInterface<T>
{
public:
freeRTOSMPMCQueue(uint32_t size);
~freeRTOSMPMCQueue();
bool push (T obj);
bool push (T obj, bool overwrite);
std::optional<T> pop();
std::optional<T> peek();
bool isFull();
bool isEmpty();
private:
QueueHandle_t queue;
};

View file

@ -2,6 +2,7 @@
#include <Arduino.h>
#include <Preferences.h>
#include "HardwareAbstract.hpp"
#include "WiFi.h"
std::shared_ptr<wifiHandler> wifiHandler::mInstance = nullptr;
@ -37,6 +38,10 @@ void wifiHandler::WiFiEvent(WiFiEvent_t event){
//this->display.wifi_scan_complete( no_networks);
}
this->scan_notification.notify(info);
if (WiFi.isConnected() == false)
{
WiFi.reconnect();
}
break;
}
case ARDUINO_EVENT_WIFI_STA_GOT_IP:
@ -47,6 +52,8 @@ void wifiHandler::WiFiEvent(WiFiEvent_t event){
case ARDUINO_EVENT_WIFI_STA_STOP:
this->update_status();
default:
Serial.print("Wifi Status: ");
Serial.println(WiFi.status());
break;
}
if (WiFi.status() == WL_CONNECT_FAILED)
@ -74,7 +81,6 @@ wifiHandler::wifiHandler()
{
this->password = "";
this->SSID = "";
this->begin();
}
void wifiHandler::update_status()
@ -137,6 +143,12 @@ void wifiHandler::update_credentials()
void wifiHandler::scan()
{
Serial.println("scan called");
/* If the */
WiFi.status();
if (WiFi.isConnected() != true)
{
WiFi.disconnect();
}
WiFi.scanNetworks(true);
}
@ -164,7 +176,7 @@ void wifiHandler::begin()
//strcpy(this->password, password.c_str());
this->SSID = ssid.c_str();
this->password = password.c_str();
//this->connect(this->SSID, this->password);
//this->connect(std::make_shared<std::string>(std::string(this->SSID)), std::make_shared<std::string>(std::string(this->password)));
}
else
{

View file

@ -0,0 +1,77 @@
#include "SimulatorMPMCQueue.hpp"
template <typename T>
bool SimulatorMPMCQueue<T>::push(T obj)
{
return this->push(obj, false);
}
template <typename T>
bool SimulatorMPMCQueue<T>::push(T obj, bool overwrite)
{
bool retval = false;
if (this->mtx.try_lock())
{
if (this->isFull() && overwrite)
{
/* If we should overwrite already written data and the buffer is full, we increment the rd_index as well.
This has to be done in the mutex so we do not overwrite data which is already being read*/
this->rd_index = this->incrementIndex(this->rd_index);
}
/* If the buffer is full, we can not write to the buffer. If overwrite is set to true, this check will never
fail as we move the rd_index if the buffer would otherwise be full*/
if (!this->isFull())
{
retval = true;
this->data[this->wr_index] = obj;
this->wr_index = this->incrementIndex(this->wr_index);
}
this->mtx.unlock();
}
return retval;
}
template <typename T>
std::optional<T> SimulatorMPMCQueue<T>::pop()
{
T retval;
if (this->mtx.try_lock()){
if (this->isEmpty())
{
return std::nullopt;
}
retval = this->data[this->rd_index];
this->rd_index = this->incrementIndex(this->rd_index);
this->mtx.unlock();
return retval;
}
return std::nullopt;
}
template <typename T>
std::optional<T> SimulatorMPMCQueue<T>::peek()
{
T retval;
if (this->mtx.try_lock())
{
if (this->isEmpty())
{
return std::nullopt;
}
retval = this->data[this->rd_index];
this->mtx.unlock();
return retval;
}
return std::nullopt;
}
template <typename T>
uint32_t SimulatorMPMCQueue<T>::incrementIndex(uint32_t index)
{
return (index + 1) % this->size;
}

View file

@ -0,0 +1,24 @@
#pragma once
#include "MPMCQueueInterface.hpp"
#include "SimulatorSPSCQueue.hpp"
#include <mutex>
template <typename T>
class SimulatorMPMCQueue: public SimulatorSPSCQueue<T>, public MPMCQueueInterface<T>
{
public:
SimulatorMPMCQueue(uint32_t size): SimulatorSPSCQueue<T>(size){};
bool push (T obj);
bool push (T obj, bool overwrite);
std::optional<T> pop();
std::optional<T> peek();
bool isFull();
bool isEmpty();
private:
T* data;
uint32_t size;
uint32_t rd_index;
uint32_t wr_index;
uint32_t incrementIndex(uint32_t index);
std::mutex mtx;
};

View file

@ -0,0 +1,68 @@
#include "SimulatorSPSCQueue.hpp"
template <typename T>
SimulatorSPSCQueue<T>::SimulatorSPSCQueue(uint32_t size)
{
this->size = size;
this->data = new T[](this->size + 1);
this->rd_index = 0;
this->wr_index = 0;
}
template <typename T>
SimulatorSPSCQueue<T>::~SimulatorSPSCQueue()
{
free(this->data);
}
template <typename T>
bool SimulatorSPSCQueue<T>::isFull()
{
return ((this->wr_index + 1) % this->size) == this->rd_index;
}
template <typename T>
bool SimulatorSPSCQueue<T>::isEmpty()
{
return this->rd_index == this->wr_index;
}
template <typename T>
bool SimulatorSPSCQueue<T>::push(T obj)
{
bool retval = false;
if (!this->isFull())
{
retval = true;
this->data[this->wr_index] = obj;
this->wr_index = this->incrementIndex(this->wr_index);
}
return retval;
}
template <typename T>
std::optional<T> SimulatorSPSCQueue<T>::pop()
{
std::optional<T> retval;
retval = this->peek();
this->rd_index = this->incrementIndex(this->rd_index);
return retval;
}
template <typename T>
std::optional<T> SimulatorSPSCQueue<T>::peek()
{
if (this->isEmpty())
{
return std::nullopt;
}
return this->data[this->rd_index];
}
template <typename T>
uint32_t SimulatorSPSCQueue<T>::incrementIndex(uint32_t index)
{
return (index + 1) % this->size;
}

View file

@ -0,0 +1,22 @@
#pragma once
#include "SPSCQueueInterface.hpp"
#include <cstdint>
template <typename T>
class SimulatorSPSCQueue: public SPSCQueueInterface<T>
{
public:
SimulatorSPSCQueue(uint32_t size);
~SimulatorSPSCQueue();
bool push (T obj);
std::optional<T> pop();
std::optional<T> peek();
bool isFull();
bool isEmpty();
private:
T* data;
uint32_t size;
uint32_t rd_index;
uint32_t wr_index;
uint32_t incrementIndex(uint32_t index);
};

View file

@ -16,6 +16,10 @@ wifiHandlerSim::wifiHandlerSim(){
}
void wifiHandlerSim::begin(){
}
static wifiStatus status = {
.isConnected = true
, .IP = "172.0.0.1"

View file

@ -26,6 +26,7 @@ class wifiHandlerSim: public wifiHandlerInterface {
*/
void scan();
bool isAvailable();
void begin();
void onScanDone(std::function<void (std::shared_ptr<std::vector<WifiInfo>>)> function);
void onStatusUpdate(std::function<void (std::shared_ptr<wifiStatus>)> function);
private:

View file

@ -463,4 +463,5 @@ void OmoteUI::layout_UI() {
lv_obj_set_size(img2, 30, 30);
this->create_status_bar();
this->mHardware->wifi()->begin();
}