Create TactilityFreertos subproject (#440)

This commit is contained in:
Ken Van Hoeylandt
2026-01-03 00:19:40 +01:00
committed by GitHub
parent a4dc633063
commit 7283920def
154 changed files with 1926 additions and 2676 deletions
@@ -1,10 +1,10 @@
#include <Tactility/service/ServiceRegistration.h>
#include <Tactility/Log.h>
#include <Tactility/Mutex.h>
#include <Tactility/service/ServiceInstance.h>
#include <Tactility/service/ServiceManifest.h>
#include <Tactility/Mutex.h>
#include <string>
namespace tt::service {
@@ -1,10 +1,11 @@
#include <Tactility/service/ServiceRegistration.h>
#include <Tactility/service/ServiceManifest.h>
#include <Tactility/service/ServiceContext.h>
#include <Tactility/CoreDefines.h>
#include <Tactility/Timer.h>
#include <Tactility/lvgl/LvglSync.h>
#include <Tactility/settings/DisplaySettings.h>
#include <Tactility/hal/display/DisplayDevice.h>
#include <Tactility/lvgl/LvglSync.h>
#include <Tactility/service/ServiceContext.h>
#include <Tactility/service/ServiceManifest.h>
#include <Tactility/service/ServiceRegistration.h>
#include <Tactility/settings/DisplaySettings.h>
namespace tt::service::displayidle {
@@ -61,9 +62,9 @@ public:
// Note: Settings changes require service restart to take effect
// TODO: Add DisplaySettingsChanged events for dynamic updates
timer = std::make_unique<Timer>(Timer::Type::Periodic, [this]{ this->tick(); });
timer->setThreadPriority(Thread::Priority::Lower);
timer->start(250); // check 4x per second for snappy restore
timer = std::make_unique<Timer>(Timer::Type::Periodic, kernel::millisToTicks(250), [this]{ this->tick(); });
timer->setCallbackPriority(Thread::Priority::Lower);
timer->start();
return true;
}
@@ -4,9 +4,10 @@
#ifdef CONFIG_ESP_WIFI_ENABLED
#include "Tactility/service/espnow/EspNow.h"
#include "Tactility/service/wifi/Wifi.h"
#include <Tactility/kernel/Kernel.h>
#include <Tactility/Log.h>
#include <Tactility/service/espnow/EspNow.h>
#include <Tactility/service/wifi/Wifi.h>
#include <esp_now.h>
#include <esp_wifi.h>
+25 -22
View File
@@ -25,27 +25,30 @@ void GuiService::onLoaderEvent(LoaderService::Event event) {
}
int32_t GuiService::guiMain() {
auto service = findServiceById<GuiService>(manifest.id);
while (true) {
uint32_t flags = Thread::awaitFlags(GUI_THREAD_FLAG_ALL, EventFlag::WaitAny, portMAX_DELAY);
// When service not started or starting -> exit
State service_state = getState(manifest.id);
if (service_state != State::Started && service_state != State::Starting) {
break;
}
// Process and dispatch draw call
if (flags & GUI_THREAD_FLAG_DRAW) {
Thread::clearFlags(GUI_THREAD_FLAG_DRAW);
auto service = findService();
if (service != nullptr) {
service->redraw();
uint32_t flags = 0;
if (service->threadFlags.wait(GUI_THREAD_FLAG_ALL, false, true, portMAX_DELAY, &flags)) {
// When service not started or starting -> exit
State service_state = getState(manifest.id);
if (service_state != State::Started && service_state != State::Starting) {
break;
}
}
if (flags & GUI_THREAD_FLAG_EXIT) {
Thread::clearFlags(GUI_THREAD_FLAG_EXIT);
break;
// Process and dispatch draw call
if (flags & GUI_THREAD_FLAG_DRAW) {
service->threadFlags.clear(GUI_THREAD_FLAG_DRAW);
auto service = findService();
if (service != nullptr) {
service->redraw();
}
}
if (flags & GUI_THREAD_FLAG_EXIT) {
service->threadFlags.clear(GUI_THREAD_FLAG_EXIT);
break;
}
}
}
@@ -177,8 +180,8 @@ void GuiService::onStop(TT_UNUSED ServiceContext& service) {
appToRender = nullptr;
isStarted = false;
ThreadId thread_id = thread->getId();
Thread::setFlags(thread_id, GUI_THREAD_FLAG_EXIT);
auto task_handle = thread->getTaskHandle();
threadFlags.set(GUI_THREAD_FLAG_EXIT);
thread->join();
delete thread;
@@ -190,8 +193,8 @@ void GuiService::onStop(TT_UNUSED ServiceContext& service) {
}
void GuiService::requestDraw() {
ThreadId thread_id = thread->getId();
Thread::setFlags(thread_id, GUI_THREAD_FLAG_DRAW);
auto task_handle = thread->getTaskHandle();
threadFlags.set(GUI_THREAD_FLAG_DRAW);
}
void GuiService::showApp(std::shared_ptr<app::AppInstance> app) {
@@ -1,12 +1,13 @@
#ifdef ESP_PLATFORM
#include <Tactility/service/ServiceRegistration.h>
#include <Tactility/service/ServiceManifest.h>
#include <Tactility/service/ServiceContext.h>
#include <Tactility/Timer.h>
#include <Tactility/lvgl/LvglSync.h>
#include <Tactility/settings/KeyboardSettings.h>
#include <Tactility/CoreDefines.h>
#include <Tactility/hal/keyboard/KeyboardDevice.h>
#include <Tactility/lvgl/LvglSync.h>
#include <Tactility/service/ServiceContext.h>
#include <Tactility/service/ServiceManifest.h>
#include <Tactility/service/ServiceRegistration.h>
#include <Tactility/settings/KeyboardSettings.h>
#include <Tactility/Timer.h>
namespace keyboardbacklight {
bool setBrightness(uint8_t brightness);
@@ -67,9 +68,9 @@ public:
// Note: Settings changes require service restart to take effect
// TODO: Add KeyboardSettingsChanged events for dynamic updates
timer = std::make_unique<Timer>(Timer::Type::Periodic, [this]{ this->tick(); });
timer->setThreadPriority(Thread::Priority::Lower);
timer->start(250); // check 4x per second for snappy restore
timer = std::make_unique<Timer>(Timer::Type::Periodic, kernel::millisToTicks(250), [this]{ this->tick(); });
timer->setCallbackPriority(Thread::Priority::Lower);
timer->start();
return true;
}
@@ -8,7 +8,6 @@
namespace tt::service::memorychecker {
constexpr const char* TAG = "MemoryChecker";
constexpr TickType_t TIMER_UPDATE_INTERVAL = 2000U / portTICK_PERIOD_MS;
// Total memory (in bytes) that should be free before warnings occur
constexpr auto TOTAL_FREE_THRESHOLD = 10'000;
@@ -58,8 +57,8 @@ bool MemoryCheckerService::onStart(ServiceContext& service) {
statusbarIconId = lvgl::statusbar_icon_add(icon_path, false);
lvgl::statusbar_icon_set_visibility(statusbarIconId, false);
timer.setThreadPriority(Thread::Priority::Lower);
timer.start(TIMER_UPDATE_INTERVAL);
timer.setCallbackPriority(Thread::Priority::Lower);
timer.start();
return true;
}
@@ -2,11 +2,13 @@
#if TT_FEATURE_SCREENSHOT_ENABLED
#include <Tactility/Log.h>
#include <Tactility/LogMessages.h>
#include <Tactility/service/screenshot/Screenshot.h>
#include <Tactility/service/ServiceRegistration.h>
#include <memory>
#include <lvgl.h>
#include <memory>
namespace tt::service::screenshot {
@@ -159,7 +159,7 @@ void ScreenshotTask::stop() {
if (thread != nullptr) {
if (mutex.lock(50 / portTICK_PERIOD_MS)) {
interrupted = true;
tt_check(mutex.unlock());
mutex.unlock();
}
thread->join();
@@ -167,7 +167,7 @@ void ScreenshotTask::stop() {
if (mutex.lock(50 / portTICK_PERIOD_MS)) {
delete thread;
thread = nullptr;
tt_check(mutex.unlock());
mutex.unlock();
}
}
}
+3 -3
View File
@@ -1,9 +1,9 @@
#include <Tactility/service/ServiceContext.h>
#include <Tactility/service/ServiceRegistration.h>
#include <Tactility/Timer.h>
#include <Tactility/Mutex.h>
#include <Tactility/Tactility.h>
#include <Tactility/Timer.h>
#include <Tactility/hal/sdcard/SdCardDevice.h>
namespace tt::service::sdcard {
@@ -60,12 +60,12 @@ public:
}
auto service = findServiceById<SdCardService>(manifest.id);
updateTimer = std::make_unique<Timer>(Timer::Type::Periodic, [service]() {
updateTimer = std::make_unique<Timer>(Timer::Type::Periodic, 1000, [service] {
service->update();
});
// We want to try and scan more often in case of startup or scan lock failure
updateTimer->start(1000);
updateTimer->start();
return true;
}
@@ -1,16 +1,16 @@
#include <Tactility/lvgl/Statusbar.h>
#include <Tactility/Timer.h>
#include <Tactility/Mutex.h>
#include <Tactility/hal/power/PowerDevice.h>
#include <Tactility/hal/sdcard/SdCardDevice.h>
#include <Tactility/lvgl/Lvgl.h>
#include <Tactility/lvgl/LvglSync.h>
#include <Tactility/Mutex.h>
#include <Tactility/service/gps/GpsService.h>
#include <Tactility/service/ServiceContext.h>
#include <Tactility/service/ServicePaths.h>
#include <Tactility/service/ServiceRegistration.h>
#include <Tactility/service/gps/GpsService.h>
#include <Tactility/service/wifi/Wifi.h>
#include <Tactility/Timer.h>
namespace tt::service::statusbar {
@@ -265,14 +265,14 @@ public:
assert(service);
service->update();
updateTimer = std::make_unique<Timer>(Timer::Type::Periodic, [service] {
updateTimer = std::make_unique<Timer>(Timer::Type::Periodic, pdMS_TO_TICKS(1000), [service] {
service->update();
});
updateTimer->setThreadPriority(Thread::Priority::Lower);
updateTimer->setCallbackPriority(Thread::Priority::Lower);
// We want to try and scan more often in case of startup or scan lock failure
updateTimer->start(1000);
updateTimer->start();
return true;
}
+2 -1
View File
@@ -1,5 +1,6 @@
#include "Tactility/service/wifi/Wifi.h"
#include <Tactility/service/wifi/Wifi.h>
#include <Tactility/Check.h>
#include <Tactility/service/ServiceManifest.h>
#include <Tactility/service/ServiceRegistration.h>
+33 -30
View File
@@ -6,15 +6,15 @@
#include <Tactility/service/wifi/Wifi.h>
#include <Tactility/EventFlag.h>
#include <Tactility/Timer.h>
#include <Tactility/EventGroup.h>
#include <Tactility/RecursiveMutex.h>
#include <Tactility/Tactility.h>
#include <Tactility/kernel/SystemEvents.h>
#include <Tactility/RecursiveMutex.h>
#include <Tactility/service/ServiceContext.h>
#include <Tactility/service/wifi/WifiBootSplashInit.h>
#include <Tactility/service/wifi/WifiGlobals.h>
#include <Tactility/service/wifi/WifiSettings.h>
#include <Tactility/service/wifi/WifiBootSplashInit.h>
#include <Tactility/Timer.h>
#include <lwip/esp_netif_net_stack.h>
#include <freertos/FreeRTOS.h>
@@ -66,10 +66,10 @@ public:
/** @brief Maximum amount of records to scan (value > 0) */
uint16_t scan_list_limit = TT_WIFI_SCAN_RECORD_LIMIT;
/** @brief when we last requested a scan. Loops around every 50 days. */
TickType_t last_scan_time = portMAX_DELAY;
TickType_t last_scan_time = kernel::MAX_TICKS;
esp_event_handler_instance_t event_handler_any_id = nullptr;
esp_event_handler_instance_t event_handler_got_ip = nullptr;
EventFlag connection_wait_flags;
EventGroup connection_wait_flags;
settings::WifiApSettings connection_target;
bool pause_auto_connect = false; // Pause when manually disconnecting until manually connecting again
bool connection_target_remember = false; // Whether to store the connection_target on successful connection or not
@@ -792,32 +792,34 @@ static void dispatchConnect(std::shared_ptr<Wifi> wifi) {
/* Waiting until either the connection is established (WIFI_CONNECTED_BIT)
* or connection failed for the maximum number of re-tries (WIFI_FAIL_BIT).
* The bits are set by wifi_event_handler() */
uint32_t bits = wifi_singleton->connection_wait_flags.wait(WIFI_FAIL_BIT | WIFI_CONNECTED_BIT);
TT_LOG_I(TAG, "Waiting for EventFlag by event_handler()");
uint32_t bits;
if (wifi_singleton->connection_wait_flags.wait(WIFI_FAIL_BIT | WIFI_CONNECTED_BIT, false, true, kernel::MAX_TICKS, &bits)) {
TT_LOG_I(TAG, "Waiting for EventGroup by event_handler()");
if (bits & WIFI_CONNECTED_BIT) {
wifi->setSecureConnection(config.sta.password[0] != 0x00U);
wifi->setRadioState(RadioState::ConnectionActive);
publish_event(wifi, WifiEvent::ConnectionSuccess);
TT_LOG_I(TAG, "Connected to %s", wifi->connection_target.ssid.c_str());
if (wifi->connection_target_remember) {
if (!settings::save(wifi->connection_target)) {
TT_LOG_E(TAG, "Failed to store credentials");
} else {
TT_LOG_I(TAG, "Stored credentials");
if (bits & WIFI_CONNECTED_BIT) {
wifi->setSecureConnection(config.sta.password[0] != 0x00U);
wifi->setRadioState(RadioState::ConnectionActive);
publish_event(wifi, WifiEvent::ConnectionSuccess);
TT_LOG_I(TAG, "Connected to %s", wifi->connection_target.ssid.c_str());
if (wifi->connection_target_remember) {
if (!settings::save(wifi->connection_target)) {
TT_LOG_E(TAG, "Failed to store credentials");
} else {
TT_LOG_I(TAG, "Stored credentials");
}
}
} else if (bits & WIFI_FAIL_BIT) {
wifi->setRadioState(RadioState::On);
publish_event(wifi, WifiEvent::ConnectionFailed);
TT_LOG_I(TAG, "Failed to connect to %s", wifi->connection_target.ssid.c_str());
} else {
wifi->setRadioState(RadioState::On);
publish_event(wifi, WifiEvent::ConnectionFailed);
TT_LOG_E(TAG, "UNEXPECTED EVENT");
}
} else if (bits & WIFI_FAIL_BIT) {
wifi->setRadioState(RadioState::On);
publish_event(wifi, WifiEvent::ConnectionFailed);
TT_LOG_I(TAG, "Failed to connect to %s", wifi->connection_target.ssid.c_str());
} else {
wifi->setRadioState(RadioState::On);
publish_event(wifi, WifiEvent::ConnectionFailed);
TT_LOG_E(TAG, "UNEXPECTED EVENT");
}
wifi_singleton->connection_wait_flags.clear(WIFI_FAIL_BIT | WIFI_CONNECTED_BIT);
wifi_singleton->connection_wait_flags.clear(WIFI_FAIL_BIT | WIFI_CONNECTED_BIT);
}
}
static void dispatchDisconnectButKeepActive(std::shared_ptr<Wifi> wifi) {
@@ -920,9 +922,10 @@ public:
bootSplashInit();
});
wifi_singleton->autoConnectTimer = std::make_unique<Timer>(Timer::Type::Periodic, []() { onAutoConnectTimer(); });
auto timer_interval = std::min(2000, AUTO_SCAN_INTERVAL);
wifi_singleton->autoConnectTimer = std::make_unique<Timer>(Timer::Type::Periodic, timer_interval, [] { onAutoConnectTimer(); });
// We want to try and scan more often in case of startup or scan lock failure
wifi_singleton->autoConnectTimer->start(std::min(2000, AUTO_SCAN_INTERVAL));
wifi_singleton->autoConnectTimer->start();
if (settings::shouldEnableOnBoot()) {
TT_LOG_I(TAG, "Auto-enabling due to setting");
+6 -1
View File
@@ -2,9 +2,9 @@
#include <Tactility/service/wifi/Wifi.h>
#include <Tactility/PubSub.h>
#include <Tactility/Check.h>
#include <Tactility/Log.h>
#include <Tactility/PubSub.h>
#include <Tactility/RecursiveMutex.h>
#include <Tactility/service/Service.h>
#include <Tactility/service/ServiceManifest.h>
@@ -81,26 +81,31 @@ std::vector<ApRecord> getScanResults() {
records.push_back((ApRecord) {
.ssid = "Home Wifi",
.rssi = -30,
.channel = 0,
.auth_mode = WIFI_AUTH_WPA2_PSK
});
records.push_back((ApRecord) {
.ssid = "No place like 127.0.0.1",
.rssi = -67,
.channel = 0,
.auth_mode = WIFI_AUTH_WPA2_PSK
});
records.push_back((ApRecord) {
.ssid = "Pretty fly for a Wi-Fi",
.rssi = -70,
.channel = 0,
.auth_mode = WIFI_AUTH_WPA2_PSK
});
records.push_back((ApRecord) {
.ssid = "An AP with a really, really long name",
.rssi = -80,
.channel = 0,
.auth_mode = WIFI_AUTH_WPA2_PSK
});
records.push_back((ApRecord) {
.ssid = "Bad Reception",
.rssi = -90,
.channel = 0,
.auth_mode = WIFI_AUTH_OPEN
});