Files
esp-protocols/esp_modem/include/cxx_include/esp_modem_primitives.hpp

118 lines
3.0 KiB
C++
Raw Normal View History

2021-02-26 18:32:15 +01:00
//
// Created by david on 2/26/21.
//
#ifndef SIMPLE_CXX_CLIENT_ESP_MODEM_PRIMITIVES_HPP
#define SIMPLE_CXX_CLIENT_ESP_MODEM_PRIMITIVES_HPP
2021-02-26 18:32:15 +01:00
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
2021-03-06 16:56:50 +01:00
#include "freertos/semphr.h"
2021-03-16 21:36:13 +01:00
#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
#define THROW(exception) throw(exception)
2021-02-26 18:32:15 +01:00
class esp_err_exception: virtual public std::exception {
public:
explicit esp_err_exception(esp_err_t err): esp_err(err) {}
explicit esp_err_exception(std::string msg): esp_err(ESP_FAIL), message(std::move(msg)) {}
explicit esp_err_exception(std::string msg, esp_err_t err): esp_err(err), message(std::move(msg)) {}
virtual esp_err_t get_err_t() { return esp_err; }
~esp_err_exception() noexcept override = default;
virtual const char* what() const noexcept {
return message.c_str();
}
private:
esp_err_t esp_err;
std::string message;
};
2021-03-16 21:36:13 +01:00
#else
#define THROW(exception) abort()
#endif
2021-02-26 18:32:15 +01:00
static inline void throw_if_false(bool condition, std::string message)
{
if (!condition) {
2021-03-16 21:36:13 +01:00
THROW(esp_err_exception(std::move(message)));
2021-02-26 18:32:15 +01:00
}
}
static inline void throw_if_esp_fail(esp_err_t err, std::string message)
{
if (err != ESP_OK) {
2021-03-16 21:36:13 +01:00
THROW(esp_err_exception(std::move(message), err));
2021-02-26 18:32:15 +01:00
}
}
static inline void throw_if_esp_fail(esp_err_t err)
{
if (err != ESP_OK) {
2021-03-16 21:36:13 +01:00
THROW(esp_err_exception(err));
2021-02-26 18:32:15 +01:00
}
}
2021-03-06 16:56:50 +01:00
struct Lock {
explicit Lock(): lock(nullptr)
{
lock = xSemaphoreCreateRecursiveMutex();
2021-03-06 16:56:50 +01:00
throw_if_false(lock != nullptr, "create signal event group failed");
}
~Lock() { vSemaphoreDelete(lock); }
void take() { xSemaphoreTake(lock, portMAX_DELAY); }
void give() { xSemaphoreGive(lock); }
xSemaphoreHandle lock;
};
template<class T>
class Scoped {
public:
explicit Scoped(T &l):lock(l) { lock.take(); }
~Scoped() { lock.give(); }
private:
T& lock;
};
2021-02-26 18:32:15 +01:00
struct signal_group {
explicit signal_group(): event_group(nullptr)
{
event_group = xEventGroupCreate();
throw_if_false(event_group != nullptr, "create signal event group failed");
}
void set(uint32_t bits)
{
xEventGroupSetBits(event_group, bits);
}
2021-03-04 20:19:18 +01:00
void clear(uint32_t bits)
{
xEventGroupClearBits(event_group, bits);
}
2021-02-26 18:32:15 +01:00
bool wait(uint32_t flags, uint32_t time_ms) // waiting for all and clearing if set
{
EventBits_t bits = xEventGroupWaitBits(event_group, flags, pdTRUE, pdTRUE, pdMS_TO_TICKS(time_ms));
return bits & flags;
}
bool is_any(uint32_t flags)
{
return xEventGroupGetBits(event_group) & flags;
}
bool wait_any(uint32_t flags, uint32_t time_ms) // waiting for any bit, not clearing them
{
EventBits_t bits = xEventGroupWaitBits(event_group, flags, pdFALSE, pdFALSE, pdMS_TO_TICKS(time_ms));
return bits & flags;
}
~signal_group()
{
if (event_group) vEventGroupDelete(event_group);
}
EventGroupHandle_t event_group;
};
#endif //SIMPLE_CXX_CLIENT_ESP_MODEM_PRIMITIVES_HPP