Skip to content
Open
Show file tree
Hide file tree
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 Sep 15, 2025
d3f0a58
Add sdkconfig to .gitignore
sbgaia Sep 18, 2025
9aadfc8
Remove IDF setup from buildAll.sh script
sbgaia Sep 18, 2025
eb59df8
Refactor platform name from ESP32 to ESPIDF, updating related CMake a…
sbgaia Sep 18, 2025
a6772fc
Add platform support to include FreeRTOS and ESP-IDF, updating CMake …
sbgaia Sep 19, 2025
15aefa0
Revert unused parameter handling to (void)super for consistency.
sbgaia Sep 19, 2025
91feffc
Format code.
sbgaia Sep 19, 2025
ef8c296
Remove sdkconfig
sbgaia Sep 25, 2025
9922666
Update CPU clock frequency in FreeRTOSConfig.h for raspberry pico
sbgaia Sep 25, 2025
08e341b
Improve comments for unused parameter suppression in CMakeLists.txt
sbgaia Oct 22, 2025
7821fbc
Refactor timeout handling in CMakeLists.txt files and update build sc…
sbgaia Oct 22, 2025
ee4ca35
Add README.md for Reactor-UC examples
sbgaia Oct 22, 2025
e5e19ee
Add startup reaction in TimerSource for initialization procedures (e.…
sbgaia Oct 23, 2025
039fcb2
Add startup reaction in hello and blink examples
sbgaia Oct 23, 2025
ca7e405
Enable tick hook and add overflow handling for 32-bit architectures i…
sbgaia Oct 23, 2025
d1b2c3c
Enable tick hook in FreeRTOSConfig
sbgaia Oct 23, 2025
7b593ba
Refactor pico_toggle_led invoked in startup reaction
sbgaia Oct 23, 2025
435f07c
Refactor pico_toggle_led invoked in startup reaction
sbgaia Oct 23, 2025
42785c9
Enable USB and UART for blinky example
sbgaia Oct 23, 2025
8f09e15
Add TimerSource startup reaction
sbgaia Oct 23, 2025
a7e1763
Add startup reaction in riot examples
sbgaia Oct 23, 2025
eb84f3e
Add startup reaction in zephyr examples
sbgaia Oct 23, 2025
ea9bb7c
Format code
sbgaia Oct 23, 2025
ba85baa
Fix platform default to FREERTOS in CMakeLists.txt
sbgaia Oct 30, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ cmake-build-release
doc/html
doc/latex
doc/markdown/platform
sdkconfig
9 changes: 9 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,15 @@ elseif (PLATFORM STREQUAL "PICO")

elseif (PLATFORM STREQUAL "PATMOS")
add_library(reactor-uc STATIC ${SOURCES})
elseif( PLATFORM STREQUAL "FREERTOS")
add_library(reactor-uc STATIC ${SOURCES})
# Include FreeRTOSConfig directory
target_include_directories(reactor-uc PUBLIC ${FREERTOS_CONFIG_PATH})

target_link_libraries(reactor-uc PUBLIC FreeRTOS-Kernel FreeRTOS-Kernel-Heap1)
elseif (PLATFORM STREQUAL "ESP_IDF")
add_library(reactor-uc STATIC ${SOURCES})
target_link_libraries(reactor-uc PUBLIC idf::freertos idf::spi_flash idf::esp_timer)
else ()
message(FATAL_ERROR "No valid platform specified")
endif ()
Expand Down
86 changes: 86 additions & 0 deletions examples/README.md
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
30 changes: 25 additions & 5 deletions examples/common/timer_source.h
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);
38 changes: 38 additions & 0 deletions examples/esp-idf/blink/CMakeLists.txt
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)

# 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})


106 changes: 106 additions & 0 deletions examples/esp-idf/blink/main.c
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();
}
18 changes: 18 additions & 0 deletions examples/esp-idf/buildAll.sh
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
33 changes: 33 additions & 0 deletions examples/esp-idf/hello/CMakeLists.txt
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)

# 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})
Loading
Loading