Refactor LVGL code into kernel module (#472)

* **New Features**
  * Added a standalone LVGL module and enabled LVGL support in the simulator for richer local UI testing.

* **Refactor**
  * HAL and LVGL split into distinct modules; startup and device attach/detach flows reorganized for clearer lifecycle management.
  * Public APIs tightened with clearer nullability/documentation.

* **Bug Fixes**
  * More consistent LVGL start/stop and device attach/detach behavior for improved stability.
This commit is contained in:
Ken Van Hoeylandt
2026-02-01 22:57:45 +01:00
committed by GitHub
parent 3fe1dc0312
commit 9f721e6655
135 changed files with 1553 additions and 667 deletions
+3 -5
View File
@@ -7,9 +7,6 @@ set(CMAKE_CXX_COMPILER g++)
file(GLOB_RECURSE TEST_SOURCES ${PROJECT_SOURCE_DIR}/*.cpp)
add_executable(TactilityTests EXCLUDE_FROM_ALL ${TEST_SOURCES})
add_definitions(-D_Nullable=)
add_definitions(-D_Nonnull=)
target_include_directories(TactilityTests PRIVATE
${DOCTESTINC}
)
@@ -23,7 +20,8 @@ target_link_libraries(TactilityTests PRIVATE
TactilityCore
TactilityKernel
PlatformPosix
hal-device
Simulator
hal-device-module
lvgl-module
lvgl
SDL2::SDL2-static SDL2-static
)
+1 -4
View File
@@ -7,7 +7,6 @@
#include <tactility/kernel_init.h>
#include <tactility/hal_device_module.h>
typedef struct {
int argc;
char** argv;
@@ -17,8 +16,6 @@ typedef struct {
extern "C" {
// From the relevant platform
extern struct Module platform_module;
// From the relevant device
extern struct Module device_module;
}
struct ModuleParent tactility_tests_module_parent {
@@ -36,7 +33,7 @@ void test_task(void* parameter) {
// overrides
context.setOption("no-breaks", true); // don't break in the debugger when assertions fail
check(kernel_init(&platform_module, &device_module, nullptr) == ERROR_NONE);
check(kernel_init(&platform_module, nullptr, nullptr) == ERROR_NONE);
// HAL compatibility module: it creates kernel driver wrappers for tt::hal::Device
check(module_parent_construct(&tactility_tests_module_parent) == ERROR_NONE);
check(module_set_parent(&hal_device_module, &tactility_tests_module_parent) == ERROR_NONE);
-3
View File
@@ -7,9 +7,6 @@ set(CMAKE_CXX_COMPILER g++)
file(GLOB_RECURSE TEST_SOURCES ${PROJECT_SOURCE_DIR}/*.cpp)
add_executable(TactilityCoreTests EXCLUDE_FROM_ALL ${TEST_SOURCES})
add_definitions(-D_Nullable=)
add_definitions(-D_Nonnull=)
target_include_directories(TactilityCoreTests PRIVATE
${DOCTESTINC}
)
+5 -4
View File
@@ -50,9 +50,10 @@ int main(int argc, char** argv) {
return data.result;
}
// NOTE: This is normally provided by the platform kernel module, but that's not loaded for TactilityCore
extern "C" {
// Required for FreeRTOS
void vAssertCalled(unsigned long line, const char* const file) {
__assert_fail("assert failed", file, line, "");
}
// Required for FreeRTOS
void vAssertCalled(unsigned long line, const char* const file) {
__assert_fail("assert failed", file, line, "");
}
}
-3
View File
@@ -7,9 +7,6 @@ set(CMAKE_CXX_COMPILER g++)
file(GLOB_RECURSE TEST_SOURCES ${PROJECT_SOURCE_DIR}/*.cpp)
add_executable(TactilityFreeRtosTests EXCLUDE_FROM_ALL ${TEST_SOURCES})
add_definitions(-D_Nullable=)
add_definitions(-D_Nonnull=)
target_include_directories(TactilityFreeRtosTests PRIVATE
${DOCTESTINC}
)
+5 -4
View File
@@ -50,9 +50,10 @@ int main(int argc, char** argv) {
return data.result;
}
// NOTE: This is normally provided by the platform kernel module, but that's not loaded for TactilityCore
extern "C" {
// Required for FreeRTOS
void vAssertCalled(unsigned long line, const char* const file) {
__assert_fail("assert failed", file, line, "");
}
// Required for FreeRTOS
void vAssertCalled(unsigned long line, const char* const file) {
__assert_fail("assert failed", file, line, "");
}
}
-1
View File
@@ -14,5 +14,4 @@ add_test(NAME TactilityKernelTests COMMAND TactilityKernelTests)
target_link_libraries(TactilityKernelTests PUBLIC
TactilityKernel
PlatformPosix
hal-device
)
+3 -3
View File
@@ -167,10 +167,10 @@ TEST_CASE("device_is_ready should return true only when it is started") {
Driver driver = {
.name = "test_driver",
.compatible = compatible,
.startDevice = nullptr,
.stopDevice = nullptr,
.start_device = nullptr,
.stop_device = nullptr,
.api = nullptr,
.deviceType = nullptr,
.device_type = nullptr,
.owner = &module,
.driver_private = nullptr
};
@@ -33,10 +33,10 @@ static int stop(Device* device) {
static Driver integration_driver = {
.name = "integration_test_driver",
.compatible = (const char*[]) { "integration", nullptr },
.startDevice = start,
.stopDevice = stop,
.start_device = start,
.stop_device = stop,
.api = nullptr,
.deviceType = nullptr,
.device_type = nullptr,
.owner = &module,
.driver_private = nullptr,
};
+6 -6
View File
@@ -35,10 +35,10 @@ TEST_CASE("driver_is_compatible should return true if a compatible value is foun
Driver driver = {
.name = "test_driver",
.compatible = compatible,
.startDevice = nullptr,
.stopDevice = nullptr,
.start_device = nullptr,
.stop_device = nullptr,
.api = nullptr,
.deviceType = nullptr,
.device_type = nullptr,
.owner = &module,
.driver_private = nullptr
};
@@ -52,10 +52,10 @@ TEST_CASE("driver_find should only find a compatible driver when the driver was
Driver driver = {
.name = "test_driver",
.compatible = compatible,
.startDevice = nullptr,
.stopDevice = nullptr,
.start_device = nullptr,
.stop_device = nullptr,
.api = nullptr,
.deviceType = nullptr,
.device_type = nullptr,
.owner = &module,
.driver_private = nullptr
};
-6
View File
@@ -57,9 +57,3 @@ int main(int argc, char** argv) {
return data.result;
}
extern "C" {
// Required for FreeRTOS
void vAssertCalled(unsigned long line, const char* const file) {
__assert_fail("assert failed", file, line, "");
}
}