-
Notifications
You must be signed in to change notification settings - Fork 6
Add preliminary support for ESP IDF and FreeRTOS #305
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
sbgaia
wants to merge
24
commits into
main
Choose a base branch
from
esp32
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
24 commits
Select commit
Hold shift + click to select a range
9e35f8b
Add support for the ESP32 platform and related example projects.
sbgaia d3f0a58
Add sdkconfig to .gitignore
sbgaia 9aadfc8
Remove IDF setup from buildAll.sh script
sbgaia eb59df8
Refactor platform name from ESP32 to ESPIDF, updating related CMake a…
sbgaia a6772fc
Add platform support to include FreeRTOS and ESP-IDF, updating CMake …
sbgaia 15aefa0
Revert unused parameter handling to (void)super for consistency.
sbgaia 91feffc
Format code.
sbgaia ef8c296
Remove sdkconfig
sbgaia 9922666
Update CPU clock frequency in FreeRTOSConfig.h for raspberry pico
sbgaia 08e341b
Improve comments for unused parameter suppression in CMakeLists.txt
sbgaia 7821fbc
Refactor timeout handling in CMakeLists.txt files and update build sc…
sbgaia ee4ca35
Add README.md for Reactor-UC examples
sbgaia e5e19ee
Add startup reaction in TimerSource for initialization procedures (e.…
sbgaia 039fcb2
Add startup reaction in hello and blink examples
sbgaia ca7e405
Enable tick hook and add overflow handling for 32-bit architectures i…
sbgaia d1b2c3c
Enable tick hook in FreeRTOSConfig
sbgaia 7b593ba
Refactor pico_toggle_led invoked in startup reaction
sbgaia 435f07c
Refactor pico_toggle_led invoked in startup reaction
sbgaia 42785c9
Enable USB and UART for blinky example
sbgaia 8f09e15
Add TimerSource startup reaction
sbgaia a7e1763
Add startup reaction in riot examples
sbgaia eb84f3e
Add startup reaction in zephyr examples
sbgaia ea9bb7c
Format code
sbgaia ba85baa
Fix platform default to FREERTOS in CMakeLists.txt
sbgaia File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,3 +11,4 @@ cmake-build-release | |
| doc/html | ||
| doc/latex | ||
| doc/markdown/platform | ||
| sdkconfig | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,86 @@ | ||
| # Reactor-UC Examples | ||
|
|
||
| This directory contains example applications for the Reactor-UC runtime across various platforms. These examples demonstrate the core functionality of the framework and can serve as a starting point for exploring Reactor-UC. | ||
|
|
||
| ## Directory Structure | ||
|
|
||
| ``` | ||
| examples/ | ||
| ├── common/ # Shared header files used across examples | ||
| ├── esp-idf/ # Espressif ESP-IDF examples | ||
| ├── freertos/ # FreeRTOS examples | ||
| ├── posix/ # POSIX-compliant systems (Linux, macOS) | ||
| ├── pico/ # Raspberry Pi Pico examples | ||
| ├── zephyr/ # Zephyr RTOS examples | ||
| ├── riot/ # RIOT OS examples | ||
| ├── flexpret/ # FlexPRET platform examples | ||
| └── fed-template/ # Federated application templates | ||
| ``` | ||
|
|
||
| ## Building All Examples | ||
|
|
||
| Each platform directory contains a `buildAll.sh` script to build all examples for that platform: | ||
|
|
||
| ```sh | ||
| cd examples/<platform> | ||
| ./buildAll.sh | ||
| ``` | ||
|
|
||
| To build all examples across all platforms (requires all platform dependencies installed): | ||
|
|
||
| ```sh | ||
| cd examples | ||
| ./runAll.sh | ||
| ``` | ||
|
|
||
| ## WSL (Windows Subsystem for Linux) Considerations | ||
|
|
||
| If you're developing on Windows using WSL, there are important considerations when working with embedded devices. | ||
|
|
||
| ### Serial Port Access | ||
|
|
||
| WSL2 doesn't natively support USB device passthrough. To access serial ports from your embedded devices, you can follow the [Microsoft WSL USB guide](https://learn.microsoft.com/en-us/windows/wsl/connect-usb). | ||
|
|
||
| ### Configuring Runtime Duration for Serial Monitoring | ||
|
|
||
| When using WSL with external serial ports, it's convenient to configure your application to run indefinitely. Otherwise, the program may terminate before you can connect your serial monitor. | ||
|
|
||
| Edit the timeout in the `LF_ENTRY_POINT` macro in the `examples/common/timer_source.h` file: | ||
|
|
||
| ```c | ||
| // Run for 1 second (default) | ||
| LF_ENTRY_POINT(TimerSource, 32, 32, SEC(1), false, false); | ||
|
|
||
| // Run indefinitely (recommended for WSL with external serial monitors) | ||
| LF_ENTRY_POINT(TimerSource, 32, 32, FOREVER, false, false); | ||
|
|
||
| // Run for other durations | ||
| LF_ENTRY_POINT(TimerSource, 32, 32, MINS(5), false, false); // 5 minutes | ||
| LF_ENTRY_POINT(TimerSource, 32, 32, HOUR(1), false, false); // 1 hour | ||
| ``` | ||
|
|
||
| This ensures your device continues outputting serial data, giving you enough time to connect your serial monitor on the Windows side. | ||
|
|
||
| ## Troubleshooting | ||
|
|
||
| ### Build Failures | ||
|
|
||
| If you encounter build issues: | ||
|
|
||
| 1. Clean the build directory: | ||
| ```sh | ||
| rm -rf build && mkdir build | ||
| ``` | ||
|
|
||
| 2. Verify all prerequisites are installed for your platform | ||
|
|
||
| 3. Check that platform-specific environment variables are set correctly | ||
|
|
||
| ## Contributing | ||
|
|
||
| When adding new examples: | ||
|
|
||
| 1. Place shared code in `common/` | ||
| 2. Follow the existing directory structure for platform-specific examples | ||
| 3. Add a `buildAll.sh` script for batch building | ||
| 4. Test on the target platform before submitting a PR |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,25 +1,45 @@ | ||
| #include "reactor-uc/reactor-uc.h" | ||
| #include "reactor-uc/schedulers/dynamic/scheduler.h" | ||
|
|
||
| LF_DEFINE_TIMER_STRUCT(TimerSource, t, 1, 0); | ||
| LF_DEFINE_TIMER_CTOR(TimerSource, t, 1, 0); | ||
| LF_DEFINE_REACTION_STRUCT(TimerSource, s, 0); | ||
| LF_DEFINE_REACTION_STRUCT(TimerSource, r, 0); | ||
| LF_DEFINE_REACTION_CTOR(TimerSource, r, 0, NULL, NULL); | ||
|
|
||
| LF_DEFINE_TIMER_STRUCT(TimerSource, t, 1, 0); | ||
| LF_DEFINE_STARTUP_STRUCT(TimerSource, 1, 0); | ||
|
|
||
| typedef struct { | ||
| Reactor super; | ||
|
|
||
| LF_TIMER_INSTANCE(TimerSource, t); | ||
| LF_REACTION_INSTANCE(TimerSource, r); | ||
| LF_REACTOR_BOOKKEEPING_INSTANCES(1,1,0); | ||
|
|
||
| LF_REACTION_INSTANCE(TimerSource, s); | ||
| LF_STARTUP_INSTANCE(TimerSource); | ||
|
|
||
| LF_REACTOR_BOOKKEEPING_INSTANCES(2,2,0); | ||
| } TimerSource; | ||
|
|
||
| LF_DEFINE_REACTION_CTOR(TimerSource, s, 0, NULL, NULL); | ||
| LF_DEFINE_REACTION_CTOR(TimerSource, r, 1, NULL, NULL); | ||
|
|
||
| LF_DEFINE_STARTUP_CTOR(TimerSource); | ||
| LF_DEFINE_TIMER_CTOR(TimerSource, t, 1, 0); | ||
|
|
||
| LF_REACTOR_CTOR_SIGNATURE(TimerSource) { | ||
| LF_REACTOR_CTOR_PREAMBLE(); | ||
| LF_REACTOR_CTOR(TimerSource); | ||
| LF_INITIALIZE_REACTION(TimerSource, r, NEVER); | ||
|
|
||
| LF_INITIALIZE_TIMER(TimerSource, t, MSEC(0), MSEC(500)); | ||
| LF_INITIALIZE_STARTUP(TimerSource); | ||
|
|
||
| LF_INITIALIZE_REACTION(TimerSource, s, NEVER); | ||
| LF_STARTUP_REGISTER_EFFECT(self->s); | ||
|
|
||
| LF_INITIALIZE_REACTION(TimerSource, r, NEVER); | ||
| LF_TIMER_REGISTER_EFFECT(self->t, self->r); | ||
|
|
||
| } | ||
|
|
||
| // Replace SEC(1) with FOREVER to run indefinitely. | ||
| // You can also use MINS(...) or HOURS(...) to specify other durations. | ||
| LF_ENTRY_POINT(TimerSource,32,32, SEC(1), false, false); | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| cmake_minimum_required(VERSION 3.20.0) | ||
| set(PLATFORM "ESP_IDF" CACHE STRING "Platform to target") | ||
| set(BUILD_EXAMPLES OFF CAHCHE BOOL) | ||
|
|
||
| set(IDF_COMPONENTS "freertos" "esptool_py" "driver" "led_strip") | ||
|
|
||
| if(DEFINED ENV{IDF_PATH}) | ||
| else() | ||
| message(FATAL_ERROR "IDF_PATH environment variable not set") | ||
| endif() | ||
|
|
||
| # Include for ESP-IDF build system functions | ||
| include($ENV{IDF_PATH}/tools/cmake/idf.cmake) | ||
| # Set led_strip component path | ||
| set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/../idf-extra-components/led_strip) | ||
| idf_build_component($ENV{IDF_PATH}/../idf-extra-components/led_strip) | ||
|
|
||
| project(blink) | ||
|
|
||
| # Create idf::{target} and idf::freertos static libraries | ||
| idf_build_process(${IDF_TARGET} | ||
| COMPONENTS ${IDF_COMPONENTS} | ||
| SDKCONFIG ${CMAKE_CURRENT_LIST_DIR}/sdkconfig | ||
| BUILD_DIR ${CMAKE_BINARY_DIR}) | ||
|
|
||
| add_subdirectory(../../../ reactor-uc) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe use the $ENV{REACTOR_UC_PATH} here? |
||
|
|
||
| # Suppress unused parameter warnings for reactor-uc and main executable | ||
| # This is needed because ESP-IDF headers (e.g., spinlock.h) have unused parameters | ||
| target_compile_options(reactor-uc PRIVATE -Wno-unused-parameter) | ||
|
|
||
| set(elf_file ${CMAKE_PROJECT_NAME}.elf) | ||
| add_executable(${elf_file} main.c) | ||
| target_link_libraries(${elf_file} PRIVATE reactor-uc idf::led_strip idf::driver) | ||
|
|
||
| idf_build_executable(${elf_file}) | ||
|
|
||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,106 @@ | ||
| #include <stdio.h> | ||
| #include <inttypes.h> | ||
| #include "sdkconfig.h" | ||
| #include "freertos/FreeRTOS.h" | ||
| #include "freertos/task.h" | ||
| #include "esp_chip_info.h" | ||
| #include "esp_flash.h" | ||
| #include "esp_system.h" | ||
| #include "reactor-uc/reactor-uc.h" | ||
| #include "sys/time.h" | ||
| #include "esp_timer.h" | ||
| #include "../../common/timer_source.h" | ||
| #include "led_strip.h" | ||
| #include "driver/gpio.h" | ||
|
|
||
| #define BLINK_GPIO 8 | ||
| #define CONFIG_BLINK_LED_STRIP 1 | ||
| #define CONFIG_BLINK_LED_STRIP_BACKEND_SPI 1 | ||
| static uint8_t s_led_state = 0; | ||
|
|
||
| #ifdef CONFIG_BLINK_LED_STRIP | ||
|
|
||
| static led_strip_handle_t led_strip; | ||
|
|
||
| static void blink_led(void) | ||
| { | ||
| /* If the addressable LED is enabled */ | ||
| if (s_led_state) { | ||
| /* Set the LED pixel using RGB from 0 (0%) to 255 (100%) for each color */ | ||
| led_strip_set_pixel(led_strip, 0, 16, 16, 16); | ||
| /* Refresh the strip to send data */ | ||
| led_strip_refresh(led_strip); | ||
| } else { | ||
| /* Set all LED off to clear all pixels */ | ||
| led_strip_clear(led_strip); | ||
| } | ||
| } | ||
|
|
||
| static void configure_led(void) | ||
| { | ||
| printf("Example configured to blink addressable LED!\n"); | ||
| /* LED strip initialization with the GPIO and pixels number*/ | ||
| led_strip_config_t strip_config = { | ||
| .strip_gpio_num = BLINK_GPIO, | ||
| .max_leds = 1, // at least one LED on board | ||
| }; | ||
| #if CONFIG_BLINK_LED_STRIP_BACKEND_RMT | ||
| led_strip_rmt_config_t rmt_config = { | ||
| .resolution_hz = 10 * 1000 * 1000, // 10MHz | ||
| .flags.with_dma = false, | ||
| }; | ||
| ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip)); | ||
| #elif CONFIG_BLINK_LED_STRIP_BACKEND_SPI | ||
| led_strip_spi_config_t spi_config = { | ||
| .spi_bus = SPI2_HOST, | ||
| .flags.with_dma = true, | ||
| }; | ||
| ESP_ERROR_CHECK(led_strip_new_spi_device(&strip_config, &spi_config, &led_strip)); | ||
| #else | ||
| #error "unsupported LED strip backend" | ||
| #endif | ||
| /* Set all LED off to clear all pixels */ | ||
| led_strip_clear(led_strip); | ||
| } | ||
|
|
||
| #elif CONFIG_BLINK_LED_GPIO | ||
|
|
||
| static void blink_led(void) | ||
| { | ||
| /* Set the GPIO level according to the state (LOW or HIGH)*/ | ||
| gpio_set_level(BLINK_GPIO, s_led_state); | ||
| } | ||
|
|
||
| static void configure_led(void) | ||
| { | ||
| ESP_LOGI(TAG, "Example configured to blink GPIO LED!"); | ||
| gpio_reset_pin(BLINK_GPIO); | ||
| /* Set the GPIO as a push/pull output */ | ||
| gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT); | ||
| } | ||
|
|
||
| #else | ||
| #error "unsupported LED type" | ||
| #endif | ||
|
|
||
| LF_DEFINE_REACTION_BODY(TimerSource, r) { | ||
| LF_SCOPE_SELF(TimerSource); | ||
| LF_SCOPE_ENV(); | ||
| printf("Turning the LED %s! @ lt=%lld, pt=%lld\n", s_led_state == true ? "ON" : "OFF", env->get_elapsed_logical_time(env), env->get_physical_time(env)); | ||
| blink_led(); | ||
| /* Toggle the LED state */ | ||
| s_led_state = !s_led_state; | ||
| } | ||
|
|
||
| LF_DEFINE_REACTION_BODY(TimerSource, s) { | ||
| LF_SCOPE_SELF(TimerSource); | ||
| LF_SCOPE_ENV(); | ||
| LF_SCOPE_STARTUP(TimerSource); | ||
| // Configure the LED on startup | ||
| configure_led(); | ||
| } | ||
|
|
||
| void app_main(void) | ||
| { | ||
| lf_start(); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| #!/bin/bash | ||
| set -e | ||
|
|
||
| # Set the target platform | ||
| IDF_TARGET="esp32c6" | ||
| # List of folders | ||
| FOLDERS=("hello" "blink") | ||
|
|
||
| # Iterate over each folder and execute the command | ||
| for dir in "${FOLDERS[@]}"; do | ||
| echo "Entering $dir" | ||
| pushd $dir | ||
|
|
||
| rm -rf build && mkdir build && cd build | ||
| cmake .. -DCMAKE_TOOLCHAIN_FILE=$IDF_PATH/tools/cmake/toolchain-${IDF_TARGET}.cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DPLATFORM=ESP_IDF -DIDF_TARGET=${IDF_TARGET} -GNinja | ||
| cmake --build . -j | ||
| popd | ||
| done |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| cmake_minimum_required(VERSION 3.20.0) | ||
| set(PLATFORM "ESP_IDF" CACHE STRING "Platform to target") | ||
| set(BUILD_EXAMPLES OFF CAHCHE BOOL) | ||
|
|
||
| set(IDF_COMPONENTS "freertos" "esptool_py") | ||
|
|
||
| if(DEFINED ENV{IDF_PATH}) | ||
| else() | ||
| message(FATAL_ERROR "IDF_PATH environment variable not set") | ||
| endif() | ||
|
|
||
| # Include for ESP-IDF build system functions | ||
| include($ENV{IDF_PATH}/tools/cmake/idf.cmake) | ||
|
|
||
| project(hello) | ||
|
|
||
| # Create idf::{target} and idf::freertos static libraries | ||
| idf_build_process(${IDF_TARGET} | ||
| COMPONENTS ${IDF_COMPONENTS} | ||
| SDKCONFIG ${CMAKE_CURRENT_LIST_DIR}/sdkconfig | ||
| BUILD_DIR ${CMAKE_BINARY_DIR}) | ||
|
|
||
| add_subdirectory(../../../ reactor-uc) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. REACTOR_UC_PATH |
||
|
|
||
| # Suppress unused parameter warnings for reactor-uc and main executable | ||
| # This is needed because ESP-IDF headers (e.g., spinlock.h) have unused parameters | ||
| target_compile_options(reactor-uc PRIVATE -Wno-unused-parameter) | ||
|
|
||
| set(elf_file ${CMAKE_PROJECT_NAME}.elf) | ||
| add_executable(${elf_file} main.c) | ||
| target_link_libraries(${elf_file} PRIVATE reactor-uc) | ||
|
|
||
| idf_build_executable(${elf_file}) | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why changing this file?