Add FreeRTOS Kernel and C++ Support to Simulator (#59)
* Add FreeRTOS * Add FreeRTOS Task * Update README.md * Upgrade to C++ * Update Code to run multiple tasks * Add ui folder Add UI folder for SquareLine Studio files * Update ui.cpp * Add UI files to CMake from SquareLine Studio Add UI files to CMake path. UI folder setup so files from SquareLine Studio can be used. Add more heap to debug SDL. * Update README.md * Add drop den menu test * Add global include file * remove cpp file to test stability * Fixing wrong cmake configuration remove ui files from here * work * Change project structure Changed project structure and CMake file so freertos implementation will be activated when enabled in lv_conf.h * Refactor project structure and CMake configuration, remove unused UI components - Restructured the project and updated the CMake file to conditionally activate FreeRTOS based on lv_conf.h settings. - Removed UI files and C++ files related to SquareLine Studio to improve project stability. - Added a global include. - Updated the README.md to reflect the changes. - Increased heap size for debugging with SDL. * Move to CPP file Moved to cpp file created task with lv_thread_init() * Update freertos_main.cpp * Clean up code Not using task notification, since pxTCD is always NULL Changed back to LV_OS_NONE since user of this project has to device what he want to use Commented freertos posix file with AI :) Cleanup freertos_main.cpp as mentioned in PR * Update README.md Co-authored-by: Gabor Kiss-Vamosi <kisvegabor@gmail.com> * Update README.md * Update main/src/FreeRTOS_Posix_Port.c Co-authored-by: Gabor Kiss-Vamosi <kisvegabor@gmail.com> * Update main/src/main.c Co-authored-by: Gabor Kiss-Vamosi <kisvegabor@gmail.com> * Update README.md Co-authored-by: Gabor Kiss-Vamosi <kisvegabor@gmail.com> * Update README.md * Update README.md --------- Co-authored-by: Gabor Kiss-Vamosi <kisvegabor@gmail.com>
This commit is contained in:
parent
bbb4c82266
commit
0a8220a874
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -4,3 +4,6 @@
|
|||||||
[submodule "lvgl"]
|
[submodule "lvgl"]
|
||||||
path = lvgl
|
path = lvgl
|
||||||
url = https://github.com/lvgl/lvgl.git
|
url = https://github.com/lvgl/lvgl.git
|
||||||
|
[submodule "FreeRTOS"]
|
||||||
|
path = FreeRTOS
|
||||||
|
url = https://github.com/FreeRTOS/FreeRTOS-Kernel.git
|
||||||
|
|||||||
104
CMakeLists.txt
104
CMakeLists.txt
@ -1,70 +1,130 @@
|
|||||||
cmake_minimum_required(VERSION 3.10)
|
cmake_minimum_required(VERSION 3.10)
|
||||||
project(lvgl)
|
project(lvgl C CXX)
|
||||||
|
|
||||||
|
# Set the correct FreeRTOS port for your system (e.g., Posix for WSL)
|
||||||
|
set(FREERTOS_PORT GCC_POSIX CACHE STRING "Port for FreeRTOS on Posix environment")
|
||||||
|
|
||||||
|
# Check if the FreeRTOS directory exists
|
||||||
|
if(EXISTS "${PROJECT_SOURCE_DIR}/FreeRTOS")
|
||||||
|
message(STATUS "FreeRTOS found, integrating into the build")
|
||||||
|
|
||||||
|
# Add FreeRTOS configuration as an interface library
|
||||||
|
add_library(freertos_config INTERFACE)
|
||||||
|
target_include_directories(freertos_config SYSTEM INTERFACE ${PROJECT_SOURCE_DIR}/config)
|
||||||
|
target_compile_definitions(freertos_config INTERFACE projCOVERAGE_TEST=0)
|
||||||
|
add_definitions(-DFREERTOS_PORT=${FREERTOS_PORT})
|
||||||
|
|
||||||
|
# Add FreeRTOS as a subdirectory
|
||||||
|
add_subdirectory(FreeRTOS)
|
||||||
|
|
||||||
|
# Include directories for FreeRTOS headers
|
||||||
|
include_directories(${PROJECT_SOURCE_DIR}/FreeRTOS/include)
|
||||||
|
include_directories(${PROJECT_SOURCE_DIR}/FreeRTOS/portable/ThirdParty/GCC/Posix)
|
||||||
|
include_directories(${PROJECT_SOURCE_DIR}/config)
|
||||||
|
|
||||||
|
# Add FreeRTOS source files
|
||||||
|
file(GLOB FREERTOS_SOURCES
|
||||||
|
"${PROJECT_SOURCE_DIR}/FreeRTOS/*.c"
|
||||||
|
"${PROJECT_SOURCE_DIR}/FreeRTOS/portable/MemMang/heap_4.c"
|
||||||
|
"${PROJECT_SOURCE_DIR}/FreeRTOS/portable/ThirdParty/GCC/Posix/*.c"
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
message(STATUS "FreeRTOS not found, skipping FreeRTOS integration")
|
||||||
|
set(FREERTOS_SOURCES "")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Main include files of the project
|
||||||
|
include_directories(${PROJECT_SOURCE_DIR}/main/inc)
|
||||||
|
|
||||||
|
# Define options for LVGL with default values (OFF)
|
||||||
option(LV_USE_DRAW_SDL "Use SDL draw unit" OFF)
|
option(LV_USE_DRAW_SDL "Use SDL draw unit" OFF)
|
||||||
option(LV_USE_LIBPNG "Use libpng to decode PNG" OFF)
|
option(LV_USE_LIBPNG "Use libpng to decode PNG" OFF)
|
||||||
option(LV_USE_LIBJPEG_TURBO "Use libjpeg turbo to decode JPEG" OFF)
|
option(LV_USE_LIBJPEG_TURBO "Use libjpeg turbo to decode JPEG" OFF)
|
||||||
option(LV_USE_FFMPEG "Use libffmpeg to display video using lv_ffmpeg" OFF)
|
option(LV_USE_FFMPEG "Use libffmpeg to display video using lv_ffmpeg" OFF)
|
||||||
option(LV_USE_FREETYPE "Use freetype lib" OFF)
|
option(LV_USE_FREETYPE "Use freetype library" OFF)
|
||||||
|
|
||||||
set(CMAKE_C_STANDARD 99)#C99 # lvgl officially support C99 and above
|
# Set C and C++ standards
|
||||||
set(CMAKE_CXX_STANDARD 17)#C17
|
set(CMAKE_C_STANDARD 99)
|
||||||
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
|
# Set the output path for the executable
|
||||||
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
|
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
|
||||||
set(WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
set(WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
||||||
|
|
||||||
find_package(SDL2 REQUIRED SDL2)
|
# Find and include SDL2 library
|
||||||
|
find_package(SDL2 REQUIRED)
|
||||||
|
|
||||||
|
# Remove ARM-specific compile and linker options
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native")
|
||||||
|
|
||||||
|
# Add compile definitions based on the selected options
|
||||||
add_compile_definitions($<$<BOOL:${LV_USE_DRAW_SDL}>:LV_USE_DRAW_SDL=1>)
|
add_compile_definitions($<$<BOOL:${LV_USE_DRAW_SDL}>:LV_USE_DRAW_SDL=1>)
|
||||||
add_compile_definitions($<$<BOOL:${LV_USE_LIBPNG}>:LV_USE_LIBPNG=1>)
|
add_compile_definitions($<$<BOOL:${LV_USE_LIBPNG}>:LV_USE_LIBPNG=1>)
|
||||||
add_compile_definitions($<$<BOOL:${LV_USE_LIBJPEG_TURBO}>:LV_USE_LIBJPEG_TURBO=1>)
|
add_compile_definitions($<$<BOOL:${LV_USE_LIBJPEG_TURBO}>:LV_USE_LIBJPEG_TURBO=1>)
|
||||||
add_compile_definitions($<$<BOOL:${LV_USE_FFMPEG}>:LV_USE_FFMPEG=1>)
|
add_compile_definitions($<$<BOOL:${LV_USE_FFMPEG}>:LV_USE_FFMPEG=1>)
|
||||||
|
|
||||||
|
# Add LVGL subdirectory
|
||||||
add_subdirectory(lvgl)
|
add_subdirectory(lvgl)
|
||||||
target_include_directories(lvgl PUBLIC ${PROJECT_SOURCE_DIR} ${SDL2_INCLUDE_DIRS})
|
target_include_directories(lvgl PUBLIC ${PROJECT_SOURCE_DIR} ${SDL2_INCLUDE_DIRS})
|
||||||
|
|
||||||
add_executable(main main/src/main.c main/src/mouse_cursor_icon.c)
|
# Create the main executable and add source files
|
||||||
|
add_executable(main
|
||||||
|
${PROJECT_SOURCE_DIR}/main/src/main.c
|
||||||
|
${PROJECT_SOURCE_DIR}/main/src/freertos_main.cpp
|
||||||
|
${PROJECT_SOURCE_DIR}/main/src/mouse_cursor_icon.c
|
||||||
|
${PROJECT_SOURCE_DIR}/main/src/FreeRTOS_Posix_Port.c
|
||||||
|
${FREERTOS_SOURCES}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Define LVGL configuration as a simple include
|
||||||
target_compile_definitions(main PRIVATE LV_CONF_INCLUDE_SIMPLE)
|
target_compile_definitions(main PRIVATE LV_CONF_INCLUDE_SIMPLE)
|
||||||
target_link_libraries(main lvgl lvgl::examples lvgl::demos lvgl::thorvg ${SDL2_LIBRARIES} m pthread)
|
target_link_libraries(main lvgl lvgl::examples lvgl::demos lvgl::thorvg ${SDL2_LIBRARIES} m pthread)
|
||||||
|
|
||||||
|
# Only link FreeRTOS if the FreeRTOS directory exists
|
||||||
|
if(EXISTS "${PROJECT_SOURCE_DIR}/FreeRTOS")
|
||||||
|
target_link_libraries(main freertos_config)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Custom target to run the executable
|
||||||
add_custom_target(run COMMAND ${EXECUTABLE_OUTPUT_PATH}/main DEPENDS main)
|
add_custom_target(run COMMAND ${EXECUTABLE_OUTPUT_PATH}/main DEPENDS main)
|
||||||
|
|
||||||
|
# Conditionally include and link SDL2_image if LV_USE_DRAW_SDL is enabled
|
||||||
if(LV_USE_DRAW_SDL)
|
if(LV_USE_DRAW_SDL)
|
||||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
|
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
|
||||||
# Need to install libsdl2-image-dev
|
|
||||||
# `sudo apt install libsdl2-image-dev`
|
|
||||||
# `brew install sdl2_image`
|
|
||||||
find_package(SDL2_image REQUIRED)
|
find_package(SDL2_image REQUIRED)
|
||||||
target_include_directories(lvgl PUBLIC ${SDL2_IMAGE_INCLUDE_DIRS})
|
target_include_directories(lvgl PUBLIC ${SDL2_IMAGE_INCLUDE_DIRS})
|
||||||
target_link_libraries(main ${SDL2_IMAGE_LIBRARIES})
|
target_link_libraries(main ${SDL2_IMAGE_LIBRARIES})
|
||||||
endif(LV_USE_DRAW_SDL)
|
endif()
|
||||||
|
|
||||||
|
# Conditionally include and link libpng if LV_USE_LIBPNG is enabled
|
||||||
if(LV_USE_LIBPNG)
|
if(LV_USE_LIBPNG)
|
||||||
find_package(PNG REQUIRED)
|
find_package(PNG REQUIRED)
|
||||||
target_include_directories(lvgl PUBLIC ${PNG_INCLUDE_DIR})
|
target_include_directories(lvgl PUBLIC ${PNG_INCLUDE_DIRS})
|
||||||
target_link_libraries(main ${PNG_LIBRARY})
|
target_link_libraries(main ${PNG_LIBRARIES})
|
||||||
endif(LV_USE_LIBPNG)
|
endif()
|
||||||
|
|
||||||
|
# Conditionally include and link libjpeg-turbo if LV_USE_LIBJPEG_TURBO is enabled
|
||||||
if(LV_USE_LIBJPEG_TURBO)
|
if(LV_USE_LIBJPEG_TURBO)
|
||||||
# Need to install libjpeg-turbo8-dev
|
|
||||||
# `sudo apt install libjpeg-turbo8-dev`
|
|
||||||
# `brew install libjpeg-turbo`
|
|
||||||
find_package(JPEG REQUIRED)
|
find_package(JPEG REQUIRED)
|
||||||
target_include_directories(lvgl PUBLIC ${JPEG_INCLUDE_DIRS})
|
target_include_directories(lvgl PUBLIC ${JPEG_INCLUDE_DIRS})
|
||||||
target_link_libraries(main ${JPEG_LIBRARIES})
|
target_link_libraries(main ${JPEG_LIBRARIES})
|
||||||
endif(LV_USE_LIBJPEG_TURBO)
|
endif()
|
||||||
|
|
||||||
|
# Conditionally include and link FFmpeg libraries if LV_USE_FFMPEG is enabled
|
||||||
if(LV_USE_FFMPEG)
|
if(LV_USE_FFMPEG)
|
||||||
target_link_libraries(main avformat avcodec avutil swscale z)
|
target_link_libraries(main avformat avcodec avutil swscale z)
|
||||||
endif(LV_USE_FFMPEG)
|
endif()
|
||||||
|
|
||||||
|
# Conditionally include and link FreeType if LV_USE_FREETYPE is enabled
|
||||||
if(LV_USE_FREETYPE)
|
if(LV_USE_FREETYPE)
|
||||||
find_package(Freetype REQUIRED)
|
find_package(Freetype REQUIRED)
|
||||||
target_link_libraries(main ${FREETYPE_LIBRARIES})
|
|
||||||
target_include_directories(lvgl PUBLIC ${FREETYPE_INCLUDE_DIRS})
|
target_include_directories(lvgl PUBLIC ${FREETYPE_INCLUDE_DIRS})
|
||||||
endif(LV_USE_FREETYPE)
|
target_link_libraries(main ${FREETYPE_LIBRARIES})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Apply additional compile options if the build type is Debug
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
target_compile_options(lvgl PRIVATE
|
target_compile_options(lvgl PRIVATE
|
||||||
-pedantic-errors
|
-pedantic-errors
|
||||||
@ -79,7 +139,7 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|||||||
# -Wmissing-prototypes
|
# -Wmissing-prototypes
|
||||||
-Wpointer-arith
|
-Wpointer-arith
|
||||||
-Wmultichar
|
-Wmultichar
|
||||||
-Wno-pedantic # ignored for now, we convert functions to pointers for propertis table.
|
-Wno-pedantic # ignored for now, we convert functions to pointers for properties table.
|
||||||
-Wreturn-type
|
-Wreturn-type
|
||||||
-Wshadow
|
-Wshadow
|
||||||
-Wshift-negative-value
|
-Wshift-negative-value
|
||||||
@ -92,7 +152,7 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|||||||
-Wstrict-aliasing
|
-Wstrict-aliasing
|
||||||
)
|
)
|
||||||
|
|
||||||
# Check if the compiler supports -fsanitize=leak, -fsanitize=address, and -fsanitize=undefined
|
# Check if the compiler supports sanitizers (e.g., leak, address, undefined)
|
||||||
include(CheckCXXCompilerFlag)
|
include(CheckCXXCompilerFlag)
|
||||||
|
|
||||||
check_cxx_compiler_flag("-fsanitize=leak" HAS_SANITIZE_LEAK)
|
check_cxx_compiler_flag("-fsanitize=leak" HAS_SANITIZE_LEAK)
|
||||||
|
|||||||
1
FreeRTOS
Submodule
1
FreeRTOS
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 23cfd114d314b0e2dc5e53a3540b0647fc0a1b5b
|
||||||
36
README.md
36
README.md
@ -1,15 +1,11 @@
|
|||||||
# Simulator project for LVGL embedded GUI Library
|
# VSCode Simulator project for LVGL
|
||||||
|
|
||||||
The [LVGL](https://github.com/lvgl/lvgl) is written mainly for microcontrollers and embedded systems, however you can run the library **on your PC** as well without any embedded hardware. The code written on PC can be simply copied when your are using an embedded system.
|
[LVGL](https://github.com/lvgl/lvgl) is written mainly for microcontrollers and embedded systems, however you can run the library **on your PC** as well without any embedded hardware. The code written on PC can be simply copied when your are using an embedded system.
|
||||||
|
|
||||||
This project is configured for [VSCode](https://code.visualstudio.com) and only tested on Linux, although this may work on OSx or WSL. It requires a working version of GCC, GDB and make in your path.
|
This project is pre-configured for VSCode and should work work on Windows, Linux and MacOs as well. FreeRTOS is also included and can be optionally enabled to better simulate embedded system's behavior.
|
||||||
|
|
||||||
To allow debugging inside VSCode you will also require a GDB [extension](https://marketplace.visualstudio.com/items?itemName=webfreak.debug) or other suitable debugger. All the requirements, build and debug settings have been pre-configured in the [.workspace](simulator.code-workspace) file.
|
|
||||||
|
|
||||||
The project can use **SDL** but it can be easily relaced by any other built-in LVGL dirvers.
|
|
||||||
|
|
||||||
## Get started
|
## Get started
|
||||||
|
|
||||||
### Get the PC project
|
### Get the PC project
|
||||||
|
|
||||||
Clone the PC project and the related sub modules:
|
Clone the PC project and the related sub modules:
|
||||||
@ -38,7 +34,6 @@ sudo pacman -Syu && sudo pacman -S sdl2 libsdl2-devel sdl2_mixer sdl2-devel base
|
|||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
### Visual Studio Code
|
### Visual Studio Code
|
||||||
|
|
||||||
1. Be sure you have installed [SDL and the build tools](#install-sdl-and-build-tools)
|
1. Be sure you have installed [SDL and the build tools](#install-sdl-and-build-tools)
|
||||||
@ -73,6 +68,18 @@ to build using the latest version of clang from homebrew, do the following:
|
|||||||
|
|
||||||
5. build using [step 4 above](#visual-studio-code)
|
5. build using [step 4 above](#visual-studio-code)
|
||||||
|
|
||||||
|
### FreeRTOS configuration
|
||||||
|
To correctly configure the project, the RTOS (Real-Time Operating System) requires a significant amount of heap memory, especially when debugging an SDL (Simple DirectMedia Layer) window application. In this project, the heap memory has been experimentally set to **512 MB**.
|
||||||
|
|
||||||
|
```c
|
||||||
|
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 512 * 1024 * 1024 ) ) // 512 MB Heap
|
||||||
|
```
|
||||||
|
This configuration ensures that the SDL window is displayed in a timely manner. If this value is reduced, it may cause significant delays in the SDL window's appearance. If the allocated heap memory is too small, the window may fail to appear altogether.
|
||||||
|
Therefore, it is crucial to allocate sufficient heap memory to ensure smooth execution and debugging experience.
|
||||||
|
|
||||||
|
### Enable FreeRTOS
|
||||||
|
To enable the rtos part of this project select in lv_conf.h `#define LV_USE_OS LV_OS_NONE` to `#define LV_USE_OS LV_OS_FREERTOS`
|
||||||
|
|
||||||
### CMake
|
### CMake
|
||||||
|
|
||||||
This project uses CMake under the hood which can be used without Visula Studio Code too. Just type these in a Terminal when you are in the project's root folder:
|
This project uses CMake under the hood which can be used without Visula Studio Code too. Just type these in a Terminal when you are in the project's root folder:
|
||||||
@ -108,3 +115,16 @@ git checkout release/6.0
|
|||||||
make
|
make
|
||||||
sudo make install
|
sudo make install
|
||||||
```
|
```
|
||||||
|
### (RT)OS support
|
||||||
|
Works with any OS like pthred, Windows, FreeRTOS, etc. It has build in support for FreeRTOS.
|
||||||
|
|
||||||
|
## Test
|
||||||
|
This project is configured for [VSCode](https://code.visualstudio.com) and is tested on:
|
||||||
|
- Ubuntu Linux
|
||||||
|
- Windows WSL (Ubuntu Linux)
|
||||||
|
|
||||||
|
It requires a working version of GCC, GDB and make in your path.
|
||||||
|
|
||||||
|
To allow debugging inside VSCode you will also require a GDB [extension](https://marketplace.visualstudio.com/items?itemName=webfreak.debug) or other suitable debugger. All the requirements, build and debug settings have been pre-configured in the [.workspace](simulator.code-workspace) file.
|
||||||
|
|
||||||
|
The project can use **SDL** but it can be easily relaced by any other built-in LVGL dirvers.
|
||||||
61
config/FreeRTOSConfig.h
Normal file
61
config/FreeRTOSConfig.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#ifndef FREERTOS_CONFIG_H
|
||||||
|
#define FREERTOS_CONFIG_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
extern uint32_t SystemCoreClock;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Application specific definitions.
|
||||||
|
*
|
||||||
|
* These definitions should be adjusted for your particular hardware and
|
||||||
|
* application requirements.
|
||||||
|
*
|
||||||
|
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
|
||||||
|
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define configUSE_PREEMPTION 1
|
||||||
|
#define configUSE_IDLE_HOOK 0
|
||||||
|
#define configUSE_TICK_HOOK 0
|
||||||
|
#define configCPU_CLOCK_HZ ( SystemCoreClock )
|
||||||
|
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
|
||||||
|
#define configMAX_PRIORITIES ( 5 )
|
||||||
|
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 256 )
|
||||||
|
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 512 * 1024 * 1024 ) ) // 512 MB Heap
|
||||||
|
#define configMAX_TASK_NAME_LEN ( 10 )
|
||||||
|
#define configUSE_TRACE_FACILITY 1
|
||||||
|
#define configUSE_16_BIT_TICKS 0
|
||||||
|
#define configIDLE_SHOULD_YIELD 1
|
||||||
|
#define configUSE_MUTEXES 1
|
||||||
|
#define configQUEUE_REGISTRY_SIZE 8
|
||||||
|
#define configCHECK_FOR_STACK_OVERFLOW 0
|
||||||
|
#define configUSE_RECURSIVE_MUTEXES 1
|
||||||
|
#define configUSE_MALLOC_FAILED_HOOK 1
|
||||||
|
#define configUSE_APPLICATION_TASK_TAG 0
|
||||||
|
#define configUSE_COUNTING_SEMAPHORES 1
|
||||||
|
#define configGENERATE_RUN_TIME_STATS 0
|
||||||
|
#define configUSE_TASK_NOTIFICATIONS 0
|
||||||
|
#define configUSE_STREAM_BUFFERS 0
|
||||||
|
|
||||||
|
/* Co-routine definitions. */
|
||||||
|
#define configUSE_CO_ROUTINES 0
|
||||||
|
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
|
||||||
|
|
||||||
|
/* Software timer definitions. */
|
||||||
|
#define configUSE_TIMERS 1
|
||||||
|
#define configTIMER_TASK_PRIORITY ( 2 )
|
||||||
|
#define configTIMER_QUEUE_LENGTH 10
|
||||||
|
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )
|
||||||
|
|
||||||
|
/* Set the following definitions to 1 to include the API function, or zero
|
||||||
|
to exclude the API function. */
|
||||||
|
|
||||||
|
#define INCLUDE_vTaskPrioritySet 1
|
||||||
|
#define INCLUDE_uxTaskPriorityGet 1
|
||||||
|
#define INCLUDE_vTaskDelete 1
|
||||||
|
#define INCLUDE_vTaskCleanUpResources 0
|
||||||
|
#define INCLUDE_vTaskSuspend 1
|
||||||
|
#define INCLUDE_vTaskDelayUntil 1
|
||||||
|
#define INCLUDE_vTaskDelay 1
|
||||||
|
|
||||||
|
#endif /* FREERTOS_CONFIG_H */
|
||||||
@ -27,7 +27,7 @@
|
|||||||
*====================*/
|
*====================*/
|
||||||
|
|
||||||
/*Color depth: 8 (A8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888)*/
|
/*Color depth: 8 (A8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888)*/
|
||||||
#define LV_COLOR_DEPTH 16
|
#define LV_COLOR_DEPTH 32
|
||||||
|
|
||||||
/*=========================
|
/*=========================
|
||||||
STDLIB WRAPPER SETTINGS
|
STDLIB WRAPPER SETTINGS
|
||||||
|
|||||||
92
main/src/FreeRTOS_Posix_Port.c
Normal file
92
main/src/FreeRTOS_Posix_Port.c
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
/**
|
||||||
|
* @file Event management with pthreads
|
||||||
|
* @brief Implementation of an event mechanism using POSIX threads.
|
||||||
|
* @date 2024-09-03
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Structure representing an event, consisting of a condition variable and a mutex */
|
||||||
|
typedef struct Event
|
||||||
|
{
|
||||||
|
pthread_cond_t cond; /* Condition variable used to signal the event */
|
||||||
|
pthread_mutex_t mutex; /* Mutex to protect access to the condition variable */
|
||||||
|
} Event_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create an event object
|
||||||
|
*
|
||||||
|
* Allocates memory for an Event_t structure and initializes its condition variable and mutex.
|
||||||
|
*
|
||||||
|
* @param None
|
||||||
|
* @return Pointer to the created Event_t object, or NULL if memory allocation fails
|
||||||
|
*/
|
||||||
|
Event_t *event_create(void)
|
||||||
|
{
|
||||||
|
Event_t *event = (Event_t *)malloc(sizeof(Event_t)); /* Allocate memory for the event */
|
||||||
|
if (event) /* Check if allocation was successful */
|
||||||
|
{
|
||||||
|
pthread_cond_init(&event->cond, NULL); /* Initialize the condition variable */
|
||||||
|
pthread_mutex_init(&event->mutex, NULL); /* Initialize the mutex */
|
||||||
|
}
|
||||||
|
return event; /* Return the created event object */
|
||||||
|
}
|
||||||
|
|
||||||
|
// ........................................................................................................
|
||||||
|
/**
|
||||||
|
* @brief Delete an event object
|
||||||
|
*
|
||||||
|
* Destroys the condition variable and mutex associated with the event, then frees the memory.
|
||||||
|
*
|
||||||
|
* @param event Pointer to the Event_t object to be deleted
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void event_delete(Event_t *event)
|
||||||
|
{
|
||||||
|
if (event) /* Check if the event object is valid */
|
||||||
|
{
|
||||||
|
pthread_cond_destroy(&event->cond); /* Destroy the condition variable */
|
||||||
|
pthread_mutex_destroy(&event->mutex); /* Destroy the mutex */
|
||||||
|
free(event); /* Free the memory allocated for the event object */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ........................................................................................................
|
||||||
|
/**
|
||||||
|
* @brief Signal an event
|
||||||
|
*
|
||||||
|
* Signals the condition variable associated with the event, waking up any waiting threads.
|
||||||
|
*
|
||||||
|
* @param event Pointer to the Event_t object to be signaled
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void event_signal(Event_t *event)
|
||||||
|
{
|
||||||
|
if (event) /* Check if the event object is valid */
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&event->mutex); /* Lock the mutex before signaling */
|
||||||
|
pthread_cond_signal(&event->cond); /* Signal the condition variable */
|
||||||
|
pthread_mutex_unlock(&event->mutex); /* Unlock the mutex after signaling */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ........................................................................................................
|
||||||
|
/**
|
||||||
|
* @brief Wait for an event
|
||||||
|
*
|
||||||
|
* Waits for the condition variable associated with the event to be signaled.
|
||||||
|
*
|
||||||
|
* @param event Pointer to the Event_t object to wait for
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void event_wait(Event_t *event)
|
||||||
|
{
|
||||||
|
if (event) /* Check if the event object is valid */
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&event->mutex); /* Lock the mutex before waiting */
|
||||||
|
pthread_cond_wait(&event->cond, &event->mutex); /* Wait for the condition variable to be signaled */
|
||||||
|
pthread_mutex_unlock(&event->mutex); /* Unlock the mutex after waiting */
|
||||||
|
}
|
||||||
|
}
|
||||||
179
main/src/freertos_main.cpp
Normal file
179
main/src/freertos_main.cpp
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
/**
|
||||||
|
* @file Freertos main file
|
||||||
|
* @author MootSeeker
|
||||||
|
* @date 2024-09-02
|
||||||
|
* @brief Main file for FreeRTOS tasks and hooks.
|
||||||
|
* @license MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lvgl/src/osal/lv_os.h"
|
||||||
|
|
||||||
|
#if LV_USE_OS == LV_OS_FREERTOS
|
||||||
|
|
||||||
|
#include "lvgl.h"
|
||||||
|
#include <cstdio> // For printf in C++
|
||||||
|
|
||||||
|
// ........................................................................................................
|
||||||
|
/**
|
||||||
|
* @brief Malloc failed hook
|
||||||
|
*
|
||||||
|
* This function is called when a memory allocation (malloc) fails. It logs the available heap size and enters
|
||||||
|
* an infinite loop to halt the system.
|
||||||
|
*
|
||||||
|
* @param None
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
extern "C" void vApplicationMallocFailedHook(void)
|
||||||
|
{
|
||||||
|
printf("Malloc failed! Available heap: %ld bytes\n", xPortGetFreeHeapSize());
|
||||||
|
for( ;; );
|
||||||
|
}
|
||||||
|
|
||||||
|
// ........................................................................................................
|
||||||
|
/**
|
||||||
|
* @brief Idle hook
|
||||||
|
*
|
||||||
|
* This function is called when the system is idle. It can be used for low-power mode operations or other
|
||||||
|
* maintenance tasks that need to run when the CPU is not busy.
|
||||||
|
*
|
||||||
|
* @param None
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
extern "C" void vApplicationIdleHook(void) {}
|
||||||
|
|
||||||
|
// ........................................................................................................
|
||||||
|
/**
|
||||||
|
* @brief Stack overflow hook
|
||||||
|
*
|
||||||
|
* This function is called when a stack overflow is detected in a task. It logs the task name and enters
|
||||||
|
* an infinite loop to halt the system.
|
||||||
|
*
|
||||||
|
* @param xTask Handle of the task that caused the stack overflow
|
||||||
|
* @param pcTaskName Name of the task that caused the stack overflow
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
extern "C" void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName)
|
||||||
|
{
|
||||||
|
printf("Stack overflow in task %s\n", pcTaskName);
|
||||||
|
for(;;);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ........................................................................................................
|
||||||
|
/**
|
||||||
|
* @brief Tick hook
|
||||||
|
*
|
||||||
|
* This function is called on each tick interrupt. It can be used to execute periodic operations
|
||||||
|
* that need to occur at a fixed time interval.
|
||||||
|
*
|
||||||
|
* @param None
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
extern "C" void vApplicationTickHook(void) {}
|
||||||
|
|
||||||
|
// ........................................................................................................
|
||||||
|
/**
|
||||||
|
* @brief Create Hello World screen
|
||||||
|
*
|
||||||
|
* This function creates a simple LVGL screen with a "Hello, World!" label centered on the screen.
|
||||||
|
*
|
||||||
|
* @param None
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void create_hello_world_screen()
|
||||||
|
{
|
||||||
|
/* Create a new screen object */
|
||||||
|
lv_obj_t *screen = lv_obj_create(NULL);
|
||||||
|
if (screen == NULL){
|
||||||
|
printf("Error: Failed to create screen object\n");
|
||||||
|
/* Return if screen creation fails */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a new label object on the screen */
|
||||||
|
lv_obj_t *label = lv_label_create(screen);
|
||||||
|
if (label == NULL){
|
||||||
|
printf("Error: Failed to create label object\n");
|
||||||
|
/* Return if label creation fails */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the text of the label to "Hello, World!" */
|
||||||
|
lv_label_set_text(label, "Hello, World!");
|
||||||
|
|
||||||
|
/* Align the label to the center of the screen */
|
||||||
|
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
|
||||||
|
|
||||||
|
/* Load the created screen and make it visible */
|
||||||
|
lv_scr_load(screen);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ........................................................................................................
|
||||||
|
/**
|
||||||
|
* @brief LVGL task
|
||||||
|
*
|
||||||
|
* This task initializes LVGL and runs the main loop, periodically calling the LVGL task handler.
|
||||||
|
* It is responsible for managing the LVGL state and rendering updates.
|
||||||
|
*
|
||||||
|
* @param pvParameters Task parameters (not used in this example)
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void lvgl_task(void *pvParameters)
|
||||||
|
{
|
||||||
|
/* Show simple hello world screen */
|
||||||
|
create_hello_world_screen();
|
||||||
|
|
||||||
|
while (true){
|
||||||
|
lv_timer_handler(); /* Handle LVGL tasks */
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(5)); /* Short delay for the RTOS scheduler */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ........................................................................................................
|
||||||
|
/**
|
||||||
|
* @brief Another task
|
||||||
|
*
|
||||||
|
* This task simulates some background work by periodically printing a message.
|
||||||
|
*
|
||||||
|
* @param pvParameters Task parameters (not used in this example)
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
void another_task(void *pvParameters)
|
||||||
|
{
|
||||||
|
/* Create some load in an infinite loop */
|
||||||
|
while (true){
|
||||||
|
printf("Second Task is running :)\n");
|
||||||
|
/* Delay the task for 500 milliseconds */
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(500));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ........................................................................................................
|
||||||
|
/**
|
||||||
|
* @brief FreeRTOS main function
|
||||||
|
*
|
||||||
|
* This function sets up and starts the FreeRTOS tasks, including the LVGL task and another demo task.
|
||||||
|
*
|
||||||
|
* @param None
|
||||||
|
* @return None
|
||||||
|
*/
|
||||||
|
extern "C" void freertos_main()
|
||||||
|
{
|
||||||
|
/* Initialize LVGL (Light and Versatile Graphics Library) and other resources */
|
||||||
|
|
||||||
|
/* Create the LVGL task */
|
||||||
|
if (xTaskCreate(lvgl_task, "LVGL Task", 4096, nullptr, 1, nullptr) != pdPASS) {
|
||||||
|
printf("Error creating LVGL task\n");
|
||||||
|
/* Error handling */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create another task */
|
||||||
|
if (xTaskCreate(another_task, "Another Task", 1024, nullptr, 1, nullptr) != pdPASS) {
|
||||||
|
printf("Error creating another task\n");
|
||||||
|
/* Error handling */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Start the scheduler */
|
||||||
|
vTaskStartScheduler();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -9,11 +9,13 @@
|
|||||||
*********************/
|
*********************/
|
||||||
#define _DEFAULT_SOURCE /* needed for usleep() */
|
#define _DEFAULT_SOURCE /* needed for usleep() */
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include "lvgl/lvgl.h"
|
#include "lvgl/lvgl.h"
|
||||||
#include "lvgl/examples/lv_examples.h"
|
#include "lvgl/examples/lv_examples.h"
|
||||||
#include "lvgl/demos/lv_demos.h"
|
#include "lvgl/demos/lv_demos.h"
|
||||||
|
#include "glob.h"
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
* DEFINES
|
* DEFINES
|
||||||
@ -40,6 +42,8 @@ static lv_display_t * hal_init(int32_t w, int32_t h);
|
|||||||
* GLOBAL FUNCTIONS
|
* GLOBAL FUNCTIONS
|
||||||
**********************/
|
**********************/
|
||||||
|
|
||||||
|
extern void freertos_main(void);
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
* DEFINES
|
* DEFINES
|
||||||
*********************/
|
*********************/
|
||||||
@ -69,7 +73,9 @@ int main(int argc, char **argv)
|
|||||||
lv_init();
|
lv_init();
|
||||||
|
|
||||||
/*Initialize the HAL (display, input devices, tick) for LVGL*/
|
/*Initialize the HAL (display, input devices, tick) for LVGL*/
|
||||||
hal_init(480, 272);
|
hal_init(320, 480);
|
||||||
|
|
||||||
|
#if LV_USE_OS == LV_OS_NONE
|
||||||
|
|
||||||
lv_demo_widgets();
|
lv_demo_widgets();
|
||||||
|
|
||||||
@ -80,6 +86,13 @@ int main(int argc, char **argv)
|
|||||||
usleep(5 * 1000);
|
usleep(5 * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#elif LV_USE_OS == LV_OS_FREERTOS
|
||||||
|
|
||||||
|
/* Run FreeRTOS and create lvgl task */
|
||||||
|
freertos_main();
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -24,6 +24,10 @@
|
|||||||
"files.insertFinalNewline": true,
|
"files.insertFinalNewline": true,
|
||||||
"files.trimFinalNewlines": true,
|
"files.trimFinalNewlines": true,
|
||||||
"cmake.configureOnOpen": true,
|
"cmake.configureOnOpen": true,
|
||||||
|
"files.associations": {
|
||||||
|
"glob.h": "c",
|
||||||
|
"lvgl.h": "c"
|
||||||
|
},
|
||||||
},
|
},
|
||||||
// tasks.json section
|
// tasks.json section
|
||||||
"tasks": {
|
"tasks": {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user