mirror of
https://github.com/ByteWelder/Tactility.git
synced 2026-04-18 09:25:06 +00:00
Refactor LVGL into module for POSIX
This commit is contained in:
parent
2cf5c3c853
commit
73319c7ba4
@ -1,107 +0,0 @@
|
||||
#include "LvglTask.h"
|
||||
|
||||
#include <Tactility/Logger.h>
|
||||
#include <Tactility/RecursiveMutex.h>
|
||||
#include <Tactility/Thread.h>
|
||||
#include <tactility/check.h>
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
|
||||
#include <lvgl.h>
|
||||
|
||||
static const auto LOGGER = tt::Logger("LvglTask");
|
||||
|
||||
// Mutex for LVGL drawing
|
||||
static tt::RecursiveMutex lvgl_mutex;
|
||||
static tt::RecursiveMutex task_mutex;
|
||||
|
||||
static uint32_t task_max_sleep_ms = 10;
|
||||
// Mutex for LVGL task state (to modify task_running state)
|
||||
static bool task_running = false;
|
||||
|
||||
lv_disp_t* displayHandle = nullptr;
|
||||
|
||||
static void lvgl_task(void* arg);
|
||||
|
||||
static bool task_lock(TickType_t timeout) {
|
||||
return task_mutex.lock(timeout);
|
||||
}
|
||||
|
||||
static void task_unlock() {
|
||||
task_mutex.unlock();
|
||||
}
|
||||
|
||||
static void task_set_running(bool running) {
|
||||
assert(task_lock(configTICK_RATE_HZ / 100));
|
||||
task_running = running;
|
||||
task_unlock();
|
||||
}
|
||||
|
||||
bool lvgl_task_is_running() {
|
||||
assert(task_lock(configTICK_RATE_HZ / 100));
|
||||
bool result = task_running;
|
||||
task_unlock();
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool lvgl_lock(uint32_t timeoutMillis) {
|
||||
return lvgl_mutex.lock(pdMS_TO_TICKS(timeoutMillis));
|
||||
}
|
||||
|
||||
static void lvgl_unlock() {
|
||||
lvgl_mutex.unlock();
|
||||
}
|
||||
|
||||
void lvgl_task_interrupt() {
|
||||
check(task_lock(portMAX_DELAY));
|
||||
task_set_running(false); // interrupt task with boolean as flag
|
||||
task_unlock();
|
||||
}
|
||||
|
||||
void lvgl_task_start() {
|
||||
LOGGER.info("LVGL task starting");
|
||||
|
||||
|
||||
// Create the main app loop, like ESP-IDF
|
||||
BaseType_t task_result = xTaskCreate(
|
||||
lvgl_task,
|
||||
"lvgl",
|
||||
8192,
|
||||
nullptr,
|
||||
static_cast<UBaseType_t>(tt::Thread::Priority::High), // Should be higher than main app task
|
||||
nullptr
|
||||
);
|
||||
|
||||
assert(task_result == pdTRUE);
|
||||
}
|
||||
|
||||
static void lvgl_task(void* arg) {
|
||||
LOGGER.info("LVGL task started");
|
||||
|
||||
/** Ideally. the display handle would be created during Simulator.start(),
|
||||
* but somehow that doesn't work. Waiting here from a ThreadFlag when that happens
|
||||
* also doesn't work. It seems that it must be called from this task. */
|
||||
displayHandle = lv_sdl_window_create(320, 240);
|
||||
lv_sdl_window_set_title(displayHandle, "Tactility");
|
||||
|
||||
uint32_t task_delay_ms = task_max_sleep_ms;
|
||||
|
||||
task_set_running(true);
|
||||
|
||||
while (lvgl_task_is_running()) {
|
||||
if (lvgl_lock(10)) {
|
||||
task_delay_ms = lv_timer_handler();
|
||||
lvgl_unlock();
|
||||
}
|
||||
if ((task_delay_ms > task_max_sleep_ms) || (1 == task_delay_ms)) {
|
||||
task_delay_ms = task_max_sleep_ms;
|
||||
} else if (task_delay_ms < 1) {
|
||||
task_delay_ms = 1;
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(task_delay_ms));
|
||||
}
|
||||
|
||||
lv_disp_remove(displayHandle);
|
||||
displayHandle = nullptr;
|
||||
vTaskDelete(nullptr);
|
||||
}
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
void lvgl_task_start();
|
||||
bool lvgl_task_is_running();
|
||||
void lvgl_task_interrupt();
|
||||
@ -1,4 +1,3 @@
|
||||
#include "LvglTask.h"
|
||||
#include "hal/SdlDisplay.h"
|
||||
#include "hal/SdlKeyboard.h"
|
||||
#include "hal/SimulatorPower.h"
|
||||
@ -11,23 +10,6 @@
|
||||
|
||||
using namespace tt::hal;
|
||||
|
||||
static bool initBoot() {
|
||||
lv_init();
|
||||
lvgl_task_start();
|
||||
return true;
|
||||
}
|
||||
|
||||
static void deinitPower() {
|
||||
lvgl_task_interrupt();
|
||||
while (lvgl_task_is_running()) {
|
||||
tt::kernel::delayMillis(10);
|
||||
}
|
||||
|
||||
#if LV_ENABLE_GC || !LV_MEM_CUSTOM
|
||||
lv_deinit();
|
||||
#endif
|
||||
}
|
||||
|
||||
static std::vector<std::shared_ptr<tt::hal::Device>> createDevices() {
|
||||
return {
|
||||
std::make_shared<SdlDisplay>(),
|
||||
@ -38,7 +20,7 @@ static std::vector<std::shared_ptr<tt::hal::Device>> createDevices() {
|
||||
}
|
||||
|
||||
extern const Configuration hardwareConfiguration = {
|
||||
.initBoot = initBoot,
|
||||
.initBoot = nullptr,
|
||||
.createDevices = createDevices,
|
||||
.uart = {
|
||||
uart::Configuration {
|
||||
|
||||
@ -13,21 +13,24 @@ public:
|
||||
std::string getName() const override { return "SDL Display"; }
|
||||
std::string getDescription() const override { return ""; }
|
||||
|
||||
bool start() override {
|
||||
bool start() override { return true; }
|
||||
|
||||
bool stop() override { return true; }
|
||||
|
||||
bool supportsLvgl() const override { return true; }
|
||||
|
||||
bool startLvgl() override {
|
||||
displayHandle = lv_sdl_window_create(320, 240);
|
||||
lv_sdl_window_set_title(displayHandle, "Tactility");
|
||||
return true;
|
||||
return displayHandle != nullptr;
|
||||
}
|
||||
|
||||
bool stop() override {
|
||||
bool stopLvgl() override {
|
||||
lv_display_delete(displayHandle);
|
||||
displayHandle = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool supportsLvgl() const override { return true; }
|
||||
bool startLvgl() override { return displayHandle != nullptr; }
|
||||
bool stopLvgl() override { check(false, "Not supported"); }
|
||||
lv_display_t* getLvglDisplay() const override { return displayHandle; }
|
||||
|
||||
std::shared_ptr<tt::hal::touch::TouchDevice> getTouchDevice() override { return std::make_shared<SdlTouch>(); }
|
||||
|
||||
@ -7,7 +7,6 @@ if (DEFINED ENV{ESP_IDF_VERSION})
|
||||
idf_component_register(
|
||||
SRCS ${SOURCE_FILES}
|
||||
INCLUDE_DIRS "Include/"
|
||||
PRIV_INCLUDE_DIRS "Private/"
|
||||
REQUIRES lvgl esp_lvgl_port
|
||||
)
|
||||
|
||||
@ -19,7 +18,6 @@ else ()
|
||||
|
||||
target_include_directories(lvgl-module
|
||||
PUBLIC Include/
|
||||
PRIVATE Private/
|
||||
)
|
||||
|
||||
target_link_libraries(lvgl-module PUBLIC
|
||||
|
||||
@ -1,11 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
bool lvgl_is_stop_requested();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@ -10,7 +10,9 @@
|
||||
|
||||
#include <lvgl.h>
|
||||
|
||||
#include "lvgl_module_private.h"
|
||||
#include "tactility/lvgl_module.h"
|
||||
|
||||
extern struct LvglModuleConfig lvgl_module_config;
|
||||
|
||||
// Mutex for LVGL drawing
|
||||
static struct RecursiveMutex lvgl_mutex;
|
||||
@ -80,6 +82,8 @@ static void lvgl_task(void* arg) {
|
||||
|
||||
check(!lvgl_task_is_interrupt_requested());
|
||||
|
||||
if (lvgl_module_config.on_start) lvgl_module_config.on_start();
|
||||
|
||||
while (!lvgl_task_is_interrupt_requested()) {
|
||||
if (lvgl_try_lock_timed(10)) {
|
||||
task_delay_ms = lv_timer_handler();
|
||||
@ -93,10 +97,14 @@ static void lvgl_task(void* arg) {
|
||||
vTaskDelay(pdMS_TO_TICKS(task_delay_ms));
|
||||
}
|
||||
|
||||
if (lvgl_module_config.on_stop) lvgl_module_config.on_stop();
|
||||
|
||||
vTaskDelete(nullptr);
|
||||
}
|
||||
|
||||
error_t lvgl_arch_start() {
|
||||
lv_init();
|
||||
|
||||
// Create the main app loop, like ESP-IDF
|
||||
BaseType_t task_result = xTaskCreate(
|
||||
lvgl_task,
|
||||
@ -119,6 +127,9 @@ error_t lvgl_arch_stop() {
|
||||
return ERROR_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
lv_deinit();
|
||||
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
|
||||
@ -8,13 +8,13 @@ error_t lvgl_arch_stop();
|
||||
|
||||
static bool is_running;
|
||||
|
||||
static struct LvglModuleConfig config = {
|
||||
struct LvglModuleConfig lvgl_module_config = {
|
||||
nullptr,
|
||||
nullptr
|
||||
};
|
||||
|
||||
void lvgl_module_configure(const struct LvglModuleConfig in_config) {
|
||||
memcpy(&config, &in_config, sizeof(struct LvglModuleConfig));
|
||||
void lvgl_module_configure(const struct LvglModuleConfig config) {
|
||||
memcpy(&lvgl_module_config, &config, sizeof(struct LvglModuleConfig));
|
||||
}
|
||||
|
||||
static error_t start() {
|
||||
@ -25,7 +25,6 @@ static error_t start() {
|
||||
error_t result = lvgl_arch_start();
|
||||
if (result == ERROR_NONE) {
|
||||
is_running = true;
|
||||
if (config.on_start) config.on_start();
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -39,7 +38,6 @@ static error_t stop() {
|
||||
error_t error = lvgl_arch_stop();
|
||||
if (error == ERROR_NONE) {
|
||||
is_running = false;
|
||||
if (config.on_stop) config.on_stop();
|
||||
}
|
||||
|
||||
return error;
|
||||
|
||||
11
Tactility/Private/Tactility/lvgl/LvglPrivate.h
Normal file
11
Tactility/Private/Tactility/lvgl/LvglPrivate.h
Normal file
@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <Tactility/lvgl/Lvgl.h>
|
||||
|
||||
namespace tt::lvgl {
|
||||
|
||||
void attachDevices();
|
||||
|
||||
void detachDevices();
|
||||
|
||||
}
|
||||
@ -14,7 +14,7 @@
|
||||
#include <Tactility/hal/HalPrivate.h>
|
||||
#include <Tactility/Logger.h>
|
||||
#include <Tactility/LogMessages.h>
|
||||
#include <Tactility/lvgl/Lvgl.h>
|
||||
#include <Tactility/lvgl/LvglPrivate.h>
|
||||
#include <Tactility/MountPoints.h>
|
||||
#include <Tactility/network/NtpPrivate.h>
|
||||
#include <Tactility/service/ServiceManifest.h>
|
||||
@ -358,8 +358,8 @@ void run(const Configuration& config, Module* platformModule, Module* deviceModu
|
||||
registerAndStartPrimaryServices();
|
||||
|
||||
lvgl_module_configure((LvglModuleConfig) {
|
||||
.on_start = lvgl::start,
|
||||
.on_stop = lvgl::stop
|
||||
.on_start = lvgl::attachDevices,
|
||||
.on_stop = lvgl::detachDevices
|
||||
});
|
||||
module_set_parent(&lvgl_module, &tactility_module_parent);
|
||||
lvgl::start();
|
||||
|
||||
@ -23,7 +23,7 @@ bool isStarted() {
|
||||
return module_is_started(&lvgl_module);
|
||||
}
|
||||
|
||||
static void on_start() {
|
||||
void attachDevices() {
|
||||
LOGGER.info("Adding devices");
|
||||
|
||||
auto lock = getSyncLock()->asScopedLock();
|
||||
@ -120,7 +120,7 @@ static void on_start() {
|
||||
}
|
||||
}
|
||||
|
||||
static void on_stop() {
|
||||
void detachDevices() {
|
||||
LOGGER.info("Removing devices");
|
||||
|
||||
auto lock = getSyncLock()->asScopedLock();
|
||||
@ -174,6 +174,7 @@ static void on_stop() {
|
||||
}
|
||||
|
||||
void start() {
|
||||
tt::lvgl::syncSet(&lvgl_try_lock_timed, &lvgl_unlock);
|
||||
check(module_start(&lvgl_module) == ERROR_NONE);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user