Split off RecursiveMutex from Mutex (#437)

* Split off RecursiveMutex from Mutex

* Fix

* Code quality
This commit is contained in:
Ken Van Hoeylandt 2025-12-28 12:30:54 +01:00 committed by GitHub
parent f48654d3dc
commit 3fc2ff8bc6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
45 changed files with 185 additions and 177 deletions

View File

@ -3,6 +3,7 @@
#define TAG "twodotfour_sdcard" #define TAG "twodotfour_sdcard"
#include <Tactility/hal/sdcard/SpiSdCardDevice.h> #include <Tactility/hal/sdcard/SpiSdCardDevice.h>
#include <Tactility/RecursiveMutex.h>
constexpr auto SDCARD_SPI_HOST = SPI3_HOST; constexpr auto SDCARD_SPI_HOST = SPI3_HOST;
constexpr auto SDCARD_PIN_CS = GPIO_NUM_5; constexpr auto SDCARD_PIN_CS = GPIO_NUM_5;
@ -16,7 +17,7 @@ std::shared_ptr<SdCardDevice> createSdCard() {
GPIO_NUM_NC, GPIO_NUM_NC,
GPIO_NUM_NC, GPIO_NUM_NC,
SdCardDevice::MountBehaviour::AtBoot, SdCardDevice::MountBehaviour::AtBoot,
std::make_shared<tt::Mutex>(tt::Mutex::Type::Recursive), std::make_shared<tt::RecursiveMutex>(),
std::vector<gpio_num_t>(), std::vector<gpio_num_t>(),
SDCARD_SPI_HOST SDCARD_SPI_HOST
); );

View File

@ -1,6 +1,7 @@
#include "SdCard.h" #include "SdCard.h"
#include <Tactility/hal/sdcard/SpiSdCardDevice.h> #include <Tactility/hal/sdcard/SpiSdCardDevice.h>
#include <Tactility/lvgl/LvglSync.h> #include <Tactility/lvgl/LvglSync.h>
#include <Tactility/RecursiveMutex.h>
using tt::hal::sdcard::SpiSdCardDevice; using tt::hal::sdcard::SpiSdCardDevice;
@ -11,7 +12,7 @@ std::shared_ptr<SdCardDevice> createSdCard() {
GPIO_NUM_NC, GPIO_NUM_NC,
GPIO_NUM_NC, GPIO_NUM_NC,
SdCardDevice::MountBehaviour::AtBoot, SdCardDevice::MountBehaviour::AtBoot,
std::make_shared<tt::Mutex>(tt::Mutex::Type::Recursive), std::make_shared<tt::RecursiveMutex>(),
std::vector<gpio_num_t>(), std::vector<gpio_num_t>(),
SPI3_HOST SPI3_HOST
); );

View File

@ -1,6 +1,7 @@
#include "SdCard.h" #include "SdCard.h"
#include <Tactility/hal/sdcard/SpiSdCardDevice.h> #include <Tactility/hal/sdcard/SpiSdCardDevice.h>
#include <Tactility/lvgl/LvglSync.h> #include <Tactility/lvgl/LvglSync.h>
#include <Tactility/RecursiveMutex.h>
using tt::hal::sdcard::SpiSdCardDevice; using tt::hal::sdcard::SpiSdCardDevice;
@ -11,7 +12,7 @@ std::shared_ptr<SdCardDevice> createSdCard() {
GPIO_NUM_NC, GPIO_NUM_NC,
GPIO_NUM_NC, GPIO_NUM_NC,
SdCardDevice::MountBehaviour::AtBoot, SdCardDevice::MountBehaviour::AtBoot,
std::make_shared<tt::Mutex>(tt::Mutex::Type::Recursive), std::make_shared<tt::RecursiveMutex>(),
std::vector<gpio_num_t>(), std::vector<gpio_num_t>(),
SPI3_HOST SPI3_HOST
); );

View File

@ -2,6 +2,7 @@
#include <Tactility/hal/sdcard/SpiSdCardDevice.h> #include <Tactility/hal/sdcard/SpiSdCardDevice.h>
#include <Tactility/lvgl/LvglSync.h> #include <Tactility/lvgl/LvglSync.h>
#include <Tactility/RecursiveMutex.h>
constexpr auto SDCARD_SPI_HOST = SPI3_HOST; constexpr auto SDCARD_SPI_HOST = SPI3_HOST;
constexpr auto SDCARD_PIN_CS = GPIO_NUM_5; constexpr auto SDCARD_PIN_CS = GPIO_NUM_5;
@ -15,7 +16,7 @@ std::shared_ptr<SdCardDevice> createSdCard() {
GPIO_NUM_NC, GPIO_NUM_NC,
GPIO_NUM_NC, GPIO_NUM_NC,
SdCardDevice::MountBehaviour::AtBoot, SdCardDevice::MountBehaviour::AtBoot,
std::make_shared<tt::Mutex>(tt::Mutex::Type::Recursive), std::make_shared<tt::RecursiveMutex>(),
std::vector<gpio_num_t>(), std::vector<gpio_num_t>(),
SDCARD_SPI_HOST SDCARD_SPI_HOST
); );

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
#include <Tactility/Mutex.h> #include <Tactility/RecursiveMutex.h>
#include <EspLcdDisplay.h> #include <EspLcdDisplay.h>
#include <lvgl.h> #include <lvgl.h>
@ -21,7 +21,7 @@ class St7701Display final : public EspLcdDisplay {
public: public:
St7701Display() : EspLcdDisplay(std::make_shared<tt::Mutex>(tt::Mutex::Type::Recursive)) {} St7701Display() : EspLcdDisplay(std::make_shared<tt::RecursiveMutex>()) {}
std::string getName() const override { return "ST7701S"; } std::string getName() const override { return "ST7701S"; }

View File

@ -1,5 +1,6 @@
#include "SdCard.h" #include "SdCard.h"
#include <Tactility/hal/sdcard/SpiSdCardDevice.h> #include <Tactility/hal/sdcard/SpiSdCardDevice.h>
#include <Tactility/RecursiveMutex.h>
using tt::hal::sdcard::SpiSdCardDevice; using tt::hal::sdcard::SpiSdCardDevice;
@ -10,7 +11,7 @@ std::shared_ptr<SdCardDevice> createSdCard() {
GPIO_NUM_NC, GPIO_NUM_NC,
GPIO_NUM_NC, GPIO_NUM_NC,
SdCardDevice::MountBehaviour::AtBoot, SdCardDevice::MountBehaviour::AtBoot,
std::make_shared<tt::Mutex>(tt::Mutex::Type::Recursive), std::make_shared<tt::RecursiveMutex>(),
std::vector<gpio_num_t>(), std::vector<gpio_num_t>(),
SPI3_HOST SPI3_HOST
); );

View File

@ -1,5 +1,6 @@
#include "SdCard.h" #include "SdCard.h"
#include <Tactility/hal/sdcard/SpiSdCardDevice.h> #include <Tactility/hal/sdcard/SpiSdCardDevice.h>
#include <Tactility/RecursiveMutex.h>
using tt::hal::sdcard::SpiSdCardDevice; using tt::hal::sdcard::SpiSdCardDevice;
using SdCardDevice = tt::hal::sdcard::SdCardDevice; using SdCardDevice = tt::hal::sdcard::SdCardDevice;
@ -11,7 +12,7 @@ std::shared_ptr<SdCardDevice> createSdCard() {
GPIO_NUM_NC, // MISO override: leave NC GPIO_NUM_NC, // MISO override: leave NC
GPIO_NUM_NC, // SCLK override: leave NC GPIO_NUM_NC, // SCLK override: leave NC
SdCardDevice::MountBehaviour::AtBoot, SdCardDevice::MountBehaviour::AtBoot,
std::make_shared<tt::Mutex>(tt::Mutex::Type::Recursive), std::make_shared<tt::RecursiveMutex>(),
std::vector<gpio_num_t>(), std::vector<gpio_num_t>(),
SD_SPI_HOST // SPI host for SD card (SPI3_HOST) SD_SPI_HOST // SPI host for SD card (SPI3_HOST)
); );

View File

@ -2,6 +2,7 @@
#include <Tactility/hal/sdcard/SpiSdCardDevice.h> #include <Tactility/hal/sdcard/SpiSdCardDevice.h>
#include <Tactility/lvgl/LvglSync.h> #include <Tactility/lvgl/LvglSync.h>
#include <Tactility/RecursiveMutex.h>
constexpr auto SDCARD_SPI_HOST = SPI3_HOST; constexpr auto SDCARD_SPI_HOST = SPI3_HOST;
constexpr auto SDCARD_PIN_CS = GPIO_NUM_5; constexpr auto SDCARD_PIN_CS = GPIO_NUM_5;
@ -15,7 +16,7 @@ std::shared_ptr<SdCardDevice> createSdCard() {
GPIO_NUM_NC, GPIO_NUM_NC,
GPIO_NUM_NC, GPIO_NUM_NC,
SdCardDevice::MountBehaviour::AtBoot, SdCardDevice::MountBehaviour::AtBoot,
std::make_shared<tt::Mutex>(tt::Mutex::Type::Recursive), std::make_shared<tt::RecursiveMutex>(),
std::vector<gpio_num_t>(), std::vector<gpio_num_t>(),
SDCARD_SPI_HOST SDCARD_SPI_HOST
); );

View File

@ -2,6 +2,7 @@
#include <Tactility/hal/sdcard/SpiSdCardDevice.h> #include <Tactility/hal/sdcard/SpiSdCardDevice.h>
#include <Tactility/lvgl/LvglSync.h> #include <Tactility/lvgl/LvglSync.h>
#include <Tactility/RecursiveMutex.h>
using tt::hal::sdcard::SpiSdCardDevice; using tt::hal::sdcard::SpiSdCardDevice;
@ -12,7 +13,7 @@ std::shared_ptr<SdCardDevice> createSdCard() {
GPIO_NUM_NC, GPIO_NUM_NC,
GPIO_NUM_NC, GPIO_NUM_NC,
SdCardDevice::MountBehaviour::AtBoot, SdCardDevice::MountBehaviour::AtBoot,
std::make_shared<tt::Mutex>(tt::Mutex::Type::Recursive), std::make_shared<tt::RecursiveMutex>(),
std::vector<gpio_num_t>(), std::vector<gpio_num_t>(),
SPI2_HOST SPI2_HOST
); );

View File

@ -2,7 +2,7 @@
#include <Tactility/Log.h> #include <Tactility/Log.h>
#include <Tactility/lvgl/LvglSync.h> #include <Tactility/lvgl/LvglSync.h>
#include <Tactility/Mutex.h> #include <Tactility/RecursiveMutex.h>
#include <Tactility/Thread.h> #include <Tactility/Thread.h>
#include <lvgl.h> #include <lvgl.h>
@ -10,8 +10,8 @@
#define TAG "lvgl_task" #define TAG "lvgl_task"
// Mutex for LVGL drawing // Mutex for LVGL drawing
static tt::Mutex lvgl_mutex(tt::Mutex::Type::Recursive); static tt::RecursiveMutex lvgl_mutex;
static tt::Mutex task_mutex(tt::Mutex::Type::Recursive); static tt::RecursiveMutex task_mutex;
static uint32_t task_max_sleep_ms = 10; static uint32_t task_max_sleep_ms = 10;
// Mutex for LVGL task state (to modify task_running state) // Mutex for LVGL task state (to modify task_running state)

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#include "Tactility/hal/sdcard/SdCardDevice.h" #include "Tactility/hal/sdcard/SdCardDevice.h"
#include <Tactility/Mutex.h> #include <Tactility/RecursiveMutex.h>
#include <memory> #include <memory>
using tt::hal::sdcard::SdCardDevice; using tt::hal::sdcard::SdCardDevice;
@ -16,7 +16,7 @@ public:
SimulatorSdCard() : SdCardDevice(MountBehaviour::AtBoot), SimulatorSdCard() : SdCardDevice(MountBehaviour::AtBoot),
state(State::Unmounted), state(State::Unmounted),
lock(std::make_shared<tt::Mutex>(tt::Mutex::Type::Recursive)) lock(std::make_shared<tt::RecursiveMutex>())
{} {}
std::string getName() const override { return "Mock SD Card"; } std::string getName() const override { return "Mock SD Card"; }

View File

@ -2,6 +2,7 @@
#include <Tactility/lvgl/LvglSync.h> #include <Tactility/lvgl/LvglSync.h>
#include <Tactility/hal/sdcard/SpiSdCardDevice.h> #include <Tactility/hal/sdcard/SpiSdCardDevice.h>
#include <Tactility/RecursiveMutex.h>
using tt::hal::sdcard::SpiSdCardDevice; using tt::hal::sdcard::SpiSdCardDevice;
@ -12,7 +13,7 @@ std::shared_ptr<SdCardDevice> createSdCard() {
GPIO_NUM_NC, GPIO_NUM_NC,
GPIO_NUM_NC, GPIO_NUM_NC,
SdCardDevice::MountBehaviour::AtBoot, SdCardDevice::MountBehaviour::AtBoot,
std::make_shared<tt::Mutex>(tt::Mutex::Type::Recursive), std::make_shared<tt::RecursiveMutex>(),
std::vector<gpio_num_t>(), std::vector<gpio_num_t>(),
SPI3_HOST SPI3_HOST
); );

View File

@ -2,6 +2,7 @@
#include <Tactility/lvgl/LvglSync.h> #include <Tactility/lvgl/LvglSync.h>
#include <Tactility/hal/sdcard/SpiSdCardDevice.h> #include <Tactility/hal/sdcard/SpiSdCardDevice.h>
#include <Tactility/RecursiveMutex.h>
using tt::hal::sdcard::SpiSdCardDevice; using tt::hal::sdcard::SpiSdCardDevice;
@ -12,7 +13,7 @@ std::shared_ptr<SdCardDevice> createSdCard() {
GPIO_NUM_NC, GPIO_NUM_NC,
GPIO_NUM_NC, GPIO_NUM_NC,
SdCardDevice::MountBehaviour::AtBoot, SdCardDevice::MountBehaviour::AtBoot,
std::make_shared<tt::Mutex>(tt::Mutex::Type::Recursive), std::make_shared<tt::RecursiveMutex>(),
std::vector<gpio_num_t>(), std::vector<gpio_num_t>(),
SPI3_HOST SPI3_HOST
); );

View File

@ -1,13 +1,14 @@
#pragma once #pragma once
#include <Tactility/hal/display/DisplayDevice.h> #include <Tactility/hal/display/DisplayDevice.h>
#include <Tactility/RecursiveMutex.h>
#include <EspLcdDisplayDriver.h> #include <EspLcdDisplayDriver.h>
#include <esp_lcd_panel_rgb.h> #include <esp_lcd_panel_rgb.h>
#include <esp_lvgl_port_disp.h> #include <esp_lvgl_port_disp.h>
class RgbDisplay final : public tt::hal::display::DisplayDevice { class RgbDisplay final : public tt::hal::display::DisplayDevice {
std::shared_ptr<tt::Lock> lock = std::make_shared<tt::Mutex>(tt::Mutex::Type::Recursive); std::shared_ptr<tt::Lock> lock = std::make_shared<tt::RecursiveMutex>();
public: public:

View File

@ -4,7 +4,7 @@
#include "GpsConfiguration.h" #include "GpsConfiguration.h"
#include "Satellites.h" #include "Satellites.h"
#include <Tactility/Mutex.h> #include <Tactility/RecursiveMutex.h>
#include <Tactility/Thread.h> #include <Tactility/Thread.h>
#include <minmea.h> #include <minmea.h>
@ -47,7 +47,7 @@ private:
}; };
const GpsConfiguration configuration; const GpsConfiguration configuration;
Mutex mutex = Mutex(Mutex::Type::Recursive); RecursiveMutex mutex;
std::unique_ptr<Thread> _Nullable thread; std::unique_ptr<Thread> _Nullable thread;
bool threadInterrupted = false; bool threadInterrupted = false;
std::vector<GgaSubscription> ggaSubscriptions; std::vector<GgaSubscription> ggaSubscriptions;

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#include <Tactility/RtosCompat.h> #include <Tactility/RtosCompat.h>
#include <Tactility/Mutex.h> #include <Tactility/RecursiveMutex.h>
#include <minmea.h> #include <minmea.h>
@ -30,7 +30,7 @@ private:
bool inUse = false; bool inUse = false;
}; };
Mutex mutex = Mutex(Mutex::Type::Recursive); RecursiveMutex mutex;
std::array<SatelliteRecord, recordCount> records; std::array<SatelliteRecord, recordCount> records;
uint16_t recycleTimeSeconds; uint16_t recycleTimeSeconds;
uint16_t recentTimeSeconds; uint16_t recentTimeSeconds;

View File

@ -4,14 +4,13 @@
#include "SdCardDevice.h" #include "SdCardDevice.h"
#include <Tactility/RecursiveMutex.h>
#include <Tactility/hal/Device.h>
#include <Tactility/hal/spi/Spi.h> #include <Tactility/hal/spi/Spi.h>
#include <sd_protocol_types.h> #include <sd_protocol_types.h>
#include <soc/gpio_num.h>
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <Tactility/hal/Device.h>
#include <hal/spi_types.h>
#include <soc/gpio_num.h>
namespace tt::hal::sdcard { namespace tt::hal::sdcard {
@ -20,7 +19,7 @@ namespace tt::hal::sdcard {
*/ */
class SdmmcDevice final : public SdCardDevice { class SdmmcDevice final : public SdCardDevice {
std::shared_ptr<Mutex> mutex = std::make_shared<Mutex>(Mutex::Type::Recursive); std::shared_ptr<RecursiveMutex> mutex = std::make_shared<RecursiveMutex>();
public: public:

View File

@ -2,7 +2,7 @@
#ifdef ESP_PLATFORM #ifdef ESP_PLATFORM
#include <esp_http_server.h> #include <esp_http_server.h>
#include <Tactility/Mutex.h> #include <Tactility/RecursiveMutex.h>
#include <Tactility/kernel/SystemEvents.h> #include <Tactility/kernel/SystemEvents.h>
namespace tt::network { namespace tt::network {
@ -33,7 +33,7 @@ private:
std::vector<httpd_uri_t> handlers; std::vector<httpd_uri_t> handlers;
Mutex mutex = Mutex(Mutex::Type::Recursive); RecursiveMutex mutex;
httpd_handle_t server = nullptr; httpd_handle_t server = nullptr;
bool startInternal(); bool startInternal();

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "Tactility/Mutex.h" #include "Tactility/Mutex.h"
#include "Tactility/RecursiveMutex.h"
#include "Tactility/PubSub.h" #include "Tactility/PubSub.h"
#include "Tactility/hal/gps/GpsDevice.h" #include "Tactility/hal/gps/GpsDevice.h"
#include "Tactility/service/Service.h" #include "Tactility/service/Service.h"
@ -20,7 +21,7 @@ class GpsService final : public Service {
minmea_sentence_rmc rmcRecord; minmea_sentence_rmc rmcRecord;
TickType_t rmcTime = 0; TickType_t rmcTime = 0;
Mutex mutex = Mutex(Mutex::Type::Recursive); RecursiveMutex mutex;
Mutex stateMutex; Mutex stateMutex;
std::vector<GpsDeviceRecord> deviceRecords; std::vector<GpsDeviceRecord> deviceRecords;
std::shared_ptr<PubSub<State>> statePubSub = std::make_shared<PubSub<State>>(); std::shared_ptr<PubSub<State>> statePubSub = std::make_shared<PubSub<State>>();

View File

@ -5,6 +5,7 @@
#include <Tactility/Bundle.h> #include <Tactility/Bundle.h>
#include <Tactility/DispatcherThread.h> #include <Tactility/DispatcherThread.h>
#include <Tactility/PubSub.h> #include <Tactility/PubSub.h>
#include <Tactility/RecursiveMutex.h>
#include <Tactility/service/Service.h> #include <Tactility/service/Service.h>
#include <memory> #include <memory>
@ -26,7 +27,7 @@ public:
private: private:
std::shared_ptr<PubSub<Event>> pubsubExternal = std::make_shared<PubSub<Event>>(); std::shared_ptr<PubSub<Event>> pubsubExternal = std::make_shared<PubSub<Event>>();
Mutex mutex = Mutex(Mutex::Type::Recursive); RecursiveMutex mutex;
std::vector<std::shared_ptr<app::AppInstance>> appStack; std::vector<std::shared_ptr<app::AppInstance>> appStack;
app::LaunchId nextLaunchId = 0; app::LaunchId nextLaunchId = 0;

View File

@ -25,7 +25,7 @@ enum class State {
*/ */
class AppInstance : public AppContext { class AppInstance : public AppContext {
Mutex mutex = Mutex(Mutex::Type::Normal); Mutex mutex;
const std::shared_ptr<AppManifest> manifest; const std::shared_ptr<AppManifest> manifest;
State state = State::Initial; State state = State::Initial;
LaunchId launchId; LaunchId launchId;

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
#include <Tactility/Mutex.h> #include <Tactility/RecursiveMutex.h>
#include <string> #include <string>
#include <vector> #include <vector>
@ -20,7 +20,7 @@ public:
private: private:
Mutex mutex = Mutex(Mutex::Type::Recursive); RecursiveMutex mutex;
std::vector<dirent> dir_entries; std::vector<dirent> dir_entries;
std::string current_path; std::string current_path;
std::string selected_child_entry; std::string selected_child_entry;

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
#include <Tactility/Mutex.h> #include <Tactility/RecursiveMutex.h>
#include <string> #include <string>
#include <vector> #include <vector>
@ -10,7 +10,7 @@ namespace tt::app::fileselection {
class State final { class State final {
Mutex mutex = Mutex(Mutex::Type::Recursive); RecursiveMutex mutex;
std::vector<dirent> dir_entries; std::vector<dirent> dir_entries;
std::string current_path; std::string current_path;
std::string selected_child_entry; std::string selected_child_entry;

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#include <Tactility/service/wifi/Wifi.h> #include <Tactility/service/wifi/Wifi.h>
#include <Tactility/Mutex.h> #include <Tactility/RecursiveMutex.h>
namespace tt::app::wifimanage { namespace tt::app::wifimanage {
@ -10,7 +10,7 @@ namespace tt::app::wifimanage {
*/ */
class State final { class State final {
Mutex mutex = Mutex(Mutex::Type::Recursive); RecursiveMutex mutex;
bool scanning = false; bool scanning = false;
bool scannedAfterRadioOn = false; bool scannedAfterRadioOn = false;
service::wifi::RadioState radioState; service::wifi::RadioState radioState;

View File

@ -10,7 +10,7 @@ namespace tt::service {
class ServiceInstance final : public ServiceContext { class ServiceInstance final : public ServiceContext {
Mutex mutex = Mutex(Mutex::Type::Normal); Mutex mutex;
std::shared_ptr<const ServiceManifest> manifest; std::shared_ptr<const ServiceManifest> manifest;
std::shared_ptr<Service> service; std::shared_ptr<Service> service;
State state = State::Stopped; State state = State::Stopped;

View File

@ -3,7 +3,7 @@
#include <Tactility/service/Service.h> #include <Tactility/service/Service.h>
#include <Tactility/Mutex.h> #include <Tactility/RecursiveMutex.h>
#include <esp_event.h> #include <esp_event.h>
#include <esp_http_server.h> #include <esp_http_server.h>
@ -13,7 +13,7 @@ namespace tt::service::development {
class DevelopmentService final : public Service { class DevelopmentService final : public Service {
Mutex mutex = Mutex(Mutex::Type::Recursive); RecursiveMutex mutex;
std::string deviceResponse; std::string deviceResponse;
network::HttpServer httpServer = network::HttpServer( network::HttpServer httpServer = network::HttpServer(
6666, 6666,

View File

@ -9,7 +9,7 @@
#include <Tactility/service/Service.h> #include <Tactility/service/Service.h>
#include <Tactility/service/espnow/EspNow.h> #include <Tactility/service/espnow/EspNow.h>
#include <Tactility/Mutex.h> #include <Tactility/RecursiveMutex.h>
#include <functional> #include <functional>
@ -27,7 +27,7 @@ class EspNowService final : public Service {
bool success; bool success;
}; };
Mutex mutex = Mutex(Mutex::Type::Recursive); RecursiveMutex mutex;
std::vector<ReceiverSubscriptionData> subscriptions; std::vector<ReceiverSubscriptionData> subscriptions;
ReceiverSubscription lastSubscriptionId = 0; ReceiverSubscription lastSubscriptionId = 0;
bool enabled = false; bool enabled = false;

View File

@ -2,7 +2,7 @@
#include <Tactility/app/AppContext.h> #include <Tactility/app/AppContext.h>
#include <Tactility/MessageQueue.h> #include <Tactility/MessageQueue.h>
#include <Tactility/Mutex.h> #include <Tactility/RecursiveMutex.h>
#include <Tactility/PubSub.h> #include <Tactility/PubSub.h>
#include <Tactility/service/Service.h> #include <Tactility/service/Service.h>
#include <Tactility/service/loader/Loader.h> #include <Tactility/service/loader/Loader.h>
@ -21,7 +21,7 @@ class GuiService final : public Service {
// Thread and lock // Thread and lock
Thread* thread = nullptr; Thread* thread = nullptr;
Mutex mutex = Mutex(Mutex::Type::Recursive); RecursiveMutex mutex;
PubSub<loader::LoaderService::Event>::SubscriptionHandle loader_pubsub_subscription = nullptr; PubSub<loader::LoaderService::Event>::SubscriptionHandle loader_pubsub_subscription = nullptr;
// Layers and Canvas // Layers and Canvas

View File

@ -13,7 +13,7 @@ namespace tt::service::memorychecker {
*/ */
class MemoryCheckerService final : public Service { class MemoryCheckerService final : public Service {
Mutex mutex = Mutex(Mutex::Type::Recursive); Mutex mutex;
Timer timer = Timer(Timer::Type::Periodic, [this] { onTimerUpdate(); }); Timer timer = Timer(Timer::Type::Periodic, [this] { onTimerUpdate(); });
// LVGL Statusbar icon // LVGL Statusbar icon

View File

@ -5,7 +5,7 @@
#pragma once #pragma once
#include <Tactility/Thread.h> #include <Tactility/Thread.h>
#include <Tactility/Mutex.h> #include <Tactility/RecursiveMutex.h>
namespace tt::service::screenshot { namespace tt::service::screenshot {
@ -22,7 +22,7 @@ class ScreenshotTask {
}; };
Thread* thread = nullptr; Thread* thread = nullptr;
Mutex mutex = Mutex(Mutex::Type::Recursive); RecursiveMutex mutex;
bool interrupted = false; bool interrupted = false;
bool finished = false; bool finished = false;
ScreenshotTaskWork work; ScreenshotTaskWork work;

View File

@ -13,7 +13,7 @@ namespace tt::app {
typedef std::unordered_map<std::string, std::shared_ptr<AppManifest>> AppManifestMap; typedef std::unordered_map<std::string, std::shared_ptr<AppManifest>> AppManifestMap;
static AppManifestMap app_manifest_map; static AppManifestMap app_manifest_map;
static Mutex hash_mutex(Mutex::Type::Normal); static Mutex hash_mutex;
void addAppManifest(const AppManifest& manifest) { void addAppManifest(const AppManifest& manifest) {
TT_LOG_I(TAG, "Registering manifest %s", manifest.appId.c_str()); TT_LOG_I(TAG, "Registering manifest %s", manifest.appId.c_str());

View File

@ -9,6 +9,7 @@
#include <Tactility/service/loader/Loader.h> #include <Tactility/service/loader/Loader.h>
#include <Tactility/Assets.h> #include <Tactility/Assets.h>
#include <Tactility/RecursiveMutex.h>
#include <Tactility/Tactility.h> #include <Tactility/Tactility.h>
#include <Tactility/Timer.h> #include <Tactility/Timer.h>
@ -24,7 +25,7 @@ class I2cScannerApp final : public App {
static constexpr auto* STOP_SCAN_TEXT = "Stop scan"; static constexpr auto* STOP_SCAN_TEXT = "Stop scan";
// Core // Core
Mutex mutex = Mutex(Mutex::Type::Recursive); RecursiveMutex mutex;
std::unique_ptr<Timer> scanTimer = nullptr; std::unique_ptr<Timer> scanTimer = nullptr;
// State // State
ScanState scanState = ScanStateInitial; ScanState scanState = ScanStateInitial;

View File

@ -1,4 +1,5 @@
#include <Tactility/Assets.h> #include <Tactility/Assets.h>
#include <Tactility/RecursiveMutex.h>
#include <Tactility/app/timezone/TimeZone.h> #include <Tactility/app/timezone/TimeZone.h>
#include <Tactility/app/localesettings/TextResources.h> #include <Tactility/app/localesettings/TextResources.h>
#include <Tactility/lvgl/Toolbar.h> #include <Tactility/lvgl/Toolbar.h>
@ -26,7 +27,7 @@ extern const AppManifest manifest;
class LocaleSettingsApp final : public App { class LocaleSettingsApp final : public App {
tt::i18n::TextResources textResources = tt::i18n::TextResources(TEXT_RESOURCE_PATH); tt::i18n::TextResources textResources = tt::i18n::TextResources(TEXT_RESOURCE_PATH);
Mutex mutex = Mutex(Mutex::Type::Recursive); RecursiveMutex mutex;
lv_obj_t* timeZoneLabel = nullptr; lv_obj_t* timeZoneLabel = nullptr;
lv_obj_t* regionLabel = nullptr; lv_obj_t* regionLabel = nullptr;
lv_obj_t* languageDropdown = nullptr; lv_obj_t* languageDropdown = nullptr;

View File

@ -1,6 +1,7 @@
#include <Tactility/Assets.h> #include <Tactility/Assets.h>
#include <Tactility/app/AppManifest.h> #include <Tactility/app/AppManifest.h>
#include <Tactility/lvgl/Toolbar.h> #include <Tactility/lvgl/Toolbar.h>
#include <Tactility/RecursiveMutex.h>
#include <Tactility/service/loader/Loader.h> #include <Tactility/service/loader/Loader.h>
#include <Tactility/settings/Time.h> #include <Tactility/settings/Time.h>
@ -14,7 +15,7 @@ extern const AppManifest manifest;
class TimeDateSettingsApp final : public App { class TimeDateSettingsApp final : public App {
Mutex mutex = Mutex(Mutex::Type::Recursive); RecursiveMutex mutex;
static void onTimeFormatChanged(lv_event_t* event) { static void onTimeFormatChanged(lv_event_t* event) {
auto* widget = lv_event_get_target_obj(event); auto* widget = lv_event_get_target_obj(event);

View File

@ -1,12 +1,12 @@
#include "Tactility/hal/Device.h" #include "Tactility/hal/Device.h"
#include <Tactility/Mutex.h> #include <Tactility/RecursiveMutex.h>
#include <algorithm> #include <algorithm>
namespace tt::hal { namespace tt::hal {
std::vector<std::shared_ptr<Device>> devices; std::vector<std::shared_ptr<Device>> devices;
Mutex mutex = Mutex(Mutex::Type::Recursive); RecursiveMutex mutex;
static Device::Id nextId = 0; static Device::Id nextId = 0;
#define TAG "devices" #define TAG "devices"

View File

@ -1,6 +1,6 @@
#include "Tactility/hal/spi/Spi.h" #include "Tactility/hal/spi/Spi.h"
#include <Tactility/Mutex.h> #include <Tactility/RecursiveMutex.h>
namespace tt::hal::spi { namespace tt::hal::spi {
@ -24,7 +24,7 @@ bool init(const std::vector<Configuration>& configurations) {
if (configuration.lock != nullptr) { if (configuration.lock != nullptr) {
data.lock = configuration.lock; data.lock = configuration.lock;
} else { } else {
data.lock = std::make_shared<Mutex>(Mutex::Type::Recursive); data.lock = std::make_shared<RecursiveMutex>();
} }
} }

View File

@ -1,23 +1,22 @@
#define LV_USE_PRIVATE_API 1 // For actual lv_obj_t declaration #define LV_USE_PRIVATE_API 1 // For actual lv_obj_t declaration
#include "Tactility/lvgl/Statusbar.h" #include <Tactility/Tactility.h>
#include <Tactility/TactilityCore.h>
#include "Tactility/lvgl/Style.h"
#include "Tactility/lvgl/LvglSync.h"
#include <Tactility/kernel/SystemEvents.h> #include <Tactility/kernel/SystemEvents.h>
#include <Tactility/Mutex.h> #include <Tactility/lvgl/Statusbar.h>
#include <Tactility/lvgl/Style.h>
#include <Tactility/lvgl/LvglSync.h>
#include <Tactility/PubSub.h> #include <Tactility/PubSub.h>
#include <Tactility/TactilityCore.h> #include <Tactility/RecursiveMutex.h>
#include <Tactility/Timer.h>
#include <Tactility/settings/Time.h> #include <Tactility/settings/Time.h>
#include <Tactility/Timer.h>
#include <lvgl.h> #include <lvgl.h>
#include <Tactility/Tactility.h>
namespace tt::lvgl { namespace tt::lvgl {
#define TAG "statusbar" constexpr auto TAG = "statusbar";
static void onUpdateTime(); static void onUpdateTime();
@ -28,7 +27,7 @@ struct StatusbarIcon {
}; };
struct StatusbarData { struct StatusbarData {
Mutex mutex = Mutex(Mutex::Type::Recursive); RecursiveMutex mutex;
std::shared_ptr<PubSub<void*>> pubsub = std::make_shared<PubSub<void*>>(); std::shared_ptr<PubSub<void*>> pubsub = std::make_shared<PubSub<void*>>();
StatusbarIcon icons[STATUSBAR_ICON_LIMIT] = {}; StatusbarIcon icons[STATUSBAR_ICON_LIMIT] = {};
Timer* time_update_timer = new Timer(Timer::Type::Once, [] { onUpdateTime(); }); Timer* time_update_timer = new Timer(Timer::Type::Once, [] { onUpdateTime(); });

View File

@ -17,8 +17,8 @@ typedef std::unordered_map<std::string, std::shared_ptr<ServiceInstance>> Servic
static ManifestMap service_manifest_map; static ManifestMap service_manifest_map;
static ServiceInstanceMap service_instance_map; static ServiceInstanceMap service_instance_map;
static Mutex manifest_mutex(Mutex::Type::Normal); static Mutex manifest_mutex;
static Mutex instance_mutex(Mutex::Type::Normal); static Mutex instance_mutex;
void addService(std::shared_ptr<const ServiceManifest> manifest, bool autoStart) { void addService(std::shared_ptr<const ServiceManifest> manifest, bool autoStart) {
assert(manifest != nullptr); assert(manifest != nullptr);

View File

@ -9,6 +9,7 @@
#include <Tactility/EventFlag.h> #include <Tactility/EventFlag.h>
#include <Tactility/Tactility.h> #include <Tactility/Tactility.h>
#include <Tactility/kernel/SystemEvents.h> #include <Tactility/kernel/SystemEvents.h>
#include <Tactility/RecursiveMutex.h>
#include <Tactility/service/ServiceContext.h> #include <Tactility/service/ServiceContext.h>
#include <Tactility/service/wifi/WifiGlobals.h> #include <Tactility/service/wifi/WifiGlobals.h>
#include <Tactility/service/wifi/WifiSettings.h> #include <Tactility/service/wifi/WifiSettings.h>
@ -48,8 +49,8 @@ class Wifi {
public: public:
/** @brief Locking mechanism for modifying the Wifi instance */ /** @brief Locking mechanism for modifying the Wifi instance */
Mutex radioMutex = Mutex(Mutex::Type::Recursive); RecursiveMutex radioMutex;
Mutex dataMutex = Mutex(Mutex::Type::Recursive); RecursiveMutex dataMutex;
std::unique_ptr<Timer> autoConnectTimer; std::unique_ptr<Timer> autoConnectTimer;
/** @brief The public event bus */ /** @brief The public event bus */
std::shared_ptr<PubSub<WifiEvent>> pubsub = std::make_shared<PubSub<WifiEvent>>(); std::shared_ptr<PubSub<WifiEvent>> pubsub = std::make_shared<PubSub<WifiEvent>>();

View File

@ -4,8 +4,8 @@
#include <Tactility/Check.h> #include <Tactility/Check.h>
#include <Tactility/Log.h> #include <Tactility/Log.h>
#include <Tactility/Mutex.h>
#include <Tactility/PubSub.h> #include <Tactility/PubSub.h>
#include <Tactility/RecursiveMutex.h>
#include <Tactility/service/Service.h> #include <Tactility/service/Service.h>
#include <Tactility/service/ServiceManifest.h> #include <Tactility/service/ServiceManifest.h>
@ -15,7 +15,7 @@ constexpr auto* TAG = "Wifi";
struct Wifi { struct Wifi {
/** @brief Locking mechanism for modifying the Wifi instance */ /** @brief Locking mechanism for modifying the Wifi instance */
Mutex mutex = Mutex(Mutex::Type::Recursive); RecursiveMutex mutex;
/** @brief The public event bus */ /** @brief The public event bus */
std::shared_ptr<PubSub<WifiEvent>> pubsub = std::make_shared<PubSub<WifiEvent>>(); std::shared_ptr<PubSub<WifiEvent>> pubsub = std::make_shared<PubSub<WifiEvent>>();
/** @brief The internal message queue */ /** @brief The internal message queue */

View File

@ -1,7 +1,8 @@
#include <Tactility/Mutex.h>
#include <Tactility/RecursiveMutex.h>
#include <Tactility/file/File.h>
#include <tt_lock.h> #include <tt_lock.h>
#include <tt_lock_private.h> #include <tt_lock_private.h>
#include <Tactility/Mutex.h>
#include <Tactility/file/File.h>
#define HANDLE_AS_LOCK(handle) (static_cast<LockHolder*>(handle)->lock) #define HANDLE_AS_LOCK(handle) (static_cast<LockHolder*>(handle)->lock)
@ -11,10 +12,10 @@ LockHandle tt_lock_alloc_mutex(TtMutexType type) {
auto* lock_holder = new LockHolder(); auto* lock_holder = new LockHolder();
switch (type) { switch (type) {
case MutexTypeNormal: case MutexTypeNormal:
lock_holder->lock = std::make_shared<tt::Mutex>(tt::Mutex::Type::Normal); lock_holder->lock = std::make_shared<tt::Mutex>();
break; break;
case MutexTypeRecursive: case MutexTypeRecursive:
lock_holder->lock = std::make_shared<tt::Mutex>(tt::Mutex::Type::Recursive); lock_holder->lock = std::make_shared<tt::RecursiveMutex>();
break; break;
default: default:
tt_crash("Type not supported"); tt_crash("Type not supported");

View File

@ -1,34 +1,25 @@
/** /**
* @file mutex.h * @file Mutex.h
* Mutex * Mutex
*/ */
#pragma once #pragma once
#include "Check.h"
#include "Lock.h" #include "Lock.h"
#include "RtosCompatSemaphore.h" #include "RtosCompatSemaphore.h"
#include "Thread.h" #include "Thread.h"
#include "kernel/Kernel.h" #include "kernel/Kernel.h"
#include <memory> #include <memory>
#include <cassert>
namespace tt { namespace tt {
/** /**
* Wrapper for FreeRTOS xSemaphoreCreateMutex and xSemaphoreCreateRecursiveMutex * Wrapper for FreeRTOS xSemaphoreCreateMutex
* Cannot be used in IRQ mode (within ISR context) * Cannot be used in IRQ mode (within ISR context)
*/ */
class Mutex final : public Lock { class Mutex final : public Lock {
public:
/**
* A "Normal" mutex can only be locked once. Even from within the same task/thread.
* A "Recursive" mutex can be locked again from the same task/thread.
*/
enum class Type {
Normal,
Recursive,
};
private: private:
struct SemaphoreHandleDeleter { struct SemaphoreHandleDeleter {
@ -38,29 +29,40 @@ private:
} }
}; };
std::unique_ptr<std::remove_pointer_t<QueueHandle_t>, SemaphoreHandleDeleter> handle; std::unique_ptr<std::remove_pointer_t<QueueHandle_t>, SemaphoreHandleDeleter> handle = std::unique_ptr<std::remove_pointer_t<QueueHandle_t>, SemaphoreHandleDeleter>(xSemaphoreCreateMutex());
Type type;
public: public:
using Lock::lock; using Lock::lock;
explicit Mutex(Type type = Type::Normal); explicit Mutex() {
assert(handle != nullptr);
}
~Mutex() override = default; ~Mutex() override = default;
/** Attempt to lock the mutex. Blocks until timeout passes or lock is acquired. /** Attempt to lock the mutex. Blocks until timeout passes or lock is acquired.
* @param[in] timeout * @param[in] timeout
* @return success result * @return success result
*/ */
bool lock(TickType_t timeout) const override; bool lock(TickType_t timeout) const override {
assert(!kernel::isIsr());
return xSemaphoreTake(handle.get(), timeout) == pdPASS;
}
/** Attempt to unlock the mutex. /** Attempt to unlock the mutex.
* @return success result * @return success result
*/ */
bool unlock() const override; bool unlock() const override {
assert(!kernel::isIsr());
return xSemaphoreGive(handle.get()) == pdPASS;
}
/** @return the owner of the thread */ /** @return the owner of the thread */
ThreadId getOwner() const; ThreadId getOwner() const {
assert(!kernel::isIsr());
return xSemaphoreGetMutexHolder(handle.get());
}
}; };
} // namespace } // namespace tt

View File

@ -0,0 +1,67 @@
/**
* @file RecursiveMutex.h
* RecursiveMutex
*/
#pragma once
#include "Lock.h"
#include "RtosCompatSemaphore.h"
#include "Thread.h"
#include "kernel/Kernel.h"
#include <memory>
#include <cassert>
namespace tt {
/**
* Wrapper for FreeRTOS xSemaphoreCreateRecursiveMutex
* Cannot be used in IRQ mode (within ISR context)
*/
class RecursiveMutex final : public Lock {
private:
struct SemaphoreHandleDeleter {
void operator()(QueueHandle_t handleToDelete) {
assert(!kernel::isIsr());
vSemaphoreDelete(handleToDelete);
}
};
std::unique_ptr<std::remove_pointer_t<QueueHandle_t>, SemaphoreHandleDeleter> handle = std::unique_ptr<std::remove_pointer_t<QueueHandle_t>, SemaphoreHandleDeleter>(xSemaphoreCreateRecursiveMutex());
public:
using Lock::lock;
explicit RecursiveMutex() {
assert(handle != nullptr);
}
~RecursiveMutex() override = default;
/** Attempt to lock the mutex. Blocks until timeout passes or lock is acquired.
* @param[in] timeout
* @return success result
*/
bool lock(TickType_t timeout) const override {
assert(!kernel::isIsr());
return xSemaphoreTakeRecursive(handle.get(), timeout) == pdPASS;
}
/** Attempt to unlock the mutex.
* @return success result
*/
bool unlock() const override {
assert(!kernel::isIsr());
return xSemaphoreGiveRecursive(handle.get()) == pdPASS;
}
/** @return the owner of the thread */
ThreadId getOwner() const {
assert(!kernel::isIsr());
return xSemaphoreGetMutexHolder(handle.get());
}
};
} // namespace

View File

@ -1,77 +0,0 @@
#include "Tactility/Mutex.h"
#include "Tactility/Check.h"
#include "Tactility/CoreDefines.h"
#include "Tactility/Log.h"
namespace tt {
#define MUTEX_DEBUGGING false
#if MUTEX_DEBUGGING
#define TAG "mutex"
void tt_mutex_info(Mutex mutex, const char* label) {
MutexData* data = (MutexData*)mutex;
if (data == NULL) {
TT_LOG_I(TAG, "mutex %s: is NULL", label);
} else {
TT_LOG_I(TAG, "mutex %s: handle=%0X type=%d owner=%0x", label, data->handle, data->type, tt_mutex_get_owner(mutex));
}
}
#else
#define tt_mutex_info(mutex, text)
#endif
static inline SemaphoreHandle_t createSemaphoreHandle(Mutex::Type type) {
switch (type) {
case Mutex::Type::Normal:
return xSemaphoreCreateMutex();
case Mutex::Type::Recursive:
return xSemaphoreCreateRecursiveMutex();
default:
tt_crash("Mutex type unknown/corrupted");
}
}
Mutex::Mutex(Type type) : handle(createSemaphoreHandle(type)), type(type) {
tt_mutex_info(data, "alloc");
assert(handle != nullptr);
}
bool Mutex::lock(TickType_t timeout) const {
assert(!kernel::isIsr());
assert(handle != nullptr);
tt_mutex_info(mutex, "acquire");
switch (type) {
case Type::Normal:
return xSemaphoreTake(handle.get(), timeout) == pdPASS;
case Type::Recursive:
return xSemaphoreTakeRecursive(handle.get(), timeout) == pdPASS;
default:
tt_crash();
}
}
bool Mutex::unlock() const {
assert(!kernel::isIsr());
assert(handle != nullptr);
tt_mutex_info(mutex, "release");
switch (type) {
case Type::Normal:
return xSemaphoreGive(handle.get()) == pdPASS;
case Type::Recursive:
return xSemaphoreGiveRecursive(handle.get()) == pdPASS;
default:
tt_crash();
}
}
ThreadId Mutex::getOwner() const {
assert(!kernel::isIsr());
assert(handle != nullptr);
return (ThreadId)xSemaphoreGetMutexHolder(handle.get());
}
} // namespace

View File

@ -5,7 +5,7 @@
using namespace tt; using namespace tt;
TEST_CASE("a mutex can block a thread") { TEST_CASE("a mutex can block a thread") {
auto mutex = Mutex(Mutex::Type::Normal); auto mutex = Mutex();
mutex.lock(portMAX_DELAY); mutex.lock(portMAX_DELAY);
Thread thread = Thread( Thread thread = Thread(
@ -30,19 +30,19 @@ TEST_CASE("a mutex can block a thread") {
} }
TEST_CASE("a Mutex can be locked exactly once") { TEST_CASE("a Mutex can be locked exactly once") {
auto mutex = Mutex(Mutex::Type::Normal); Mutex mutex;
CHECK_EQ(mutex.lock(0), true); CHECK_EQ(mutex.lock(0), true);
CHECK_EQ(mutex.lock(0), false); CHECK_EQ(mutex.lock(0), false);
CHECK_EQ(mutex.unlock(), true); CHECK_EQ(mutex.unlock(), true);
} }
TEST_CASE("unlocking a Mutex without locking returns false") { TEST_CASE("unlocking a Mutex without locking returns false") {
auto mutex = Mutex(Mutex::Type::Normal); Mutex mutex;
CHECK_EQ(mutex.unlock(), false); CHECK_EQ(mutex.unlock(), false);
} }
TEST_CASE("unlocking a Mutex twice returns false on the second attempt") { TEST_CASE("unlocking a Mutex twice returns false on the second attempt") {
auto mutex = Mutex(Mutex::Type::Normal); Mutex mutex;
CHECK_EQ(mutex.lock(0), true); CHECK_EQ(mutex.lock(0), true);
CHECK_EQ(mutex.unlock(), true); CHECK_EQ(mutex.unlock(), true);
CHECK_EQ(mutex.unlock(), false); CHECK_EQ(mutex.unlock(), false);