From 857935c31442fa0d37a790edd09241e3d076d790 Mon Sep 17 00:00:00 2001 From: Rodrigo Garcia <rodrigo.garcia@espressif.com> Date: Fri, 29 Nov 2024 19:10:56 -0300 Subject: [PATCH 1/7] feat(support): toll and ci changes --- .github/ISSUE_TEMPLATE/Issue-report.yml | 2 +- .github/scripts/install-platformio-esp32.sh | 170 ------------- .github/scripts/on-push.sh | 81 +++---- .github/scripts/on-release.sh | 1 - .github/scripts/set_push_chunks.sh | 1 - .github/workflows/push.yml | 30 --- platform.txt | 1 - tools/platformio-build.py | 251 -------------------- 8 files changed, 30 insertions(+), 507 deletions(-) delete mode 100755 .github/scripts/install-platformio-esp32.sh delete mode 100644 tools/platformio-build.py diff --git a/.github/ISSUE_TEMPLATE/Issue-report.yml b/.github/ISSUE_TEMPLATE/Issue-report.yml index d5b756085c7..acbd9a3c29a 100644 --- a/.github/ISSUE_TEMPLATE/Issue-report.yml +++ b/.github/ISSUE_TEMPLATE/Issue-report.yml @@ -75,7 +75,7 @@ body: attributes: label: IDE Name description: What IDE are you using? - placeholder: eg. Arduino IDE, PlatformIO, Sloeber... + placeholder: eg. Arduino IDE, VSCode, Sloeber... validations: required: true - type: input diff --git a/.github/scripts/install-platformio-esp32.sh b/.github/scripts/install-platformio-esp32.sh deleted file mode 100755 index 80c668bdc0e..00000000000 --- a/.github/scripts/install-platformio-esp32.sh +++ /dev/null @@ -1,170 +0,0 @@ -#!/bin/bash - -export PLATFORMIO_ESP32_PATH="$HOME/.platformio/packages/framework-arduinoespressif32" -PLATFORMIO_ESP32_URL="https://github.com/platformio/platform-espressif32.git" - -TOOLCHAIN_VERSION="12.2.0+20230208" -ESPTOOLPY_VERSION="~1.40501.0" -ESPRESSIF_ORGANIZATION_NAME="espressif" -SDKCONFIG_DIR="$PLATFORMIO_ESP32_PATH/tools/esp32-arduino-libs" -SCRIPTS_DIR="./.github/scripts" -COUNT_SKETCHES="${SCRIPTS_DIR}/sketch_utils.sh count" -CHECK_REQUIREMENTS="${SCRIPTS_DIR}/sketch_utils.sh check_requirements" - -echo "Installing Python Wheel ..." -pip install wheel > /dev/null 2>&1 - -echo "Installing PlatformIO ..." -pip install -U https://github.com/platformio/platformio/archive/master.zip > /dev/null 2>&1 - -echo "Installing Platform ESP32 ..." -python -m platformio platform install $PLATFORMIO_ESP32_URL > /dev/null 2>&1 - -echo "Replacing the package versions ..." -replace_script="import json; import os;" -replace_script+="fp=open(os.path.expanduser('~/.platformio/platforms/espressif32/platform.json'), 'r+');" -replace_script+="data=json.load(fp);" -# Use framework sources from the repository -replace_script+="data['packages']['framework-arduinoespressif32']['version'] = '*';" -replace_script+="del data['packages']['framework-arduinoespressif32']['owner'];" -# Use toolchain packages from the "espressif" organization -replace_script+="data['packages']['toolchain-xtensa-esp32']['owner']='$ESPRESSIF_ORGANIZATION_NAME';" -replace_script+="data['packages']['toolchain-xtensa-esp32s2']['owner']='$ESPRESSIF_ORGANIZATION_NAME';" -replace_script+="data['packages']['toolchain-riscv32-esp']['owner']='$ESPRESSIF_ORGANIZATION_NAME';" -# Update versions to use the upstream -replace_script+="data['packages']['toolchain-xtensa-esp32']['version']='$TOOLCHAIN_VERSION';" -replace_script+="data['packages']['toolchain-xtensa-esp32s2']['version']='$TOOLCHAIN_VERSION';" -replace_script+="data['packages']['toolchain-xtensa-esp32s3']['version']='$TOOLCHAIN_VERSION';" -replace_script+="data['packages']['toolchain-riscv32-esp']['version']='$TOOLCHAIN_VERSION';" -# Add new "framework-arduinoespressif32-libs" package -# Read "package_esp32_index.template.json" to extract a url to a zip package for "esp32-arduino-libs" -replace_script+="fpackage=open(os.path.join('package', 'package_esp32_index.template.json'), 'r+');" -replace_script+="package_data=json.load(fpackage);" -replace_script+="fpackage.close();" -replace_script+="libs_package_archive_url=next(next(system['url'] for system in tool['systems'] if system['host'] == 'x86_64-pc-linux-gnu') for tool in package_data['packages'][0]['tools'] if tool['name'] == 'esp32-arduino-libs');" -replace_script+="data['packages'].update({'framework-arduinoespressif32-libs':{'type':'framework','optional':False,'version':libs_package_archive_url}});" -replace_script+="data['packages']['toolchain-xtensa-esp32'].update({'optional':False});" -# esptool.py may require an upstream version (for now platformio is the owner) -replace_script+="data['packages']['tool-esptoolpy']['version']='$ESPTOOLPY_VERSION';" -# Save results -replace_script+="fp.seek(0);fp.truncate();json.dump(data, fp, indent=2);fp.close()" -python -c "$replace_script" - -if [ "$GITHUB_REPOSITORY" == "espressif/arduino-esp32" ]; then - echo "Linking Core..." - ln -s $GITHUB_WORKSPACE "$PLATFORMIO_ESP32_PATH" -else - echo "Cloning Core Repository ..." - git clone --recursive https://github.com/espressif/arduino-esp32.git "$PLATFORMIO_ESP32_PATH" > /dev/null 2>&1 -fi - -echo "PlatformIO for ESP32 has been installed" -echo "" - -function build_pio_sketch(){ # build_pio_sketch <board> <options> <path-to-ino> - if [ "$#" -lt 3 ]; then - echo "ERROR: Illegal number of parameters" - echo "USAGE: build_pio_sketch <board> <options> <path-to-ino>" - return 1 - fi - - local board="$1" - local options="$2" - local sketch="$3" - local sketch_dir=$(dirname "$sketch") - echo "" - echo "Compiling '"$(basename "$sketch")"' ..." - python -m platformio ci --board "$board" "$sketch_dir" --project-option="$options" -} - -function build_pio_sketches(){ # build_pio_sketches <board> <options> <examples-path> <chunk> <total-chunks> - if [ "$#" -lt 3 ]; then - echo "ERROR: Illegal number of parameters" - echo "USAGE: build_pio_sketches <board> <options> <examples-path> [<chunk> <total-chunks>]" - return 1 - fi - - local board=$1 - local options="$2" - local examples=$3 - local chunk_idex=$4 - local chunks_num=$5 - - if [ "$#" -lt 5 ]; then - chunk_idex="0" - chunks_num="1" - fi - - if [ "$chunks_num" -le 0 ]; then - echo "ERROR: Chunks count must be positive number" - return 1 - fi - if [ "$chunk_idex" -ge "$chunks_num" ]; then - echo "ERROR: Chunk index must be less than chunks count" - return 1 - fi - - set +e - ${COUNT_SKETCHES} "$examples" "esp32" - local sketchcount=$? - set -e - local sketches=$(cat sketches.txt) - rm -rf sketches.txt - - local chunk_size=$(( $sketchcount / $chunks_num )) - local all_chunks=$(( $chunks_num * $chunk_size )) - if [ "$all_chunks" -lt "$sketchcount" ]; then - chunk_size=$(( $chunk_size + 1 )) - fi - - local start_index=$(( $chunk_idex * $chunk_size )) - if [ "$sketchcount" -le "$start_index" ]; then - echo "Skipping job" - return 0 - fi - - local end_index=$(( $(( $chunk_idex + 1 )) * $chunk_size )) - if [ "$end_index" -gt "$sketchcount" ]; then - end_index=$sketchcount - fi - - local start_num=$(( $start_index + 1 )) - echo "Found $sketchcount Sketches"; - echo "Chunk Count : $chunks_num" - echo "Chunk Size : $chunk_size" - echo "Start Sketch: $start_num" - echo "End Sketch : $end_index" - - local sketchnum=0 - for sketch in $sketches; do - local sketchdir=$(dirname $sketch) - local sketchdirname=$(basename $sketchdir) - local sketchname=$(basename $sketch) - if [[ "$sketchdirname.ino" != "$sketchname" ]]; then - continue - elif [ -f $sketchdir/ci.json ]; then - # If the target is listed as false, skip the sketch. Otherwise, include it. - is_target=$(jq -r '.targets[esp32]' $sketchdir/ci.json) - if [[ "$is_target" == "false" ]]; then - continue - fi - - local has_requirements=$(${CHECK_REQUIREMENTS} $sketchdir "$SDKCONFIG_DIR/esp32/sdkconfig") - if [ "$has_requirements" == "0" ]; then - continue - fi - fi - - sketchnum=$(($sketchnum + 1)) - if [ "$sketchnum" -le "$start_index" ] \ - || [ "$sketchnum" -gt "$end_index" ]; then - continue - fi - build_pio_sketch "$board" "$options" "$sketch" - local result=$? - if [ $result -ne 0 ]; then - return $result - fi - done - return 0 -} diff --git a/.github/scripts/on-push.sh b/.github/scripts/on-push.sh index 08ff505f1c0..7f436c7b0ee 100755 --- a/.github/scripts/on-push.sh +++ b/.github/scripts/on-push.sh @@ -54,14 +54,11 @@ CHUNK_INDEX=$1 CHUNKS_CNT=$2 BUILD_LOG=$3 SKETCHES_FILE=$4 -BUILD_PIO=0 if [ "$#" -lt 2 ] || [ "$CHUNKS_CNT" -le 0 ]; then CHUNK_INDEX=0 CHUNKS_CNT=1 elif [ "$CHUNK_INDEX" -gt "$CHUNKS_CNT" ] && [ "$CHUNKS_CNT" -ge 2 ]; then CHUNK_INDEX=$CHUNKS_CNT -elif [ "$CHUNK_INDEX" -eq "$CHUNKS_CNT" ]; then - BUILD_PIO=1 fi if [ -z "$BUILD_LOG" ] || [ "$BUILD_LOG" -le 0 ]; then @@ -72,54 +69,34 @@ fi #git -C "$GITHUB_WORKSPACE" submodule update --init --recursive > /dev/null 2>&1 SCRIPTS_DIR="./.github/scripts" -if [ "$BUILD_PIO" -eq 0 ]; then - source ${SCRIPTS_DIR}/install-arduino-cli.sh - source ${SCRIPTS_DIR}/install-arduino-core-esp32.sh - - SKETCHES_ESP32="\ - $ARDUINO_ESP32_PATH/libraries/NetworkClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino\ - $ARDUINO_ESP32_PATH/libraries/BLE/examples/Server/Server.ino\ - $ARDUINO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino\ - $ARDUINO_ESP32_PATH/libraries/Insights/examples/MinimalDiagnostics/MinimalDiagnostics.ino\ - " - #create sizes_file - sizes_file="$GITHUB_WORKSPACE/cli_compile_$CHUNK_INDEX.json" - - if [ "$BUILD_LOG" -eq 1 ]; then - #create sizes_file and echo start of JSON array with "boards" key - echo "{\"boards\": [" > $sizes_file - fi +source ${SCRIPTS_DIR}/install-arduino-cli.sh +source ${SCRIPTS_DIR}/install-arduino-core-esp32.sh + +SKETCHES_ESP32="\ + $ARDUINO_ESP32_PATH/libraries/NetworkClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino\ + $ARDUINO_ESP32_PATH/libraries/BLE/examples/Server/Server.ino\ + $ARDUINO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino\ + $ARDUINO_ESP32_PATH/libraries/Insights/examples/MinimalDiagnostics/MinimalDiagnostics.ino\ +" +#create sizes_file +sizes_file="$GITHUB_WORKSPACE/cli_compile_$CHUNK_INDEX.json" + +if [ "$BUILD_LOG" -eq 1 ]; then + #create sizes_file and echo start of JSON array with "boards" key + echo "{\"boards\": [" > $sizes_file +fi - #build sketches for different targets - build "esp32s3" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$SKETCHES_FILE" "$SKETCHES_ESP32" - build "esp32s2" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$SKETCHES_FILE" "$SKETCHES_ESP32" - build "esp32c3" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$SKETCHES_FILE" "$SKETCHES_ESP32" - build "esp32c6" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$SKETCHES_FILE" "$SKETCHES_ESP32" - build "esp32h2" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$SKETCHES_FILE" "$SKETCHES_ESP32" - build "esp32" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$SKETCHES_FILE" "$SKETCHES_ESP32" - - if [ "$BUILD_LOG" -eq 1 ]; then - #remove last comma from the last JSON object - sed -i '$ s/,$//' "$sizes_file" - #echo end of JSON array - echo "]}" >> $sizes_file - fi -else - source ${SCRIPTS_DIR}/install-platformio-esp32.sh - # PlatformIO ESP32 Test - BOARD="esp32dev" - OPTIONS="board_build.partitions = huge_app.csv" - build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino" && \ - build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/NetworkClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino" && \ - build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino" && \ - build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/BLE/examples/Server/Server.ino" && \ - build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino" - - # Basic sanity testing for other series - for board in "esp32-c3-devkitm-1" "esp32-s2-saola-1" "esp32-s3-devkitc-1" - do - python -m platformio ci --board "$board" "$PLATFORMIO_ESP32_PATH/libraries/WiFi/examples/WiFiClient" --project-option="board_build.partitions = huge_app.csv" - done - - #build_pio_sketches "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries" +#build sketches for different targets +build "esp32s3" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$SKETCHES_FILE" "$SKETCHES_ESP32" +build "esp32s2" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$SKETCHES_FILE" "$SKETCHES_ESP32" +build "esp32c3" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$SKETCHES_FILE" "$SKETCHES_ESP32" +build "esp32c6" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$SKETCHES_FILE" "$SKETCHES_ESP32" +build "esp32h2" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$SKETCHES_FILE" "$SKETCHES_ESP32" +build "esp32" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$SKETCHES_FILE" "$SKETCHES_ESP32" + +if [ "$BUILD_LOG" -eq 1 ]; then + #remove last comma from the last JSON object + sed -i '$ s/,$//' "$sizes_file" + #echo end of JSON array + echo "]}" >> $sizes_file fi diff --git a/.github/scripts/on-release.sh b/.github/scripts/on-release.sh index e0dd7b752c5..2308717e9d8 100755 --- a/.github/scripts/on-release.sh +++ b/.github/scripts/on-release.sh @@ -207,7 +207,6 @@ cp -f "$GITHUB_WORKSPACE/tools/gen_insights_package.py" "$PKG_DIR/tools/" cp -f "$GITHUB_WORKSPACE/tools/gen_insights_package.exe" "$PKG_DIR/tools/" cp -Rf "$GITHUB_WORKSPACE/tools/partitions" "$PKG_DIR/tools/" cp -Rf "$GITHUB_WORKSPACE/tools/ide-debug" "$PKG_DIR/tools/" -cp -f "$GITHUB_WORKSPACE/tools/platformio-build.py" "$PKG_DIR/tools/" # Remove unnecessary files in the package folder echo "Cleaning up folders ..." diff --git a/.github/scripts/set_push_chunks.sh b/.github/scripts/set_push_chunks.sh index 11a93a7159d..3e3dd89f3ae 100644 --- a/.github/scripts/set_push_chunks.sh +++ b/.github/scripts/set_push_chunks.sh @@ -78,6 +78,5 @@ echo "build_all=$build_all" >> $GITHUB_OUTPUT echo "build_libraries=$BUILD_LIBRARIES" >> $GITHUB_OUTPUT echo "build_static_sketches=$BUILD_STATIC_SKETCHES" >> $GITHUB_OUTPUT echo "build_idf=$BUILD_IDF" >> $GITHUB_OUTPUT -echo "build_platformio=$BUILD_PLATFORMIO" >> $GITHUB_OUTPUT echo "chunk_count=$chunks_count" >> $GITHUB_OUTPUT echo "chunks=$chunks" >> $GITHUB_OUTPUT diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 82159e1b8a4..899a0fe7b88 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -61,7 +61,6 @@ jobs: build_libraries: ${{ steps.set-chunks.outputs.build_libraries }} build_static_sketches: ${{ steps.set-chunks.outputs.build_static_sketches }} build_idf: ${{ steps.set-chunks.outputs.build_idf }} - build_platformio: ${{ steps.set-chunks.outputs.build_platformio }} chunk_count: ${{ steps.set-chunks.outputs.chunk_count }} chunks: ${{ steps.set-chunks.outputs.chunks }} steps: @@ -77,11 +76,9 @@ jobs: files_yaml: | core: - '.github/**' - - '!.github/scripts/install-platformio-esp32.sh' - 'cores/**' - 'package/**' - 'tools/**' - - '!tools/platformio-build.py' - 'platform.txt' - 'programmers.txt' - "variants/esp32/**/*" @@ -110,10 +107,6 @@ jobs: - 'Kconfig.projbuild' - 'CMakeLists.txt' - "variants/esp32c2/**/*" - platformio: - - 'package.json' - - '.github/scripts/install-platformio-esp32.sh' - - 'tools/platformio-build.py' - name: Set chunks id: set-chunks @@ -121,7 +114,6 @@ jobs: LIB_FILES: ${{ steps.changed-files.outputs.libraries_all_changed_files }} IS_PR: ${{ github.event_name == 'pull_request' }} MAX_CHUNKS: ${{ env.MAX_CHUNKS }} - BUILD_PLATFORMIO: ${{ steps.changed-files.outputs.platformio_any_changed == 'true' }} BUILD_IDF: ${{ steps.changed-files.outputs.idf_any_changed == 'true' }} BUILD_LIBRARIES: ${{ steps.changed-files.outputs.libraries_any_changed == 'true' }} BUILD_STATIC_SKETCHES: ${{ steps.changed-files.outputs.static_sketeches_any_changed == 'true' }} @@ -212,28 +204,6 @@ jobs: - name: Build Sketches run: bash ./.github/scripts/on-push.sh - # PlatformIO on Windows, Ubuntu and Mac - build-platformio: - name: PlatformIO on ${{ matrix.os }} - needs: gen-chunks - if: | - needs.gen-chunks.outputs.build_all == 'true' || - needs.gen-chunks.outputs.build_static_sketches == 'true' || - needs.gen-chunks.outputs.build_platformio == 'true' - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest, windows-latest, macOS-latest] - - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - name: Build Sketches - run: bash ./.github/scripts/on-push.sh 1 1 #equal and non-zero to trigger PIO - build-esp-idf-component: name: Build with ESP-IDF ${{ matrix.idf_ver }} for ${{ matrix.idf_target }} needs: gen-chunks diff --git a/platform.txt b/platform.txt index d1c3fb3a3dd..ec1245c9b92 100644 --- a/platform.txt +++ b/platform.txt @@ -47,7 +47,6 @@ compiler.warning_flags.more=-Wall compiler.warning_flags.all=-Wall -Wextra # Additional flags specific to Arduino (not based on IDF flags). -# Update tools/platformio-build.py when changing these flags. compiler.common_werror_flags=-Werror=return-type # Compile Flags diff --git a/tools/platformio-build.py b/tools/platformio-build.py deleted file mode 100644 index 1ece3afddff..00000000000 --- a/tools/platformio-build.py +++ /dev/null @@ -1,251 +0,0 @@ -# Copyright 2014-present PlatformIO <contact@platformio.org> -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -Arduino - -Arduino Wiring-based Framework allows writing cross-platform software to -control devices attached to a wide range of Arduino boards to create all -kinds of creative coding, interactive objects, spaces or physical experiences. - -http://arduino.cc/en/Reference/HomePage -""" - -# Extends: https://github.com/platformio/platform-espressif32/blob/develop/builder/main.py - -from os.path import abspath, basename, isdir, isfile, join -from copy import deepcopy -from SCons.Script import DefaultEnvironment, SConscript - -env = DefaultEnvironment() -platform = env.PioPlatform() -board_config = env.BoardConfig() -build_mcu = board_config.get("build.mcu", "").lower() -partitions_name = board_config.get("build.partitions", board_config.get("build.arduino.partitions", "")) - -FRAMEWORK_DIR = platform.get_package_dir("framework-arduinoespressif32") -FRAMEWORK_LIBS_DIR = platform.get_package_dir("framework-arduinoespressif32-libs") -assert isdir(FRAMEWORK_DIR) - - -# -# Helpers -# - - -def get_partition_table_csv(variants_dir): - fwpartitions_dir = join(FRAMEWORK_DIR, "tools", "partitions") - variant_partitions_dir = join(variants_dir, board_config.get("build.variant", "")) - - if partitions_name: - # A custom partitions file is selected - if isfile(env.subst(join(variant_partitions_dir, partitions_name))): - return join(variant_partitions_dir, partitions_name) - - return abspath( - join(fwpartitions_dir, partitions_name) - if isfile(env.subst(join(fwpartitions_dir, partitions_name))) - else partitions_name - ) - - variant_partitions = join(variant_partitions_dir, "partitions.csv") - return variant_partitions if isfile(env.subst(variant_partitions)) else join(fwpartitions_dir, "default.csv") - - -def get_bootloader_image(variants_dir): - bootloader_image_file = "bootloader.bin" - if partitions_name.endswith("tinyuf2.csv"): - bootloader_image_file = "bootloader-tinyuf2.bin" - - variant_bootloader = join( - variants_dir, - board_config.get("build.variant", ""), - board_config.get("build.arduino.custom_bootloader", bootloader_image_file), - ) - - return ( - variant_bootloader - if isfile(env.subst(variant_bootloader)) - else generate_bootloader_image( - join( - FRAMEWORK_LIBS_DIR, - build_mcu, - "bin", - "bootloader_${__get_board_boot_mode(__env__)}_${__get_board_f_boot(__env__)}.elf", - ) - ) - ) - - -def generate_bootloader_image(bootloader_elf): - bootloader_cmd = env.Command( - join("$BUILD_DIR", "bootloader.bin"), - bootloader_elf, - env.VerboseAction( - " ".join( - [ - '"$PYTHONEXE" "$OBJCOPY"', - "--chip", - build_mcu, - "elf2image", - "--flash_mode", - "${__get_board_flash_mode(__env__)}", - "--flash_freq", - "${__get_board_f_image(__env__)}", - "--flash_size", - board_config.get("upload.flash_size", "4MB"), - "-o", - "$TARGET", - "$SOURCES", - ] - ), - "Building $TARGET", - ), - ) - - env.Depends("$BUILD_DIR/$PROGNAME$PROGSUFFIX", bootloader_cmd) - - # Because the Command always returns a NodeList, we have to - # access the first element in the list to get the Node object - # that actually represents the bootloader image. - # Also, this file is later used in generic Python code, so the - # Node object in converted to a generic string - return str(bootloader_cmd[0]) - - -def add_tinyuf2_extra_image(): - tinuf2_image = board_config.get( - "upload.arduino.tinyuf2_image", - join(variants_dir, board_config.get("build.variant", ""), "tinyuf2.bin"), - ) - - # Add the UF2 image only if it exists and it's not already added - if not isfile(env.subst(tinuf2_image)): - print("Warning! The `%s` UF2 bootloader image doesn't exist" % env.subst(tinuf2_image)) - return - - if any("tinyuf2.bin" == basename(extra_image[1]) for extra_image in env.get("FLASH_EXTRA_IMAGES", [])): - print("Warning! An extra UF2 bootloader image is already added!") - return - - env.Append( - FLASH_EXTRA_IMAGES=[ - ( - board_config.get( - "upload.arduino.uf2_bootloader_offset", - ("0x2d0000" if env.subst("$BOARD").startswith("adafruit") else "0x410000"), - ), - tinuf2_image, - ), - ] - ) - - -# -# Run target-specific script to populate the environment with proper build flags -# - -SConscript( - join( - FRAMEWORK_LIBS_DIR, - build_mcu, - "platformio-build.py", - ) -) - -# -# Additional flags specific to Arduino core (not based on IDF) -# - -env.Append( - CFLAGS=["-Werror=return-type"], - CXXFLAGS=["-Werror=return-type"], -) - -# -# Target: Build Core Library -# - -# Set -DARDUINO_CORE_BUILD only for the core library -corelib_env = env.Clone() -corelib_env.Append(CPPDEFINES=["ARDUINO_CORE_BUILD"]) - -libs = [] - -variants_dir = join(FRAMEWORK_DIR, "variants") - -if "build.variants_dir" in board_config: - variants_dir = join("$PROJECT_DIR", board_config.get("build.variants_dir")) - -if "build.variant" in board_config: - env.Append(CPPPATH=[join(variants_dir, board_config.get("build.variant"))]) - corelib_env.Append(CPPPATH=[join(variants_dir, board_config.get("build.variant"))]) - corelib_env.BuildSources( - join("$BUILD_DIR", "FrameworkArduinoVariant"), - join(variants_dir, board_config.get("build.variant")), - ) - -libs.append( - corelib_env.BuildLibrary( - join("$BUILD_DIR", "FrameworkArduino"), - join(FRAMEWORK_DIR, "cores", board_config.get("build.core")), - ) -) - -env.Prepend(LIBS=libs) - -# -# Process framework extra images -# - -env.Append( - LIBSOURCE_DIRS=[join(FRAMEWORK_DIR, "libraries")], - FLASH_EXTRA_IMAGES=[ - ( - "0x1000" if build_mcu in ("esp32", "esp32s2") else "0x0000", - get_bootloader_image(variants_dir), - ), - ("0x8000", join(env.subst("$BUILD_DIR"), "partitions.bin")), - ("0xe000", join(FRAMEWORK_DIR, "tools", "partitions", "boot_app0.bin")), - ] - + [(offset, join(FRAMEWORK_DIR, img)) for offset, img in board_config.get("upload.arduino.flash_extra_images", [])], -) - -# Add an extra UF2 image if the 'TinyUF2' partition is selected -if partitions_name.endswith("tinyuf2.csv") or board_config.get("upload.arduino.tinyuf2_image", ""): - add_tinyuf2_extra_image() - -# -# Generate partition table -# - -env.Replace(PARTITIONS_TABLE_CSV=get_partition_table_csv(variants_dir)) - -partition_table = env.Command( - join("$BUILD_DIR", "partitions.bin"), - "$PARTITIONS_TABLE_CSV", - env.VerboseAction( - '"$PYTHONEXE" "%s" -q $SOURCE $TARGET' % join(FRAMEWORK_DIR, "tools", "gen_esp32part.py"), - "Generating partitions $TARGET", - ), -) -env.Depends("$BUILD_DIR/$PROGNAME$PROGSUFFIX", partition_table) - -# -# Adjust the `esptoolpy` command in the `ElfToBin` builder with firmware checksum offset -# - -action = deepcopy(env["BUILDERS"]["ElfToBin"].action) -action.cmd_list = env["BUILDERS"]["ElfToBin"].action.cmd_list.replace("-o", "--elf-sha256-offset 0xb0 -o") -env["BUILDERS"]["ElfToBin"].action = action From 34f15c0335bb02bc81daf757b0541848bb4ddaef Mon Sep 17 00:00:00 2001 From: Rodrigo Garcia <rodrigo.garcia@espressif.com> Date: Fri, 29 Nov 2024 19:12:01 -0300 Subject: [PATCH 2/7] feat(support): documentation adjustment --- docs/_static/logo_pio.png | Bin 25979 -> 0 bytes docs/en/getting_started.rst | 11 +++-- docs/en/installing.rst | 87 ------------------------------------ docs/en/tutorials/blink.rst | 3 +- 4 files changed, 6 insertions(+), 95 deletions(-) delete mode 100644 docs/_static/logo_pio.png diff --git a/docs/_static/logo_pio.png b/docs/_static/logo_pio.png deleted file mode 100644 index a64c156396481be375fd126891d10c7e9d395488..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25979 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 diff --git a/docs/en/getting_started.rst b/docs/en/getting_started.rst index c4bd54b246c..8d312317bdf 100644 --- a/docs/en/getting_started.rst +++ b/docs/en/getting_started.rst @@ -78,14 +78,13 @@ Supported IDEs Here is the list of supported IDE for Arduino ESP32 support integration. -+-------------------+-------------------+ -| |arduino-logo| | |pio-logo| | -+-------------------+-------------------+ -| Arduino IDE | PlatformIO | -+-------------------+-------------------+ ++-------------------+ +| |arduino-logo| | ++-------------------+ +| Arduino IDE | ++-------------------+ .. |arduino-logo| image:: ../_static/logo_arduino.png -.. |pio-logo| image:: ../_static/logo_pio.png See `Installing Guides <installing.html>`_ for more details on how to install the Arduino ESP32 support. diff --git a/docs/en/installing.rst b/docs/en/installing.rst index ec405b3552c..d5392d4b5ec 100644 --- a/docs/en/installing.rst +++ b/docs/en/installing.rst @@ -63,92 +63,6 @@ To start the installation process using the Boards Manager, follow these steps: - Restart Arduino IDE. -Installing using PlatformIO ---------------------------- - -.. figure:: ../_static/logo_pio.png - :align: center - :width: 200 - :figclass: align-center - -PlatformIO is a professional collaborative platform for embedded development. It has out-of-the-box support for ESP32 SoCs and allows working with Arduino ESP32 as well as ESP-IDF from Espressif without changing your development environment. PlatformIO includes lots of instruments for the most common development tasks such as debugging, unit testing, and static code analysis. - -.. warning:: Integration of the Arduino Core ESP32 project in PlatformIO is maintained by PlatformIO developers. Arduino Core ESP32 Project Team cannot support PlatformIO-specific issues. Please report these issues in official `PlatformIO repositories <https://github.com/platformio>`_. - -A detailed overview of the PlatformIO ecosystem and its philosophy can be found in `the official documentation <https://docs.platformio.org/en/latest/core/index.html>`_. - -PlatformIO can be used in two flavors: - -- `PlatformIO IDE <https://platformio.org/platformio-ide>`_ is a toolset for embedded C/C++ development available on Windows, macOS and Linux platforms - -- `PlatformIO Core (CLI) <https://docs.platformio.org/en/latest/core/index.html>`_ is a command-line tool that consists of a multi-platform build system, platform and library managers and other integration components. It can be used with a variety of code development environments and allows integration with cloud platforms and web services - -To install PlatformIO, you can follow this Getting Started, provided at `docs.platformio.org`_. - -Using the stable code -********************* - -.. note:: - A detailed overview of supported development boards, examples and frameworks can be found on `the official Espressif32 dev-platform page <https://registry.platformio.org/platforms/platformio/espressif32>`_ in the PlatformIO Registry. - -The most reliable and easiest way to get started is to use the latest stable version of the ESP32 development platform that passed all tests/verifications and can be used in production. - -Create a new project and select one of the available boards. You can change after by changing the `platformio.ini <https://docs.platformio.org/en/latest/projectconf/index.html>`_ file. - -- For ESP32 - -.. code-block:: bash - - [env:esp32dev] - platform = espressif32 - board = esp32dev - framework = arduino - -- For ESP32-S2 (ESP32-S2-Saola-1 board) - -.. code-block:: bash - - [env:esp32-s2-saola-1] - platform = espressif32 - board = esp32-s2-saola-1 - framework = arduino - -- For ESP32-C3 (ESP32-C3-DevKitM-1 board) - -.. code-block:: bash - - [env:esp32-c3-devkitm-1] - platform = espressif32 - board = esp32-c3-devkitm-1 - framework = arduino - -How to update to the latest code -******************************** - -To test the latest Arduino ESP32, you need to change your project *platformio.ini* accordingly. -The following configuration uses the upstream version of the Espressif development platform and the latest Arduino core directly from the Espressif GitHub repository: - -.. code-block:: bash - - [env:esp32-c3-devkitm-1] - platform = https://github.com/platformio/platform-espressif32.git - board = esp32-c3-devkitm-1 - framework = arduino - platform_packages = - framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32#master - - -To get more information about PlatformIO, see the following links: - -- `PlatformIO Core (CLI) <https://docs.platformio.org/en/latest/core/index.html>`_ - -- `PlatformIO Home <https://docs.platformio.org/en/latest/home/index.html>`_ - -- `Tutorials and Examples <https://docs.platformio.org/en/latest/tutorials/index.html>`_ - -- `Library Management <https://docs.platformio.org/en/latest/librarymanager/index.html>`_ - - Windows (manual installation) ----------------------------- @@ -360,4 +274,3 @@ Where ``~/Documents/Arduino`` represents your sketch book location as per "Ardui - Restart Arduino IDE. .. _Arduino.cc: https://www.arduino.cc/en/Main/Software -.. _docs.platformio.org: https://docs.platformio.org/en/latest/integration/ide/pioide.html diff --git a/docs/en/tutorials/blink.rst b/docs/en/tutorials/blink.rst index b5f6a767f8d..5d6f13c8d17 100644 --- a/docs/en/tutorials/blink.rst +++ b/docs/en/tutorials/blink.rst @@ -7,7 +7,7 @@ Introduction This is the interactive blink tutorial using `Wokwi`_. For this tutorial, you don't need the ESP32 board or the Arduino toolchain. -.. note:: If you don't want to use this tutorial with the simulation, you can copy and paste the :ref:`blink_example_code` from `Wokwi`_ editor and use it on the `Arduino IDE`_ or `PlatformIO`_. +.. note:: If you don't want to use this tutorial with the simulation, you can copy and paste the :ref:`blink_example_code` from `Wokwi`_ editor and use it on the `Arduino IDE` _. About this Tutorial ------------------- @@ -109,5 +109,4 @@ Resources .. _ESP32 Datasheet: https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf .. _Wokwi: https://wokwi.com/ -.. _PlatformIO: https://docs.espressif.com/projects/arduino-esp32/en/latest/installing.html#platformio .. _Arduino IDE: https://docs.espressif.com/projects/arduino-esp32/en/latest/installing.html#installing-using-boards-manager From cb672d8daf20ff899c83e2ed90bbeef668bda721 Mon Sep 17 00:00:00 2001 From: Rodrigo Garcia <rodrigo.garcia@espressif.com> Date: Fri, 29 Nov 2024 19:13:49 -0300 Subject: [PATCH 3/7] feat(support): readme files, commentaries and examples --- .../FreeRTOS/BasicMultiThreading/README.md | 4 - .../ESP32/examples/FreeRTOS/Mutex/README.md | 238 +++++++-------- .../ESP32/examples/FreeRTOS/Queue/README.md | 146 +++++---- .../examples/FreeRTOS/Semaphore/README.md | 158 +++++----- .../Legacy_RMT_Driver_Compatible.ino | 1 - .../Template/ExampleTemplate/README.md | 242 ++++++++------- .../examples/LITTLEFS_PlatformIO/.gitignore | 4 - .../examples/LITTLEFS_PlatformIO/README.md | 68 ----- .../LITTLEFS_PlatformIO/data/file1.txt | 1 - .../data/testfolder/test2.txt | 1 - .../include/.placeholder.txt | 0 .../LITTLEFS_PlatformIO/lib/.placeholder.txt | 0 .../LITTLEFS_PlatformIO/partitions_custom.csv | 6 - .../LITTLEFS_PlatformIO/platformio.ini | 22 -- .../examples/LITTLEFS_PlatformIO/src/main.cpp | 286 ------------------ libraries/NetworkClientSecure/README.md | 20 +- .../examples/MultiHomedServers/README.md | 4 - .../WiFi/examples/FTM/FTM_Initiator/README.md | 4 - .../WiFi/examples/FTM/FTM_Responder/README.md | 4 - libraries/WiFi/examples/WiFiClient/README.md | 4 - .../WiFi/examples/WiFiClientConnect/README.md | 4 - libraries/WiFi/examples/WiFiScan/README.md | 4 - .../WiFi/examples/WiFiScanAsync/README.md | 4 - .../examples/WiFiScanDualAntenna/README.md | 4 - .../WiFi/examples/WiFiScanTime/README.md | 4 - 25 files changed, 387 insertions(+), 846 deletions(-) delete mode 100644 libraries/LittleFS/examples/LITTLEFS_PlatformIO/.gitignore delete mode 100644 libraries/LittleFS/examples/LITTLEFS_PlatformIO/README.md delete mode 100644 libraries/LittleFS/examples/LITTLEFS_PlatformIO/data/file1.txt delete mode 100644 libraries/LittleFS/examples/LITTLEFS_PlatformIO/data/testfolder/test2.txt delete mode 100644 libraries/LittleFS/examples/LITTLEFS_PlatformIO/include/.placeholder.txt delete mode 100644 libraries/LittleFS/examples/LITTLEFS_PlatformIO/lib/.placeholder.txt delete mode 100644 libraries/LittleFS/examples/LITTLEFS_PlatformIO/partitions_custom.csv delete mode 100644 libraries/LittleFS/examples/LITTLEFS_PlatformIO/platformio.ini delete mode 100644 libraries/LittleFS/examples/LITTLEFS_PlatformIO/src/main.cpp diff --git a/libraries/ESP32/examples/FreeRTOS/BasicMultiThreading/README.md b/libraries/ESP32/examples/FreeRTOS/BasicMultiThreading/README.md index 7bd44855adc..f48e352dd45 100644 --- a/libraries/ESP32/examples/FreeRTOS/BasicMultiThreading/README.md +++ b/libraries/ESP32/examples/FreeRTOS/BasicMultiThreading/README.md @@ -62,10 +62,6 @@ To get more information about the Espressif boards see [Espressif Development Ki * Before Compile/Verify, select the correct board: `Tools -> Board`. * Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. -#### Using Platform IO - -* Select the COM port: `Devices` or set the `upload_port` option on the `platformio.ini` file. - ## Troubleshooting ***Important: Make sure you are using a good quality USB cable and that you have a reliable power source*** diff --git a/libraries/ESP32/examples/FreeRTOS/Mutex/README.md b/libraries/ESP32/examples/FreeRTOS/Mutex/README.md index d1c8c19e3be..32c9f027bff 100644 --- a/libraries/ESP32/examples/FreeRTOS/Mutex/README.md +++ b/libraries/ESP32/examples/FreeRTOS/Mutex/README.md @@ -1,121 +1,117 @@ -# Mutex Example - -This example demonstrates the basic usage of FreeRTOS Mutually Exclusive Locks (Mutex) for securing access to shared resources in multi-threading. -Please refer to other examples in this folder to better understand the usage of tasks. -It is also advised to read the documentation on FreeRTOS web pages: -https://www.freertos.org/a00106.html - -This example creates 2 tasks with the same implementation - they write into a shared variable and then read it and check if it is the same as what they have written. -In single-thread programming like on Arduino this is of no concern and will be always ok, however when multi-threading is used the execution of the task is switched by the FreeRTOS and the value can be rewritten from another task before reading again. -The tasks print write and read operation - each in their column for better reading. Task 0 is on the left and Task 1 is on the right. -Watch the writes and read in secure mode when using the mutex (default) as the results are as you would expect them. -Then try to comment the USE_MUTEX and watch again - there will be a lot of mismatches! - -### Theory: -Mutex is a specialized version of Semaphore (please see the Semaphore example for more info). -In essence, the mutex is a variable whose value determines if the mute is taken (locked) or given (unlocked). -When two or more processes access the same resource (variable, peripheral, etc) it might happen, for example, that when one task starts to read a variable and the operating system (FreeRTOS) will schedule the execution of another task -which will write to this variable and when the previous task runs again it will read something different. - -Mutexes and binary semaphores are very similar but have some subtle differences: -Mutexes include a priority inheritance mechanism, whereas binary semaphores do not. -This makes binary semaphores the better choice for implementing synchronization (between tasks or between tasks and an interrupt), and mutexes the better -choice for implementing simple mutual exclusion. -What is priority inheritance? -If a low-priority task holds the Mutex but gets interrupted by a Higher priority task, which -then tries to take the Mutex, the low-priority task will temporarily ‘inherit’ the high priority so a middle-priority task can't block the low-priority task, and thus also block the high priority task. -Semaphores don't have the logic to handle this, in part because Semaphores aren't 'owned' by the task that takes them. - -A mutex can also be recursive - if a task that holds the mutex takes it again, it will succeed, and the mutex will be released -for other tasks only when it is given the same number of times that it was taken. - -You can check the danger by commenting on the definition of USE_MUTEX which will disable the mutex and present the danger of concurrent access. - - -# Supported Targets - -This example supports all ESP32 SoCs. - -## How to Use Example - -Flash and observe the serial output. - -Comment the `USE_MUTEX` definition, save and flash again and observe the behavior of unprotected access to the shared variable. - -* How to install the Arduino IDE: [Install Arduino IDE](https://github.com/espressif/arduino-esp32/tree/master/docs/arduino-ide). - -#### Using Arduino IDE - -To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits). - -* Before Compile/Verify, select the correct board: `Tools -> Board`. -* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. - -#### Using Platform IO - -* Select the COM port: `Devices` or set the `upload_port` option on the `platformio.ini` file. - -## Example Log Output - -The expected output of shared variables protected by mutex demonstrates mutually exclusive access from tasks - they do not interrupt each other and do not rewrite the value before the other task has read it back. - -``` - Task 0 | Task 1 - | Starting - | 0 <- 227 - Starting | - | R: 227 - 227 <- 737 | - R: 737 | - | 737 <- 282 - | R: 282 - 282 <- 267 | -``` - -The output of unprotected access to shared variable - it happens often that a task is interrupted after writing and before reading the other task write a different value - a corruption occurred! - -``` - Task 0 | Task 1 - | Starting - | 0 <- 333 - Starting | - 333 <- 620 | - R: 620 | - 620 <- 244 | - | R: 244 - | Mismatch! - | 244 <- 131 - R: 131 | - Mismatch! | - 131 <- 584 | - | R: 584 - | Mismatch! - | 584 <- 134 - | R: 134 - | 134 <- 554 - R: 554 | - Mismatch! | - 554 <- 313 | -``` - -## Troubleshooting - -***Important: Make sure you are using a good quality USB cable and that you have a reliable power source*** - -## Contribute - -To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) - -If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! - -Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else. - -## Resources - -* Official ESP32 Forum: [Link](https://esp32.com) -* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) -* ESP32 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf) -* ESP32-S2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf) -* ESP32-C3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf) -* ESP32-S3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf) -* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) +# Mutex Example + +This example demonstrates the basic usage of FreeRTOS Mutually Exclusive Locks (Mutex) for securing access to shared resources in multi-threading. +Please refer to other examples in this folder to better understand the usage of tasks. +It is also advised to read the documentation on FreeRTOS web pages: +https://www.freertos.org/a00106.html + +This example creates 2 tasks with the same implementation - they write into a shared variable and then read it and check if it is the same as what they have written. +In single-thread programming like on Arduino this is of no concern and will be always ok, however when multi-threading is used the execution of the task is switched by the FreeRTOS and the value can be rewritten from another task before reading again. +The tasks print write and read operation - each in their column for better reading. Task 0 is on the left and Task 1 is on the right. +Watch the writes and read in secure mode when using the mutex (default) as the results are as you would expect them. +Then try to comment the USE_MUTEX and watch again - there will be a lot of mismatches! + +### Theory: +Mutex is a specialized version of Semaphore (please see the Semaphore example for more info). +In essence, the mutex is a variable whose value determines if the mute is taken (locked) or given (unlocked). +When two or more processes access the same resource (variable, peripheral, etc) it might happen, for example, that when one task starts to read a variable and the operating system (FreeRTOS) will schedule the execution of another task +which will write to this variable and when the previous task runs again it will read something different. + +Mutexes and binary semaphores are very similar but have some subtle differences: +Mutexes include a priority inheritance mechanism, whereas binary semaphores do not. +This makes binary semaphores the better choice for implementing synchronization (between tasks or between tasks and an interrupt), and mutexes the better +choice for implementing simple mutual exclusion. +What is priority inheritance? +If a low-priority task holds the Mutex but gets interrupted by a Higher priority task, which +then tries to take the Mutex, the low-priority task will temporarily ‘inherit’ the high priority so a middle-priority task can't block the low-priority task, and thus also block the high priority task. +Semaphores don't have the logic to handle this, in part because Semaphores aren't 'owned' by the task that takes them. + +A mutex can also be recursive - if a task that holds the mutex takes it again, it will succeed, and the mutex will be released +for other tasks only when it is given the same number of times that it was taken. + +You can check the danger by commenting on the definition of USE_MUTEX which will disable the mutex and present the danger of concurrent access. + + +# Supported Targets + +This example supports all ESP32 SoCs. + +## How to Use Example + +Flash and observe the serial output. + +Comment the `USE_MUTEX` definition, save and flash again and observe the behavior of unprotected access to the shared variable. + +* How to install the Arduino IDE: [Install Arduino IDE](https://github.com/espressif/arduino-esp32/tree/master/docs/arduino-ide). + +#### Using Arduino IDE + +To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits). + +* Before Compile/Verify, select the correct board: `Tools -> Board`. +* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. + +## Example Log Output + +The expected output of shared variables protected by mutex demonstrates mutually exclusive access from tasks - they do not interrupt each other and do not rewrite the value before the other task has read it back. + +``` + Task 0 | Task 1 + | Starting + | 0 <- 227 + Starting | + | R: 227 + 227 <- 737 | + R: 737 | + | 737 <- 282 + | R: 282 + 282 <- 267 | +``` + +The output of unprotected access to shared variable - it happens often that a task is interrupted after writing and before reading the other task write a different value - a corruption occurred! + +``` + Task 0 | Task 1 + | Starting + | 0 <- 333 + Starting | + 333 <- 620 | + R: 620 | + 620 <- 244 | + | R: 244 + | Mismatch! + | 244 <- 131 + R: 131 | + Mismatch! | + 131 <- 584 | + | R: 584 + | Mismatch! + | 584 <- 134 + | R: 134 + | 134 <- 554 + R: 554 | + Mismatch! | + 554 <- 313 | +``` + +## Troubleshooting + +***Important: Make sure you are using a good quality USB cable and that you have a reliable power source*** + +## Contribute + +To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) + +If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! + +Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else. + +## Resources + +* Official ESP32 Forum: [Link](https://esp32.com) +* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) +* ESP32 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf) +* ESP32-S2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf) +* ESP32-C3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf) +* ESP32-S3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf) +* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) diff --git a/libraries/ESP32/examples/FreeRTOS/Queue/README.md b/libraries/ESP32/examples/FreeRTOS/Queue/README.md index 745ce9e8db6..b1cc3f3e3ac 100644 --- a/libraries/ESP32/examples/FreeRTOS/Queue/README.md +++ b/libraries/ESP32/examples/FreeRTOS/Queue/README.md @@ -1,75 +1,71 @@ -# Queue Example - -This example demonstrates the basic usage of FreeRTOS Queues which enables tasks to pass data between each other in a secure asynchronous way. -Please refer to other examples in this folder to better understand the usage of tasks. -It is also advised to read the documentation on FreeRTOS web pages: -[https://www.freertos.org/a00106.html](https://www.freertos.org/a00106.html) - -This example reads data received on the serial port (sent by the user) pass it via queue to another task which will send it back on Serial Output. - -### Theory: -A queue is a simple-to-use data structure (in the most basic way) controlled by `xQueueSend` and `xQueueReceive` functions. -Usually, one task writes into the queue and the other task reads from it. -Usage of queues enables the reading task to yield the CPU until there are data in the queue and therefore not waste precious computation time. - -# Supported Targets - -This example supports all ESP32 SoCs. - -## How to Use Example - -Flash and write anything to serial input. - -* How to install the Arduino IDE: [Install Arduino IDE](https://github.com/espressif/arduino-esp32/tree/master/docs/arduino-ide). - -#### Using Arduino IDE - -To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits). - -* Before Compile/Verify, select the correct board: `Tools -> Board`. -* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. - -#### Using Platform IO - -* Select the COM port: `Devices` or set the `upload_port` option on the `platformio.ini` file. - -## Example Log Output - -``` -Anything you write will return as echo. -Maximum line length is 63 characters (+ terminating '0'). -Anything longer will be sent as a separate line. - -``` -< Input text "Short input" - -``Echo line of size 11: "Short input"`` - -< Input text "An example of very long input which is longer than default 63 characters will be split." - -``` -Echo line of size 63: "An example of very long input which is longer than default 63 c" -Echo line of size 24: "haracters will be split." -``` - -## Troubleshooting - -***Important: Make sure you are using a good quality USB cable and that you have a reliable power source*** - -## Contribute - -To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) - -If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! - -Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else. - -## Resources - -* Official ESP32 Forum: [Link](https://esp32.com) -* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) -* ESP32 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf) -* ESP32-S2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf) -* ESP32-C3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf) -* ESP32-S3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf) -* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) +# Queue Example + +This example demonstrates the basic usage of FreeRTOS Queues which enables tasks to pass data between each other in a secure asynchronous way. +Please refer to other examples in this folder to better understand the usage of tasks. +It is also advised to read the documentation on FreeRTOS web pages: +[https://www.freertos.org/a00106.html](https://www.freertos.org/a00106.html) + +This example reads data received on the serial port (sent by the user) pass it via queue to another task which will send it back on Serial Output. + +### Theory: +A queue is a simple-to-use data structure (in the most basic way) controlled by `xQueueSend` and `xQueueReceive` functions. +Usually, one task writes into the queue and the other task reads from it. +Usage of queues enables the reading task to yield the CPU until there are data in the queue and therefore not waste precious computation time. + +# Supported Targets + +This example supports all ESP32 SoCs. + +## How to Use Example + +Flash and write anything to serial input. + +* How to install the Arduino IDE: [Install Arduino IDE](https://github.com/espressif/arduino-esp32/tree/master/docs/arduino-ide). + +#### Using Arduino IDE + +To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits). + +* Before Compile/Verify, select the correct board: `Tools -> Board`. +* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. + +## Example Log Output + +``` +Anything you write will return as echo. +Maximum line length is 63 characters (+ terminating '0'). +Anything longer will be sent as a separate line. + +``` +< Input text "Short input" + +``Echo line of size 11: "Short input"`` + +< Input text "An example of very long input which is longer than default 63 characters will be split." + +``` +Echo line of size 63: "An example of very long input which is longer than default 63 c" +Echo line of size 24: "haracters will be split." +``` + +## Troubleshooting + +***Important: Make sure you are using a good quality USB cable and that you have a reliable power source*** + +## Contribute + +To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) + +If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! + +Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else. + +## Resources + +* Official ESP32 Forum: [Link](https://esp32.com) +* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) +* ESP32 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf) +* ESP32-S2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf) +* ESP32-C3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf) +* ESP32-S3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf) +* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) diff --git a/libraries/ESP32/examples/FreeRTOS/Semaphore/README.md b/libraries/ESP32/examples/FreeRTOS/Semaphore/README.md index 8f860a52db5..0a076713e14 100644 --- a/libraries/ESP32/examples/FreeRTOS/Semaphore/README.md +++ b/libraries/ESP32/examples/FreeRTOS/Semaphore/README.md @@ -1,81 +1,77 @@ -# Semaphore Example - -This example demonstrates the basic usage of FreeRTOS Semaphores and queue sets for coordination between tasks for multi-threading. -Please refer to other examples in this folder to better understand the usage of tasks. -It is also advised to read the documentation on FreeRTOS web pages: -[https://www.freertos.org/a00106.html](https://www.freertos.org/a00106.html) - -### Theory: -Semaphore is in essence a variable. Tasks can set the value, wait until one or more -semaphores are set and thus communicate between each other their state. -A binary semaphore is a semaphore that has a maximum count of 1, hence the 'binary' name. -A task can only 'take' the semaphore if it is available, and the semaphore is only available if its count is 1. - -Semaphores can be controlled by any number of tasks. If you use semaphore as a one-way -signalization with only one task giving and only one task taking there is a much faster option -called Task Notifications - please see FreeRTOS documentation and read more about them: [https://www.freertos.org/RTOS-task-notifications.html](https://www.freertos.org/RTOS-task-notifications.html) - -This example uses a semaphore to signal when a package is delivered to a warehouse by multiple -delivery trucks, and multiple workers are waiting to receive the package. - -# Supported Targets - -This example supports all ESP32 SoCs. - -## How to Use Example - -Read the code and try to understand it, then flash and observe the Serial output. - -* How to install the Arduino IDE: [Install Arduino IDE](https://github.com/espressif/arduino-esp32/tree/master/docs/arduino-ide). - -#### Using Arduino IDE - -To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits). - -* Before Compile/Verify, select the correct board: `Tools -> Board`. -* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. - -#### Using Platform IO - -* Select the COM port: `Devices` or set the `upload_port` option on the `platformio.ini` file. - -## Example Log Output - -``` -Anything you write will return as echo. -Maximum line length is 63 characters (+ terminating '0'). -Anything longer will be sent as a separate line. - -``` -< Input text "Short input" - -``Echo line of size 11: "Short input"`` - -< Input text "An example of very long input which is longer than default 63 characters will be split." - -``` -Echo line of size 63: "An example of very long input which is longer than default 63 c" -Echo line of size 24: "haracters will be split." -``` - -## Troubleshooting - -***Important: Make sure you are using a good quality USB cable and that you have a reliable power source*** - -## Contribute - -To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) - -If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! - -Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else. - -## Resources - -* Official ESP32 Forum: [Link](https://esp32.com) -* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) -* ESP32 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf) -* ESP32-S2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf) -* ESP32-C3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf) -* ESP32-S3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf) -* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) +# Semaphore Example + +This example demonstrates the basic usage of FreeRTOS Semaphores and queue sets for coordination between tasks for multi-threading. +Please refer to other examples in this folder to better understand the usage of tasks. +It is also advised to read the documentation on FreeRTOS web pages: +[https://www.freertos.org/a00106.html](https://www.freertos.org/a00106.html) + +### Theory: +Semaphore is in essence a variable. Tasks can set the value, wait until one or more +semaphores are set and thus communicate between each other their state. +A binary semaphore is a semaphore that has a maximum count of 1, hence the 'binary' name. +A task can only 'take' the semaphore if it is available, and the semaphore is only available if its count is 1. + +Semaphores can be controlled by any number of tasks. If you use semaphore as a one-way +signalization with only one task giving and only one task taking there is a much faster option +called Task Notifications - please see FreeRTOS documentation and read more about them: [https://www.freertos.org/RTOS-task-notifications.html](https://www.freertos.org/RTOS-task-notifications.html) + +This example uses a semaphore to signal when a package is delivered to a warehouse by multiple +delivery trucks, and multiple workers are waiting to receive the package. + +# Supported Targets + +This example supports all ESP32 SoCs. + +## How to Use Example + +Read the code and try to understand it, then flash and observe the Serial output. + +* How to install the Arduino IDE: [Install Arduino IDE](https://github.com/espressif/arduino-esp32/tree/master/docs/arduino-ide). + +#### Using Arduino IDE + +To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits). + +* Before Compile/Verify, select the correct board: `Tools -> Board`. +* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. + +## Example Log Output + +``` +Anything you write will return as echo. +Maximum line length is 63 characters (+ terminating '0'). +Anything longer will be sent as a separate line. + +``` +< Input text "Short input" + +``Echo line of size 11: "Short input"`` + +< Input text "An example of very long input which is longer than default 63 characters will be split." + +``` +Echo line of size 63: "An example of very long input which is longer than default 63 c" +Echo line of size 24: "haracters will be split." +``` + +## Troubleshooting + +***Important: Make sure you are using a good quality USB cable and that you have a reliable power source*** + +## Contribute + +To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) + +If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! + +Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else. + +## Resources + +* Official ESP32 Forum: [Link](https://esp32.com) +* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) +* ESP32 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf) +* ESP32-S2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf) +* ESP32-C3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf) +* ESP32-S3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf) +* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) diff --git a/libraries/ESP32/examples/RMT/Legacy_RMT_Driver_Compatible/Legacy_RMT_Driver_Compatible.ino b/libraries/ESP32/examples/RMT/Legacy_RMT_Driver_Compatible/Legacy_RMT_Driver_Compatible.ino index 5744cf884a7..b42fe15f0cd 100644 --- a/libraries/ESP32/examples/RMT/Legacy_RMT_Driver_Compatible/Legacy_RMT_Driver_Compatible.ino +++ b/libraries/ESP32/examples/RMT/Legacy_RMT_Driver_Compatible/Legacy_RMT_Driver_Compatible.ino @@ -12,7 +12,6 @@ // add the file "build_opt.h" to your Arduino project folder with "-DESP32_ARDUINO_NO_RGB_BUILTIN" to use the RMT Legacy driver #error "ESP32_ARDUINO_NO_RGB_BUILTIN is not defined, this example is intended to demonstrate the RMT Legacy driver." #error "Please add the file 'build_opt.h' with '-DESP32_ARDUINO_NO_RGB_BUILTIN' to your Arduino project folder." -#error "Another way to disable the RGB_BUILTIN is to define it in the platformio.ini file, for instance: '-D ESP32_ARDUINO_NO_RGB_BUILTIN'" #else diff --git a/libraries/ESP32/examples/Template/ExampleTemplate/README.md b/libraries/ESP32/examples/Template/ExampleTemplate/README.md index f5aa7b35e86..4c4f497f43c 100644 --- a/libraries/ESP32/examples/Template/ExampleTemplate/README.md +++ b/libraries/ESP32/examples/Template/ExampleTemplate/README.md @@ -1,123 +1,119 @@ -# Arduino-ESP32 Example/Library Name ==(REQUIRED)== - -==*Add a brief description of this example/library here!*== - -This example/library demonstrates how to create a new example README file. - -# Supported Targets ==(REQUIRED)== - -==*Add the supported devices here!*== - -Currently, this example supports the following targets. - -| Supported Targets | ESP32 | ESP32-S2 | ESP32-C3 | -| ----------------- | ----- | -------- | -------- | - -## How to Use Example/Library ==(OPTIONAL)== - -==*Add a brief description of how to use this example.*== - -* How to install the Arduino IDE: [Install Arduino IDE](https://github.com/espressif/arduino-esp32/tree/master/docs/arduino-ide). - -### Hardware Connection ==(OPTIONAL)== - -==*Add a brief description of wiring or any other hardware-specific connection.*== - -To use this example, you need to connect the LED to the `GPIOx`. - -SDCard GPIO connection scheme: - -| SDCard Pin | Function | GPIO | -| ----------- | -------- | ------ | -| 1 | CS | GPIO5 | -| 2 | DI/MOSI | GPIO23 | -| 3 | VSS/GND | GND | -| 4 | VDD/3V3 | 3V3 | -| 5 | SCLK | GPIO18 | -| 6 | VSS/GND | GND | -| 7 | DO/MISO | GPIO19 | - -To add images, please create a folder `_asset` inside the example folder to add the relevant images. - -### Configure the Project ==(OPTIONAL)== - -==*Add a brief description of this example here!*== - -Set the LED GPIO by changing the `LED_BUILTIN` value in the function `pinMode(LED_BUILTIN, OUTPUT);`. By default, the GPIO is: `GPIOx`. - -#### Example for the GPIO4: - -==*Add some code explanation if relevant to the example.*== - -```cpp -// the setup function runs once when you press reset or power the board -void setup() { -// initialize digital pin 4 as an output. -pinMode(4, OUTPUT); -} -``` - -#### Using Arduino IDE - -To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits). - -* Before Compile/Verify, select the correct board: `Tools -> Board`. -* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. - -#### Using Platform IO - -* Select the COM port: `Devices` or set the `upload_port` option on the `platformio.ini` file. - -## Example/Log Output ==(OPTIONAL)== - -==*Add the log/serial output here!*== - -``` -ets Jul 29 2019 12:21:46 - -rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) -configsip: 0, SPIWP:0xee -clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 -mode:DIO, clock div:1 -load:0x3fff0030,len:1412 -load:0x40078000,len:13400 -load:0x40080400,len:3672 -entry 0x400805f8 -ESP32 Chip model = ESP32-D0WDQ5 Rev 3 -This chip has 2 cores -Chip ID: 3957392 -``` - -## Troubleshooting ==(REQUIRED)== - -==*Add specific issues you may find by using this example here!*== - -***Important: Make sure you are using a good quality USB cable and that you have a reliable power source*** - -* **LED not blinking:** Check the wiring connection and the IO selection. -* **Programming Fail:** If the programming/flash procedure fails, try reducing the serial connection speed. -* **COM port not detected:** Check the USB cable and the USB to Serial driver installation. - -If the error persists, you can ask for help at the official [ESP32 forum](https://esp32.com) or see [Contribute](#contribute). - -## Contribute ==(REQUIRED)== - -==*Do not change! Keep it as is.*== - -To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) - -If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! - -Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else. - -## Resources ==(REQUIRED)== - -==*Do not change here! Keep it as is or add only relevant documents/info for this example. Do not add any purchase link/marketing stuff*== - -* Official ESP32 Forum: [Link](https://esp32.com) -* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) -* ESP32 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf) -* ESP32-S2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf) -* ESP32-C3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf) -* ESP32-S3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf) -* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) +# Arduino-ESP32 Example/Library Name ==(REQUIRED)== + +==*Add a brief description of this example/library here!*== + +This example/library demonstrates how to create a new example README file. + +# Supported Targets ==(REQUIRED)== + +==*Add the supported devices here!*== + +Currently, this example supports the following targets. + +| Supported Targets | ESP32 | ESP32-S2 | ESP32-C3 | +| ----------------- | ----- | -------- | -------- | + +## How to Use Example/Library ==(OPTIONAL)== + +==*Add a brief description of how to use this example.*== + +* How to install the Arduino IDE: [Install Arduino IDE](https://github.com/espressif/arduino-esp32/tree/master/docs/arduino-ide). + +### Hardware Connection ==(OPTIONAL)== + +==*Add a brief description of wiring or any other hardware-specific connection.*== + +To use this example, you need to connect the LED to the `GPIOx`. + +SDCard GPIO connection scheme: + +| SDCard Pin | Function | GPIO | +| ----------- | -------- | ------ | +| 1 | CS | GPIO5 | +| 2 | DI/MOSI | GPIO23 | +| 3 | VSS/GND | GND | +| 4 | VDD/3V3 | 3V3 | +| 5 | SCLK | GPIO18 | +| 6 | VSS/GND | GND | +| 7 | DO/MISO | GPIO19 | + +To add images, please create a folder `_asset` inside the example folder to add the relevant images. + +### Configure the Project ==(OPTIONAL)== + +==*Add a brief description of this example here!*== + +Set the LED GPIO by changing the `LED_BUILTIN` value in the function `pinMode(LED_BUILTIN, OUTPUT);`. By default, the GPIO is: `GPIOx`. + +#### Example for the GPIO4: + +==*Add some code explanation if relevant to the example.*== + +```cpp +// the setup function runs once when you press reset or power the board +void setup() { +// initialize digital pin 4 as an output. +pinMode(4, OUTPUT); +} +``` + +#### Using Arduino IDE + +To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits). + +* Before Compile/Verify, select the correct board: `Tools -> Board`. +* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. + +## Example/Log Output ==(OPTIONAL)== + +==*Add the log/serial output here!*== + +``` +ets Jul 29 2019 12:21:46 + +rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) +configsip: 0, SPIWP:0xee +clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 +mode:DIO, clock div:1 +load:0x3fff0030,len:1412 +load:0x40078000,len:13400 +load:0x40080400,len:3672 +entry 0x400805f8 +ESP32 Chip model = ESP32-D0WDQ5 Rev 3 +This chip has 2 cores +Chip ID: 3957392 +``` + +## Troubleshooting ==(REQUIRED)== + +==*Add specific issues you may find by using this example here!*== + +***Important: Make sure you are using a good quality USB cable and that you have a reliable power source*** + +* **LED not blinking:** Check the wiring connection and the IO selection. +* **Programming Fail:** If the programming/flash procedure fails, try reducing the serial connection speed. +* **COM port not detected:** Check the USB cable and the USB to Serial driver installation. + +If the error persists, you can ask for help at the official [ESP32 forum](https://esp32.com) or see [Contribute](#contribute). + +## Contribute ==(REQUIRED)== + +==*Do not change! Keep it as is.*== + +To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) + +If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! + +Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else. + +## Resources ==(REQUIRED)== + +==*Do not change here! Keep it as is or add only relevant documents/info for this example. Do not add any purchase link/marketing stuff*== + +* Official ESP32 Forum: [Link](https://esp32.com) +* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) +* ESP32 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf) +* ESP32-S2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf) +* ESP32-C3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf) +* ESP32-S3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf) +* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) diff --git a/libraries/LittleFS/examples/LITTLEFS_PlatformIO/.gitignore b/libraries/LittleFS/examples/LITTLEFS_PlatformIO/.gitignore deleted file mode 100644 index 653e92272d5..00000000000 --- a/libraries/LittleFS/examples/LITTLEFS_PlatformIO/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -.pio -.vscode -mklittlefs.exe -mklittlefs diff --git a/libraries/LittleFS/examples/LITTLEFS_PlatformIO/README.md b/libraries/LittleFS/examples/LITTLEFS_PlatformIO/README.md deleted file mode 100644 index beed34e92f1..00000000000 --- a/libraries/LittleFS/examples/LITTLEFS_PlatformIO/README.md +++ /dev/null @@ -1,68 +0,0 @@ -# How to run on PlatformIO IDE - -- Download and extract to this project root a **mklittlefs** executable for your OS [from a zipped binary here](https://github.com/earlephilhower/mklittlefs/releases) -- Open **LITTLEFS_PlatformIO** folder -- Run PlatformIO project task: **Upload Filesystem Image** -- Run PlatformIO project task: **Upload and Monitor** -- You will see a Serial output like: -``` ---- Miniterm on COM5 115200,8,N,1 --- ---- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H --- -ets Jun 8 2016 00:22:57 - -rst:0x1 (POWERON_RESET),boot:0x13 (Snfigsip: 0, SPIWP:0xee -clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 -mode:DIO, clock div:2 -load:0x3fff0018,len:4 -load:0x3fff001c,len:1044 -load:0x40078000,len:10044 -load:0x40080400,len:5872 -entry 0x400806ac -Listing directory: / - FILE: /file1.txt SIZE: 3 LAST WRITE: 2020-10-06 15:10:33 - DIR : /testfolder LAST WRITE: 2020-10-06 15:10:33 -Creating Dir: /mydir -Dir created -Writing file: /mydir/hello2.txt -- file written -Listing directory: / - FILE: /file1.txt SIZE: 3 LAST WRITE: 2020-10-06 15:10:33 - DIR : /mydir LAST WRITE: 1970-01-01 00:00:00 -Listing directory: /mydir - FILE: /mydir/hello2.txt SIZE: 6 LAST WRITE: 1970-01-01 00:00:00 - DIR : /testfolder LAST WRITE: 2020-10-06 15:10:33 -Listing directory: /testfolder - FILE: /testfolder/test2.txt SIZE: 3 LAST WRITE: 2020-10-06 15:10:33 -Deleting file: /mydir/hello2.txt -- file deleted -Removing Dir: /mydir -Dir removed -Listing directory: / - FILE: /file1.txt SIZE: 3 LAST WRITE: 2020-10-06 15:10:33 - DIR : /testfolder LAST WRITE: 2020-10-06 15:10:33 -Listing directory: /testfolder - FILE: /testfolder/test2.txt SIZE: 3 LAST WRITE: 2020-10-06 15:10:33 -Writing file: /hello.txt -- file written -Appending to file: /hello.txt -- message appended -Reading file: /hello.txt -- read from file: -Hello World! -Renaming file /hello.txt to /foo.txt -- file renamed -Reading file: /foo.txt -- read from file: -Hello World! -Deleting file: /foo.txt -- file deleted -Testing file I/O with /test.txt -- writing................................................................ - - 1048576 bytes written in 12006 ms -- reading................................................................ -- 1048576 bytes read in 547 ms -Deleting file: /test.txt -- file deleted -Test complete -``` -- If you have a module with more than 4 MB flash, you can uncomment **partitions_custom.csv** in **platformio.ini** and modify the csv file accordingly diff --git a/libraries/LittleFS/examples/LITTLEFS_PlatformIO/data/file1.txt b/libraries/LittleFS/examples/LITTLEFS_PlatformIO/data/file1.txt deleted file mode 100644 index 72943a16fb2..00000000000 --- a/libraries/LittleFS/examples/LITTLEFS_PlatformIO/data/file1.txt +++ /dev/null @@ -1 +0,0 @@ -aaa diff --git a/libraries/LittleFS/examples/LITTLEFS_PlatformIO/data/testfolder/test2.txt b/libraries/LittleFS/examples/LITTLEFS_PlatformIO/data/testfolder/test2.txt deleted file mode 100644 index f761ec192d9..00000000000 --- a/libraries/LittleFS/examples/LITTLEFS_PlatformIO/data/testfolder/test2.txt +++ /dev/null @@ -1 +0,0 @@ -bbb diff --git a/libraries/LittleFS/examples/LITTLEFS_PlatformIO/include/.placeholder.txt b/libraries/LittleFS/examples/LITTLEFS_PlatformIO/include/.placeholder.txt deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/libraries/LittleFS/examples/LITTLEFS_PlatformIO/lib/.placeholder.txt b/libraries/LittleFS/examples/LITTLEFS_PlatformIO/lib/.placeholder.txt deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/libraries/LittleFS/examples/LITTLEFS_PlatformIO/partitions_custom.csv b/libraries/LittleFS/examples/LITTLEFS_PlatformIO/partitions_custom.csv deleted file mode 100644 index 97846fa59bb..00000000000 --- a/libraries/LittleFS/examples/LITTLEFS_PlatformIO/partitions_custom.csv +++ /dev/null @@ -1,6 +0,0 @@ -# Name, Type, SubType, Offset, Size, Flags -ota_0, app, ota_0, 0x10000, 0x1A0000, -ota_1, app, ota_1, , 0x1A0000, -otadata, data, ota, 0x350000, 0x2000, -nvs, data, nvs, , 0x6000, -data, data, spiffs, , 0xA8000, diff --git a/libraries/LittleFS/examples/LITTLEFS_PlatformIO/platformio.ini b/libraries/LittleFS/examples/LITTLEFS_PlatformIO/platformio.ini deleted file mode 100644 index dce1ac84456..00000000000 --- a/libraries/LittleFS/examples/LITTLEFS_PlatformIO/platformio.ini +++ /dev/null @@ -1,22 +0,0 @@ -; PlatformIO Project Configuration File -; -; Build options: build flags, source filter -; Upload options: custom upload port, speed and extra flags -; Library options: dependencies, extra library storages -; Advanced options: extra scripting -; -; Please visit documentation for the other options and examples -; https://docs.platformio.org/page/projectconf.html - -[platformio] -default_envs = esp32 - -[env] -framework = arduino - -[env:esp32] -platform = espressif32 -board = esp32dev -board_build.partitions = partitions_custom.csv -monitor_filters = esp32_exception_decoder -monitor_speed = 115200 diff --git a/libraries/LittleFS/examples/LITTLEFS_PlatformIO/src/main.cpp b/libraries/LittleFS/examples/LITTLEFS_PlatformIO/src/main.cpp deleted file mode 100644 index 5ae9e8d7dfc..00000000000 --- a/libraries/LittleFS/examples/LITTLEFS_PlatformIO/src/main.cpp +++ /dev/null @@ -1,286 +0,0 @@ -#include <Arduino.h> -#include "FS.h" -#include <LittleFS.h> -#include <time.h> - -/* You only need to format LittleFS the first time you run a - test or else use the LITTLEFS plugin to create a partition - https://github.com/lorol/arduino-esp32littlefs-plugin */ - -#define FORMAT_LITTLEFS_IF_FAILED true - -void listDir(fs::FS &fs, const char *dirname, uint8_t levels) { - Serial.printf("Listing directory: %s\r\n", dirname); - - File root = fs.open(dirname); - if (!root) { - Serial.println("- failed to open directory"); - return; - } - if (!root.isDirectory()) { - Serial.println(" - not a directory"); - return; - } - - File file = root.openNextFile(); - while (file) { - if (file.isDirectory()) { - Serial.print(" DIR : "); - - Serial.print(file.name()); - time_t t = file.getLastWrite(); - struct tm *tmstruct = localtime(&t); - Serial.printf( - " LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n", (tmstruct->tm_year) + 1900, (tmstruct->tm_mon) + 1, tmstruct->tm_mday, tmstruct->tm_hour, - tmstruct->tm_min, tmstruct->tm_sec - ); - - if (levels) { - listDir(fs, file.name(), levels - 1); - } - } else { - Serial.print(" FILE: "); - Serial.print(file.name()); - Serial.print(" SIZE: "); - - Serial.print(file.size()); - time_t t = file.getLastWrite(); - struct tm *tmstruct = localtime(&t); - Serial.printf( - " LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n", (tmstruct->tm_year) + 1900, (tmstruct->tm_mon) + 1, tmstruct->tm_mday, tmstruct->tm_hour, - tmstruct->tm_min, tmstruct->tm_sec - ); - } - file = root.openNextFile(); - } -} - -void createDir(fs::FS &fs, const char *path) { - Serial.printf("Creating Dir: %s\n", path); - if (fs.mkdir(path)) { - Serial.println("Dir created"); - } else { - Serial.println("mkdir failed"); - } -} - -void removeDir(fs::FS &fs, const char *path) { - Serial.printf("Removing Dir: %s\n", path); - if (fs.rmdir(path)) { - Serial.println("Dir removed"); - } else { - Serial.println("rmdir failed"); - } -} - -void readFile(fs::FS &fs, const char *path) { - Serial.printf("Reading file: %s\r\n", path); - - File file = fs.open(path); - if (!file || file.isDirectory()) { - Serial.println("- failed to open file for reading"); - return; - } - - Serial.println("- read from file:"); - while (file.available()) { - Serial.write(file.read()); - } - file.close(); -} - -void writeFile(fs::FS &fs, const char *path, const char *message) { - Serial.printf("Writing file: %s\r\n", path); - - File file = fs.open(path, FILE_WRITE); - if (!file) { - Serial.println("- failed to open file for writing"); - return; - } - if (file.print(message)) { - Serial.println("- file written"); - } else { - Serial.println("- write failed"); - } - file.close(); -} - -void appendFile(fs::FS &fs, const char *path, const char *message) { - Serial.printf("Appending to file: %s\r\n", path); - - File file = fs.open(path, FILE_APPEND); - if (!file) { - Serial.println("- failed to open file for appending"); - return; - } - if (file.print(message)) { - Serial.println("- message appended"); - } else { - Serial.println("- append failed"); - } - file.close(); -} - -void renameFile(fs::FS &fs, const char *path1, const char *path2) { - Serial.printf("Renaming file %s to %s\r\n", path1, path2); - if (fs.rename(path1, path2)) { - Serial.println("- file renamed"); - } else { - Serial.println("- rename failed"); - } -} - -void deleteFile(fs::FS &fs, const char *path) { - Serial.printf("Deleting file: %s\r\n", path); - if (fs.remove(path)) { - Serial.println("- file deleted"); - } else { - Serial.println("- delete failed"); - } -} - -// SPIFFS-like write and delete file - -// See: https://github.com/esp8266/Arduino/blob/master/libraries/LittleFS/src/LittleFS.cpp#L60 -void writeFile2(fs::FS &fs, const char *path, const char *message) { - if (!fs.exists(path)) { - if (strchr(path, '/')) { - Serial.printf("Create missing folders of: %s\r\n", path); - char *pathStr = strdup(path); - if (pathStr) { - char *ptr = strchr(pathStr, '/'); - while (ptr) { - *ptr = 0; - fs.mkdir(pathStr); - *ptr = '/'; - ptr = strchr(ptr + 1, '/'); - } - } - free(pathStr); - } - } - - Serial.printf("Writing file to: %s\r\n", path); - File file = fs.open(path, FILE_WRITE); - if (!file) { - Serial.println("- failed to open file for writing"); - return; - } - if (file.print(message)) { - Serial.println("- file written"); - } else { - Serial.println("- write failed"); - } - file.close(); -} - -// See: https://github.com/esp8266/Arduino/blob/master/libraries/LittleFS/src/LittleFS.h#L149 -void deleteFile2(fs::FS &fs, const char *path) { - Serial.printf("Deleting file and empty folders on path: %s\r\n", path); - - if (fs.remove(path)) { - Serial.println("- file deleted"); - } else { - Serial.println("- delete failed"); - } - - char *pathStr = strdup(path); - if (pathStr) { - char *ptr = strrchr(pathStr, '/'); - if (ptr) { - Serial.printf("Removing all empty folders on path: %s\r\n", path); - } - while (ptr) { - *ptr = 0; - fs.rmdir(pathStr); - ptr = strrchr(pathStr, '/'); - } - free(pathStr); - } -} - -void testFileIO(fs::FS &fs, const char *path) { - Serial.printf("Testing file I/O with %s\r\n", path); - - static uint8_t buf[512]; - size_t len = 0; - File file = fs.open(path, FILE_WRITE); - if (!file) { - Serial.println("- failed to open file for writing"); - return; - } - - size_t i; - Serial.print("- writing"); - uint32_t start = millis(); - for (i = 0; i < 2048; i++) { - if ((i & 0x001F) == 0x001F) { - Serial.print("."); - } - file.write(buf, 512); - } - Serial.println(""); - uint32_t end = millis() - start; - Serial.printf(" - %u bytes written in %u ms\r\n", 2048 * 512, end); - file.close(); - - file = fs.open(path); - start = millis(); - end = start; - i = 0; - if (file && !file.isDirectory()) { - len = file.size(); - size_t flen = len; - start = millis(); - Serial.print("- reading"); - while (len) { - size_t toRead = len; - if (toRead > 512) { - toRead = 512; - } - file.read(buf, toRead); - if ((i++ & 0x001F) == 0x001F) { - Serial.print("."); - } - len -= toRead; - } - Serial.println(""); - end = millis() - start; - Serial.printf("- %u bytes read in %u ms\r\n", flen, end); - file.close(); - } else { - Serial.println("- failed to open file for reading"); - } -} - -void setup() { - Serial.begin(115200); - if (!LittleFS.begin(FORMAT_LITTLEFS_IF_FAILED)) { - Serial.println("LittleFS Mount Failed"); - return; - } - - listDir(LittleFS, "/", 0); - createDir(LittleFS, "/mydir"); - writeFile(LittleFS, "/mydir/hello2.txt", "Hello2"); - //writeFile(LittleFS, "/mydir/newdir2/newdir3/hello3.txt", "Hello3"); - writeFile2(LittleFS, "/mydir/newdir2/newdir3/hello3.txt", "Hello3"); - listDir(LittleFS, "/", 3); - deleteFile(LittleFS, "/mydir/hello2.txt"); - //deleteFile(LittleFS, "/mydir/newdir2/newdir3/hello3.txt"); - deleteFile2(LittleFS, "/mydir/newdir2/newdir3/hello3.txt"); - removeDir(LittleFS, "/mydir"); - listDir(LittleFS, "/", 3); - writeFile(LittleFS, "/hello.txt", "Hello "); - appendFile(LittleFS, "/hello.txt", "World!\r\n"); - readFile(LittleFS, "/hello.txt"); - renameFile(LittleFS, "/hello.txt", "/foo.txt"); - readFile(LittleFS, "/foo.txt"); - deleteFile(LittleFS, "/foo.txt"); - testFileIO(LittleFS, "/test.txt"); - deleteFile(LittleFS, "/test.txt"); - - Serial.println("Test complete"); -} - -void loop() {} diff --git a/libraries/NetworkClientSecure/README.md b/libraries/NetworkClientSecure/README.md index d028158730d..f83cf246287 100644 --- a/libraries/NetworkClientSecure/README.md +++ b/libraries/NetworkClientSecure/README.md @@ -32,25 +32,11 @@ This method is similar to the single root certificate verification above, but it root certificates from Mozilla to authenticate against, while the previous method only accepts a single certificate for a given server. This allows the client to connect to all public SSL servers. -To use this feature in PlatformIO: -1. create a certificate bundle as described in the document below, or obtain a pre-built one you trust: -https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/protocols/esp_crt_bundle.html -(gen_crt_bundle.py can be found in the /tools folder) - a. note: the full bundle will take up around 64k of flash space, but has minimal RAM usage, as only - the index of the certificates is kept in RAM -2. Place the bundle under the file name "data/cert/x509_crt_bundle.bin" in your platformio project -3. add "board_build.embed_files = data/cert/x509_crt_bundle.bin" in your platformio.ini -4. add the following global declaration in your project: - extern const uint8_t rootca_crt_bundle_start[] asm("_binary_data_cert_x509_crt_bundle_bin_start"); -5. before initiating the first SSL connection, call - my_client.setCACertBundle(rootca_crt_bundle_start); - To use this feature in Arduino IDE: If the Arduino IDE added support for embedding files in the meantime, then follow the instructions above. -If not, you have three choices: -1. convert your project to PlatformIO -2. create a makefile where you can add the idf_component_register() declaration to include the certificate bundle -3. Store the bundle as a SPIFFS file, but then you have to load it into RAM in runtime and waste 64k of precious memory +If not, you have two choices: +1. create a makefile where you can add the idf_component_register() declaration to include the certificate bundle +2. Store the bundle as a SPIFFS file, but then you have to load it into RAM in runtime and waste 64k of precious memory Using a root CA cert and client cert/keys ----------------------------------------- diff --git a/libraries/WebServer/examples/MultiHomedServers/README.md b/libraries/WebServer/examples/MultiHomedServers/README.md index 83ec6223850..04b96dfbd53 100644 --- a/libraries/WebServer/examples/MultiHomedServers/README.md +++ b/libraries/WebServer/examples/MultiHomedServers/README.md @@ -67,10 +67,6 @@ To get more information about the Espressif boards see [Espressif Development Ki * Before Compile/Verify, select the correct board: `Tools -> Board`. * Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. -#### Using Platform IO - -* Select the COM port: `Devices` or set the `upload_port` option on the `platformio.ini` file. - ## Example Log Output ``` diff --git a/libraries/WiFi/examples/FTM/FTM_Initiator/README.md b/libraries/WiFi/examples/FTM/FTM_Initiator/README.md index 3558f75d372..b9c7f8d438d 100644 --- a/libraries/WiFi/examples/FTM/FTM_Initiator/README.md +++ b/libraries/WiFi/examples/FTM/FTM_Initiator/README.md @@ -55,10 +55,6 @@ To get more information about the Espressif boards see [Espressif Development Ki * Before Compile/Verify, select the correct board: `Tools -> Board`. * Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. -#### Using Platform IO - -* Select the COM port: `Devices` or setting the `upload_port` option on the `platformio.ini` file. - ## Log Output Expected log output: diff --git a/libraries/WiFi/examples/FTM/FTM_Responder/README.md b/libraries/WiFi/examples/FTM/FTM_Responder/README.md index feede0867f3..fdcf1ab921b 100644 --- a/libraries/WiFi/examples/FTM/FTM_Responder/README.md +++ b/libraries/WiFi/examples/FTM/FTM_Responder/README.md @@ -48,10 +48,6 @@ To get more information about the Espressif boards see [Espressif Development Ki * Before Compile/Verify, select the correct board: `Tools -> Board`. * Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. -#### Using Platform IO - -* Select the COM port: `Devices` or setting the `upload_port` option on the `platformio.ini` file. - ## Log Output Expected log output: diff --git a/libraries/WiFi/examples/WiFiClient/README.md b/libraries/WiFi/examples/WiFiClient/README.md index 8b6a5d9caeb..9d3698a543a 100644 --- a/libraries/WiFi/examples/WiFiClient/README.md +++ b/libraries/WiFi/examples/WiFiClient/README.md @@ -61,10 +61,6 @@ To get more information about the Espressif boards see [Espressif Development Ki * Before Compile/Verify, select the correct board: `Tools -> Board`. * Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. -#### Using Platform IO - -* Select the COM port: `Devices` or set the `upload_port` option on the `platformio.ini` file. - ## Example Log Output The initial output which is common for all examples can be ignored: diff --git a/libraries/WiFi/examples/WiFiClientConnect/README.md b/libraries/WiFi/examples/WiFiClientConnect/README.md index eab02b674ff..939d44c5b76 100644 --- a/libraries/WiFi/examples/WiFiClientConnect/README.md +++ b/libraries/WiFi/examples/WiFiClientConnect/README.md @@ -18,10 +18,6 @@ Currently, this example supports the following targets. * Before Compile/Verify, select the correct board: `Tools -> Board`. * Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. -#### Using Platform IO - -* Select the COM port: `Devices` or set the `upload_port`` option on the `platformio.ini` file. - ## Example/Log Output ``` diff --git a/libraries/WiFi/examples/WiFiScan/README.md b/libraries/WiFi/examples/WiFiScan/README.md index ec39cc6c639..f1268f21b5c 100644 --- a/libraries/WiFi/examples/WiFiScan/README.md +++ b/libraries/WiFi/examples/WiFiScan/README.md @@ -18,10 +18,6 @@ Currently, this example supports the following targets. * Before Compile/Verify, select the correct board: `Tools -> Board`. * Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. -#### Using Platform IO - -* Select the COM port: `Devices` or setting the `upload_port` option on the `platformio.ini` file. - ## Example/Log Output ``` diff --git a/libraries/WiFi/examples/WiFiScanAsync/README.md b/libraries/WiFi/examples/WiFiScanAsync/README.md index a557173c10f..26120aaa31c 100644 --- a/libraries/WiFi/examples/WiFiScanAsync/README.md +++ b/libraries/WiFi/examples/WiFiScanAsync/README.md @@ -18,10 +18,6 @@ Currently, this example supports the following targets. * Before Compile/Verify, select the correct board: `Tools -> Board`. * Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. -#### Using Platform IO - -* Select the COM port: `Devices` or setting the `upload_port` option on the `platformio.ini` file. - ## Example/Log Output ``` diff --git a/libraries/WiFi/examples/WiFiScanDualAntenna/README.md b/libraries/WiFi/examples/WiFiScanDualAntenna/README.md index f7ec7cc3ef9..9a6611149d0 100644 --- a/libraries/WiFi/examples/WiFiScanDualAntenna/README.md +++ b/libraries/WiFi/examples/WiFiScanDualAntenna/README.md @@ -17,10 +17,6 @@ This example is compatible with the ESP32-WROOM-DA. * Before Compile/Verify, select the correct board: `Tools -> Board`. * Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. -#### Using Platform IO - -* Select the COM port: `Devices` or set the `upload_port` option on the `platformio.ini` file. - ## Example/Log Output ``` diff --git a/libraries/WiFi/examples/WiFiScanTime/README.md b/libraries/WiFi/examples/WiFiScanTime/README.md index f56ba893925..7be0e05d4fe 100644 --- a/libraries/WiFi/examples/WiFiScanTime/README.md +++ b/libraries/WiFi/examples/WiFiScanTime/README.md @@ -18,10 +18,6 @@ Currently, this example supports the following targets. * Before Compile/Verify, select the correct board: `Tools -> Board`. * Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. -#### Using Platform IO - -* Select the COM port: `Devices` or setting the `upload_port` option on the `platformio.ini` file. - ## Example/Log Output ``` From c03a57470c68249b2f58ff5f4ed23a3d17d83bc3 Mon Sep 17 00:00:00 2001 From: Rodrigo Garcia <rodrigo.garcia@espressif.com> Date: Fri, 29 Nov 2024 19:21:39 -0300 Subject: [PATCH 4/7] fix(support): left over in documentation. --- docs/en/tutorials/blink.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/tutorials/blink.rst b/docs/en/tutorials/blink.rst index 5d6f13c8d17..f4a53ec945d 100644 --- a/docs/en/tutorials/blink.rst +++ b/docs/en/tutorials/blink.rst @@ -7,7 +7,7 @@ Introduction This is the interactive blink tutorial using `Wokwi`_. For this tutorial, you don't need the ESP32 board or the Arduino toolchain. -.. note:: If you don't want to use this tutorial with the simulation, you can copy and paste the :ref:`blink_example_code` from `Wokwi`_ editor and use it on the `Arduino IDE` _. +.. note:: If you don't want to use this tutorial with the simulation, you can copy and paste the :ref:`blink_example_code` from `Wokwi`_ editor and use it on the `Arduino IDE`. About this Tutorial ------------------- From d0b2c59c9c3488b103e609e577686610b996a6e7 Mon Sep 17 00:00:00 2001 From: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com> Date: Mon, 2 Dec 2024 18:37:56 -0300 Subject: [PATCH 5/7] Revert "feat(support): toll and ci changes" This reverts commit 857935c31442fa0d37a790edd09241e3d076d790. --- .github/ISSUE_TEMPLATE/Issue-report.yml | 2 +- .github/scripts/install-platformio-esp32.sh | 170 +++++++++++++ .github/scripts/on-push.sh | 81 ++++--- .github/scripts/on-release.sh | 1 + .github/scripts/set_push_chunks.sh | 1 + .github/workflows/push.yml | 30 +++ platform.txt | 1 + tools/platformio-build.py | 251 ++++++++++++++++++++ 8 files changed, 507 insertions(+), 30 deletions(-) create mode 100755 .github/scripts/install-platformio-esp32.sh create mode 100644 tools/platformio-build.py diff --git a/.github/ISSUE_TEMPLATE/Issue-report.yml b/.github/ISSUE_TEMPLATE/Issue-report.yml index acbd9a3c29a..d5b756085c7 100644 --- a/.github/ISSUE_TEMPLATE/Issue-report.yml +++ b/.github/ISSUE_TEMPLATE/Issue-report.yml @@ -75,7 +75,7 @@ body: attributes: label: IDE Name description: What IDE are you using? - placeholder: eg. Arduino IDE, VSCode, Sloeber... + placeholder: eg. Arduino IDE, PlatformIO, Sloeber... validations: required: true - type: input diff --git a/.github/scripts/install-platformio-esp32.sh b/.github/scripts/install-platformio-esp32.sh new file mode 100755 index 00000000000..80c668bdc0e --- /dev/null +++ b/.github/scripts/install-platformio-esp32.sh @@ -0,0 +1,170 @@ +#!/bin/bash + +export PLATFORMIO_ESP32_PATH="$HOME/.platformio/packages/framework-arduinoespressif32" +PLATFORMIO_ESP32_URL="https://github.com/platformio/platform-espressif32.git" + +TOOLCHAIN_VERSION="12.2.0+20230208" +ESPTOOLPY_VERSION="~1.40501.0" +ESPRESSIF_ORGANIZATION_NAME="espressif" +SDKCONFIG_DIR="$PLATFORMIO_ESP32_PATH/tools/esp32-arduino-libs" +SCRIPTS_DIR="./.github/scripts" +COUNT_SKETCHES="${SCRIPTS_DIR}/sketch_utils.sh count" +CHECK_REQUIREMENTS="${SCRIPTS_DIR}/sketch_utils.sh check_requirements" + +echo "Installing Python Wheel ..." +pip install wheel > /dev/null 2>&1 + +echo "Installing PlatformIO ..." +pip install -U https://github.com/platformio/platformio/archive/master.zip > /dev/null 2>&1 + +echo "Installing Platform ESP32 ..." +python -m platformio platform install $PLATFORMIO_ESP32_URL > /dev/null 2>&1 + +echo "Replacing the package versions ..." +replace_script="import json; import os;" +replace_script+="fp=open(os.path.expanduser('~/.platformio/platforms/espressif32/platform.json'), 'r+');" +replace_script+="data=json.load(fp);" +# Use framework sources from the repository +replace_script+="data['packages']['framework-arduinoespressif32']['version'] = '*';" +replace_script+="del data['packages']['framework-arduinoespressif32']['owner'];" +# Use toolchain packages from the "espressif" organization +replace_script+="data['packages']['toolchain-xtensa-esp32']['owner']='$ESPRESSIF_ORGANIZATION_NAME';" +replace_script+="data['packages']['toolchain-xtensa-esp32s2']['owner']='$ESPRESSIF_ORGANIZATION_NAME';" +replace_script+="data['packages']['toolchain-riscv32-esp']['owner']='$ESPRESSIF_ORGANIZATION_NAME';" +# Update versions to use the upstream +replace_script+="data['packages']['toolchain-xtensa-esp32']['version']='$TOOLCHAIN_VERSION';" +replace_script+="data['packages']['toolchain-xtensa-esp32s2']['version']='$TOOLCHAIN_VERSION';" +replace_script+="data['packages']['toolchain-xtensa-esp32s3']['version']='$TOOLCHAIN_VERSION';" +replace_script+="data['packages']['toolchain-riscv32-esp']['version']='$TOOLCHAIN_VERSION';" +# Add new "framework-arduinoespressif32-libs" package +# Read "package_esp32_index.template.json" to extract a url to a zip package for "esp32-arduino-libs" +replace_script+="fpackage=open(os.path.join('package', 'package_esp32_index.template.json'), 'r+');" +replace_script+="package_data=json.load(fpackage);" +replace_script+="fpackage.close();" +replace_script+="libs_package_archive_url=next(next(system['url'] for system in tool['systems'] if system['host'] == 'x86_64-pc-linux-gnu') for tool in package_data['packages'][0]['tools'] if tool['name'] == 'esp32-arduino-libs');" +replace_script+="data['packages'].update({'framework-arduinoespressif32-libs':{'type':'framework','optional':False,'version':libs_package_archive_url}});" +replace_script+="data['packages']['toolchain-xtensa-esp32'].update({'optional':False});" +# esptool.py may require an upstream version (for now platformio is the owner) +replace_script+="data['packages']['tool-esptoolpy']['version']='$ESPTOOLPY_VERSION';" +# Save results +replace_script+="fp.seek(0);fp.truncate();json.dump(data, fp, indent=2);fp.close()" +python -c "$replace_script" + +if [ "$GITHUB_REPOSITORY" == "espressif/arduino-esp32" ]; then + echo "Linking Core..." + ln -s $GITHUB_WORKSPACE "$PLATFORMIO_ESP32_PATH" +else + echo "Cloning Core Repository ..." + git clone --recursive https://github.com/espressif/arduino-esp32.git "$PLATFORMIO_ESP32_PATH" > /dev/null 2>&1 +fi + +echo "PlatformIO for ESP32 has been installed" +echo "" + +function build_pio_sketch(){ # build_pio_sketch <board> <options> <path-to-ino> + if [ "$#" -lt 3 ]; then + echo "ERROR: Illegal number of parameters" + echo "USAGE: build_pio_sketch <board> <options> <path-to-ino>" + return 1 + fi + + local board="$1" + local options="$2" + local sketch="$3" + local sketch_dir=$(dirname "$sketch") + echo "" + echo "Compiling '"$(basename "$sketch")"' ..." + python -m platformio ci --board "$board" "$sketch_dir" --project-option="$options" +} + +function build_pio_sketches(){ # build_pio_sketches <board> <options> <examples-path> <chunk> <total-chunks> + if [ "$#" -lt 3 ]; then + echo "ERROR: Illegal number of parameters" + echo "USAGE: build_pio_sketches <board> <options> <examples-path> [<chunk> <total-chunks>]" + return 1 + fi + + local board=$1 + local options="$2" + local examples=$3 + local chunk_idex=$4 + local chunks_num=$5 + + if [ "$#" -lt 5 ]; then + chunk_idex="0" + chunks_num="1" + fi + + if [ "$chunks_num" -le 0 ]; then + echo "ERROR: Chunks count must be positive number" + return 1 + fi + if [ "$chunk_idex" -ge "$chunks_num" ]; then + echo "ERROR: Chunk index must be less than chunks count" + return 1 + fi + + set +e + ${COUNT_SKETCHES} "$examples" "esp32" + local sketchcount=$? + set -e + local sketches=$(cat sketches.txt) + rm -rf sketches.txt + + local chunk_size=$(( $sketchcount / $chunks_num )) + local all_chunks=$(( $chunks_num * $chunk_size )) + if [ "$all_chunks" -lt "$sketchcount" ]; then + chunk_size=$(( $chunk_size + 1 )) + fi + + local start_index=$(( $chunk_idex * $chunk_size )) + if [ "$sketchcount" -le "$start_index" ]; then + echo "Skipping job" + return 0 + fi + + local end_index=$(( $(( $chunk_idex + 1 )) * $chunk_size )) + if [ "$end_index" -gt "$sketchcount" ]; then + end_index=$sketchcount + fi + + local start_num=$(( $start_index + 1 )) + echo "Found $sketchcount Sketches"; + echo "Chunk Count : $chunks_num" + echo "Chunk Size : $chunk_size" + echo "Start Sketch: $start_num" + echo "End Sketch : $end_index" + + local sketchnum=0 + for sketch in $sketches; do + local sketchdir=$(dirname $sketch) + local sketchdirname=$(basename $sketchdir) + local sketchname=$(basename $sketch) + if [[ "$sketchdirname.ino" != "$sketchname" ]]; then + continue + elif [ -f $sketchdir/ci.json ]; then + # If the target is listed as false, skip the sketch. Otherwise, include it. + is_target=$(jq -r '.targets[esp32]' $sketchdir/ci.json) + if [[ "$is_target" == "false" ]]; then + continue + fi + + local has_requirements=$(${CHECK_REQUIREMENTS} $sketchdir "$SDKCONFIG_DIR/esp32/sdkconfig") + if [ "$has_requirements" == "0" ]; then + continue + fi + fi + + sketchnum=$(($sketchnum + 1)) + if [ "$sketchnum" -le "$start_index" ] \ + || [ "$sketchnum" -gt "$end_index" ]; then + continue + fi + build_pio_sketch "$board" "$options" "$sketch" + local result=$? + if [ $result -ne 0 ]; then + return $result + fi + done + return 0 +} diff --git a/.github/scripts/on-push.sh b/.github/scripts/on-push.sh index 7f436c7b0ee..08ff505f1c0 100755 --- a/.github/scripts/on-push.sh +++ b/.github/scripts/on-push.sh @@ -54,11 +54,14 @@ CHUNK_INDEX=$1 CHUNKS_CNT=$2 BUILD_LOG=$3 SKETCHES_FILE=$4 +BUILD_PIO=0 if [ "$#" -lt 2 ] || [ "$CHUNKS_CNT" -le 0 ]; then CHUNK_INDEX=0 CHUNKS_CNT=1 elif [ "$CHUNK_INDEX" -gt "$CHUNKS_CNT" ] && [ "$CHUNKS_CNT" -ge 2 ]; then CHUNK_INDEX=$CHUNKS_CNT +elif [ "$CHUNK_INDEX" -eq "$CHUNKS_CNT" ]; then + BUILD_PIO=1 fi if [ -z "$BUILD_LOG" ] || [ "$BUILD_LOG" -le 0 ]; then @@ -69,34 +72,54 @@ fi #git -C "$GITHUB_WORKSPACE" submodule update --init --recursive > /dev/null 2>&1 SCRIPTS_DIR="./.github/scripts" -source ${SCRIPTS_DIR}/install-arduino-cli.sh -source ${SCRIPTS_DIR}/install-arduino-core-esp32.sh - -SKETCHES_ESP32="\ - $ARDUINO_ESP32_PATH/libraries/NetworkClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino\ - $ARDUINO_ESP32_PATH/libraries/BLE/examples/Server/Server.ino\ - $ARDUINO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino\ - $ARDUINO_ESP32_PATH/libraries/Insights/examples/MinimalDiagnostics/MinimalDiagnostics.ino\ -" -#create sizes_file -sizes_file="$GITHUB_WORKSPACE/cli_compile_$CHUNK_INDEX.json" - -if [ "$BUILD_LOG" -eq 1 ]; then - #create sizes_file and echo start of JSON array with "boards" key - echo "{\"boards\": [" > $sizes_file -fi +if [ "$BUILD_PIO" -eq 0 ]; then + source ${SCRIPTS_DIR}/install-arduino-cli.sh + source ${SCRIPTS_DIR}/install-arduino-core-esp32.sh + + SKETCHES_ESP32="\ + $ARDUINO_ESP32_PATH/libraries/NetworkClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino\ + $ARDUINO_ESP32_PATH/libraries/BLE/examples/Server/Server.ino\ + $ARDUINO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino\ + $ARDUINO_ESP32_PATH/libraries/Insights/examples/MinimalDiagnostics/MinimalDiagnostics.ino\ + " + #create sizes_file + sizes_file="$GITHUB_WORKSPACE/cli_compile_$CHUNK_INDEX.json" + + if [ "$BUILD_LOG" -eq 1 ]; then + #create sizes_file and echo start of JSON array with "boards" key + echo "{\"boards\": [" > $sizes_file + fi -#build sketches for different targets -build "esp32s3" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$SKETCHES_FILE" "$SKETCHES_ESP32" -build "esp32s2" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$SKETCHES_FILE" "$SKETCHES_ESP32" -build "esp32c3" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$SKETCHES_FILE" "$SKETCHES_ESP32" -build "esp32c6" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$SKETCHES_FILE" "$SKETCHES_ESP32" -build "esp32h2" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$SKETCHES_FILE" "$SKETCHES_ESP32" -build "esp32" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$SKETCHES_FILE" "$SKETCHES_ESP32" - -if [ "$BUILD_LOG" -eq 1 ]; then - #remove last comma from the last JSON object - sed -i '$ s/,$//' "$sizes_file" - #echo end of JSON array - echo "]}" >> $sizes_file + #build sketches for different targets + build "esp32s3" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$SKETCHES_FILE" "$SKETCHES_ESP32" + build "esp32s2" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$SKETCHES_FILE" "$SKETCHES_ESP32" + build "esp32c3" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$SKETCHES_FILE" "$SKETCHES_ESP32" + build "esp32c6" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$SKETCHES_FILE" "$SKETCHES_ESP32" + build "esp32h2" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$SKETCHES_FILE" "$SKETCHES_ESP32" + build "esp32" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$SKETCHES_FILE" "$SKETCHES_ESP32" + + if [ "$BUILD_LOG" -eq 1 ]; then + #remove last comma from the last JSON object + sed -i '$ s/,$//' "$sizes_file" + #echo end of JSON array + echo "]}" >> $sizes_file + fi +else + source ${SCRIPTS_DIR}/install-platformio-esp32.sh + # PlatformIO ESP32 Test + BOARD="esp32dev" + OPTIONS="board_build.partitions = huge_app.csv" + build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino" && \ + build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/NetworkClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino" && \ + build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino" && \ + build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/BLE/examples/Server/Server.ino" && \ + build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino" + + # Basic sanity testing for other series + for board in "esp32-c3-devkitm-1" "esp32-s2-saola-1" "esp32-s3-devkitc-1" + do + python -m platformio ci --board "$board" "$PLATFORMIO_ESP32_PATH/libraries/WiFi/examples/WiFiClient" --project-option="board_build.partitions = huge_app.csv" + done + + #build_pio_sketches "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries" fi diff --git a/.github/scripts/on-release.sh b/.github/scripts/on-release.sh index 2308717e9d8..e0dd7b752c5 100755 --- a/.github/scripts/on-release.sh +++ b/.github/scripts/on-release.sh @@ -207,6 +207,7 @@ cp -f "$GITHUB_WORKSPACE/tools/gen_insights_package.py" "$PKG_DIR/tools/" cp -f "$GITHUB_WORKSPACE/tools/gen_insights_package.exe" "$PKG_DIR/tools/" cp -Rf "$GITHUB_WORKSPACE/tools/partitions" "$PKG_DIR/tools/" cp -Rf "$GITHUB_WORKSPACE/tools/ide-debug" "$PKG_DIR/tools/" +cp -f "$GITHUB_WORKSPACE/tools/platformio-build.py" "$PKG_DIR/tools/" # Remove unnecessary files in the package folder echo "Cleaning up folders ..." diff --git a/.github/scripts/set_push_chunks.sh b/.github/scripts/set_push_chunks.sh index 3e3dd89f3ae..11a93a7159d 100644 --- a/.github/scripts/set_push_chunks.sh +++ b/.github/scripts/set_push_chunks.sh @@ -78,5 +78,6 @@ echo "build_all=$build_all" >> $GITHUB_OUTPUT echo "build_libraries=$BUILD_LIBRARIES" >> $GITHUB_OUTPUT echo "build_static_sketches=$BUILD_STATIC_SKETCHES" >> $GITHUB_OUTPUT echo "build_idf=$BUILD_IDF" >> $GITHUB_OUTPUT +echo "build_platformio=$BUILD_PLATFORMIO" >> $GITHUB_OUTPUT echo "chunk_count=$chunks_count" >> $GITHUB_OUTPUT echo "chunks=$chunks" >> $GITHUB_OUTPUT diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 899a0fe7b88..82159e1b8a4 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -61,6 +61,7 @@ jobs: build_libraries: ${{ steps.set-chunks.outputs.build_libraries }} build_static_sketches: ${{ steps.set-chunks.outputs.build_static_sketches }} build_idf: ${{ steps.set-chunks.outputs.build_idf }} + build_platformio: ${{ steps.set-chunks.outputs.build_platformio }} chunk_count: ${{ steps.set-chunks.outputs.chunk_count }} chunks: ${{ steps.set-chunks.outputs.chunks }} steps: @@ -76,9 +77,11 @@ jobs: files_yaml: | core: - '.github/**' + - '!.github/scripts/install-platformio-esp32.sh' - 'cores/**' - 'package/**' - 'tools/**' + - '!tools/platformio-build.py' - 'platform.txt' - 'programmers.txt' - "variants/esp32/**/*" @@ -107,6 +110,10 @@ jobs: - 'Kconfig.projbuild' - 'CMakeLists.txt' - "variants/esp32c2/**/*" + platformio: + - 'package.json' + - '.github/scripts/install-platformio-esp32.sh' + - 'tools/platformio-build.py' - name: Set chunks id: set-chunks @@ -114,6 +121,7 @@ jobs: LIB_FILES: ${{ steps.changed-files.outputs.libraries_all_changed_files }} IS_PR: ${{ github.event_name == 'pull_request' }} MAX_CHUNKS: ${{ env.MAX_CHUNKS }} + BUILD_PLATFORMIO: ${{ steps.changed-files.outputs.platformio_any_changed == 'true' }} BUILD_IDF: ${{ steps.changed-files.outputs.idf_any_changed == 'true' }} BUILD_LIBRARIES: ${{ steps.changed-files.outputs.libraries_any_changed == 'true' }} BUILD_STATIC_SKETCHES: ${{ steps.changed-files.outputs.static_sketeches_any_changed == 'true' }} @@ -204,6 +212,28 @@ jobs: - name: Build Sketches run: bash ./.github/scripts/on-push.sh + # PlatformIO on Windows, Ubuntu and Mac + build-platformio: + name: PlatformIO on ${{ matrix.os }} + needs: gen-chunks + if: | + needs.gen-chunks.outputs.build_all == 'true' || + needs.gen-chunks.outputs.build_static_sketches == 'true' || + needs.gen-chunks.outputs.build_platformio == 'true' + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest, macOS-latest] + + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.x' + - name: Build Sketches + run: bash ./.github/scripts/on-push.sh 1 1 #equal and non-zero to trigger PIO + build-esp-idf-component: name: Build with ESP-IDF ${{ matrix.idf_ver }} for ${{ matrix.idf_target }} needs: gen-chunks diff --git a/platform.txt b/platform.txt index ec1245c9b92..d1c3fb3a3dd 100644 --- a/platform.txt +++ b/platform.txt @@ -47,6 +47,7 @@ compiler.warning_flags.more=-Wall compiler.warning_flags.all=-Wall -Wextra # Additional flags specific to Arduino (not based on IDF flags). +# Update tools/platformio-build.py when changing these flags. compiler.common_werror_flags=-Werror=return-type # Compile Flags diff --git a/tools/platformio-build.py b/tools/platformio-build.py new file mode 100644 index 00000000000..1ece3afddff --- /dev/null +++ b/tools/platformio-build.py @@ -0,0 +1,251 @@ +# Copyright 2014-present PlatformIO <contact@platformio.org> +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +Arduino + +Arduino Wiring-based Framework allows writing cross-platform software to +control devices attached to a wide range of Arduino boards to create all +kinds of creative coding, interactive objects, spaces or physical experiences. + +http://arduino.cc/en/Reference/HomePage +""" + +# Extends: https://github.com/platformio/platform-espressif32/blob/develop/builder/main.py + +from os.path import abspath, basename, isdir, isfile, join +from copy import deepcopy +from SCons.Script import DefaultEnvironment, SConscript + +env = DefaultEnvironment() +platform = env.PioPlatform() +board_config = env.BoardConfig() +build_mcu = board_config.get("build.mcu", "").lower() +partitions_name = board_config.get("build.partitions", board_config.get("build.arduino.partitions", "")) + +FRAMEWORK_DIR = platform.get_package_dir("framework-arduinoespressif32") +FRAMEWORK_LIBS_DIR = platform.get_package_dir("framework-arduinoespressif32-libs") +assert isdir(FRAMEWORK_DIR) + + +# +# Helpers +# + + +def get_partition_table_csv(variants_dir): + fwpartitions_dir = join(FRAMEWORK_DIR, "tools", "partitions") + variant_partitions_dir = join(variants_dir, board_config.get("build.variant", "")) + + if partitions_name: + # A custom partitions file is selected + if isfile(env.subst(join(variant_partitions_dir, partitions_name))): + return join(variant_partitions_dir, partitions_name) + + return abspath( + join(fwpartitions_dir, partitions_name) + if isfile(env.subst(join(fwpartitions_dir, partitions_name))) + else partitions_name + ) + + variant_partitions = join(variant_partitions_dir, "partitions.csv") + return variant_partitions if isfile(env.subst(variant_partitions)) else join(fwpartitions_dir, "default.csv") + + +def get_bootloader_image(variants_dir): + bootloader_image_file = "bootloader.bin" + if partitions_name.endswith("tinyuf2.csv"): + bootloader_image_file = "bootloader-tinyuf2.bin" + + variant_bootloader = join( + variants_dir, + board_config.get("build.variant", ""), + board_config.get("build.arduino.custom_bootloader", bootloader_image_file), + ) + + return ( + variant_bootloader + if isfile(env.subst(variant_bootloader)) + else generate_bootloader_image( + join( + FRAMEWORK_LIBS_DIR, + build_mcu, + "bin", + "bootloader_${__get_board_boot_mode(__env__)}_${__get_board_f_boot(__env__)}.elf", + ) + ) + ) + + +def generate_bootloader_image(bootloader_elf): + bootloader_cmd = env.Command( + join("$BUILD_DIR", "bootloader.bin"), + bootloader_elf, + env.VerboseAction( + " ".join( + [ + '"$PYTHONEXE" "$OBJCOPY"', + "--chip", + build_mcu, + "elf2image", + "--flash_mode", + "${__get_board_flash_mode(__env__)}", + "--flash_freq", + "${__get_board_f_image(__env__)}", + "--flash_size", + board_config.get("upload.flash_size", "4MB"), + "-o", + "$TARGET", + "$SOURCES", + ] + ), + "Building $TARGET", + ), + ) + + env.Depends("$BUILD_DIR/$PROGNAME$PROGSUFFIX", bootloader_cmd) + + # Because the Command always returns a NodeList, we have to + # access the first element in the list to get the Node object + # that actually represents the bootloader image. + # Also, this file is later used in generic Python code, so the + # Node object in converted to a generic string + return str(bootloader_cmd[0]) + + +def add_tinyuf2_extra_image(): + tinuf2_image = board_config.get( + "upload.arduino.tinyuf2_image", + join(variants_dir, board_config.get("build.variant", ""), "tinyuf2.bin"), + ) + + # Add the UF2 image only if it exists and it's not already added + if not isfile(env.subst(tinuf2_image)): + print("Warning! The `%s` UF2 bootloader image doesn't exist" % env.subst(tinuf2_image)) + return + + if any("tinyuf2.bin" == basename(extra_image[1]) for extra_image in env.get("FLASH_EXTRA_IMAGES", [])): + print("Warning! An extra UF2 bootloader image is already added!") + return + + env.Append( + FLASH_EXTRA_IMAGES=[ + ( + board_config.get( + "upload.arduino.uf2_bootloader_offset", + ("0x2d0000" if env.subst("$BOARD").startswith("adafruit") else "0x410000"), + ), + tinuf2_image, + ), + ] + ) + + +# +# Run target-specific script to populate the environment with proper build flags +# + +SConscript( + join( + FRAMEWORK_LIBS_DIR, + build_mcu, + "platformio-build.py", + ) +) + +# +# Additional flags specific to Arduino core (not based on IDF) +# + +env.Append( + CFLAGS=["-Werror=return-type"], + CXXFLAGS=["-Werror=return-type"], +) + +# +# Target: Build Core Library +# + +# Set -DARDUINO_CORE_BUILD only for the core library +corelib_env = env.Clone() +corelib_env.Append(CPPDEFINES=["ARDUINO_CORE_BUILD"]) + +libs = [] + +variants_dir = join(FRAMEWORK_DIR, "variants") + +if "build.variants_dir" in board_config: + variants_dir = join("$PROJECT_DIR", board_config.get("build.variants_dir")) + +if "build.variant" in board_config: + env.Append(CPPPATH=[join(variants_dir, board_config.get("build.variant"))]) + corelib_env.Append(CPPPATH=[join(variants_dir, board_config.get("build.variant"))]) + corelib_env.BuildSources( + join("$BUILD_DIR", "FrameworkArduinoVariant"), + join(variants_dir, board_config.get("build.variant")), + ) + +libs.append( + corelib_env.BuildLibrary( + join("$BUILD_DIR", "FrameworkArduino"), + join(FRAMEWORK_DIR, "cores", board_config.get("build.core")), + ) +) + +env.Prepend(LIBS=libs) + +# +# Process framework extra images +# + +env.Append( + LIBSOURCE_DIRS=[join(FRAMEWORK_DIR, "libraries")], + FLASH_EXTRA_IMAGES=[ + ( + "0x1000" if build_mcu in ("esp32", "esp32s2") else "0x0000", + get_bootloader_image(variants_dir), + ), + ("0x8000", join(env.subst("$BUILD_DIR"), "partitions.bin")), + ("0xe000", join(FRAMEWORK_DIR, "tools", "partitions", "boot_app0.bin")), + ] + + [(offset, join(FRAMEWORK_DIR, img)) for offset, img in board_config.get("upload.arduino.flash_extra_images", [])], +) + +# Add an extra UF2 image if the 'TinyUF2' partition is selected +if partitions_name.endswith("tinyuf2.csv") or board_config.get("upload.arduino.tinyuf2_image", ""): + add_tinyuf2_extra_image() + +# +# Generate partition table +# + +env.Replace(PARTITIONS_TABLE_CSV=get_partition_table_csv(variants_dir)) + +partition_table = env.Command( + join("$BUILD_DIR", "partitions.bin"), + "$PARTITIONS_TABLE_CSV", + env.VerboseAction( + '"$PYTHONEXE" "%s" -q $SOURCE $TARGET' % join(FRAMEWORK_DIR, "tools", "gen_esp32part.py"), + "Generating partitions $TARGET", + ), +) +env.Depends("$BUILD_DIR/$PROGNAME$PROGSUFFIX", partition_table) + +# +# Adjust the `esptoolpy` command in the `ElfToBin` builder with firmware checksum offset +# + +action = deepcopy(env["BUILDERS"]["ElfToBin"].action) +action.cmd_list = env["BUILDERS"]["ElfToBin"].action.cmd_list.replace("-o", "--elf-sha256-offset 0xb0 -o") +env["BUILDERS"]["ElfToBin"].action = action From 47c61465679c3e947ad02dece7a72ca4065d2d77 Mon Sep 17 00:00:00 2001 From: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com> Date: Mon, 2 Dec 2024 18:39:19 -0300 Subject: [PATCH 6/7] fix(template): Fix Issue Report Template --- .github/ISSUE_TEMPLATE/Issue-report.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/Issue-report.yml b/.github/ISSUE_TEMPLATE/Issue-report.yml index d5b756085c7..acbd9a3c29a 100644 --- a/.github/ISSUE_TEMPLATE/Issue-report.yml +++ b/.github/ISSUE_TEMPLATE/Issue-report.yml @@ -75,7 +75,7 @@ body: attributes: label: IDE Name description: What IDE are you using? - placeholder: eg. Arduino IDE, PlatformIO, Sloeber... + placeholder: eg. Arduino IDE, VSCode, Sloeber... validations: required: true - type: input From 723ad19f5c8c0a79b61a9816141a3bb4f4d7f1d3 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci-lite[bot]" <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Date: Tue, 3 Dec 2024 14:00:56 +0000 Subject: [PATCH 7/7] ci(pre-commit): Apply automatic fixes --- .../ESP32/examples/FreeRTOS/Mutex/README.md | 234 ++++++++--------- .../ESP32/examples/FreeRTOS/Queue/README.md | 142 +++++------ .../examples/FreeRTOS/Semaphore/README.md | 154 ++++++------ .../Template/ExampleTemplate/README.md | 238 +++++++++--------- 4 files changed, 384 insertions(+), 384 deletions(-) diff --git a/libraries/ESP32/examples/FreeRTOS/Mutex/README.md b/libraries/ESP32/examples/FreeRTOS/Mutex/README.md index 32c9f027bff..435528bd771 100644 --- a/libraries/ESP32/examples/FreeRTOS/Mutex/README.md +++ b/libraries/ESP32/examples/FreeRTOS/Mutex/README.md @@ -1,117 +1,117 @@ -# Mutex Example - -This example demonstrates the basic usage of FreeRTOS Mutually Exclusive Locks (Mutex) for securing access to shared resources in multi-threading. -Please refer to other examples in this folder to better understand the usage of tasks. -It is also advised to read the documentation on FreeRTOS web pages: -https://www.freertos.org/a00106.html - -This example creates 2 tasks with the same implementation - they write into a shared variable and then read it and check if it is the same as what they have written. -In single-thread programming like on Arduino this is of no concern and will be always ok, however when multi-threading is used the execution of the task is switched by the FreeRTOS and the value can be rewritten from another task before reading again. -The tasks print write and read operation - each in their column for better reading. Task 0 is on the left and Task 1 is on the right. -Watch the writes and read in secure mode when using the mutex (default) as the results are as you would expect them. -Then try to comment the USE_MUTEX and watch again - there will be a lot of mismatches! - -### Theory: -Mutex is a specialized version of Semaphore (please see the Semaphore example for more info). -In essence, the mutex is a variable whose value determines if the mute is taken (locked) or given (unlocked). -When two or more processes access the same resource (variable, peripheral, etc) it might happen, for example, that when one task starts to read a variable and the operating system (FreeRTOS) will schedule the execution of another task -which will write to this variable and when the previous task runs again it will read something different. - -Mutexes and binary semaphores are very similar but have some subtle differences: -Mutexes include a priority inheritance mechanism, whereas binary semaphores do not. -This makes binary semaphores the better choice for implementing synchronization (between tasks or between tasks and an interrupt), and mutexes the better -choice for implementing simple mutual exclusion. -What is priority inheritance? -If a low-priority task holds the Mutex but gets interrupted by a Higher priority task, which -then tries to take the Mutex, the low-priority task will temporarily ‘inherit’ the high priority so a middle-priority task can't block the low-priority task, and thus also block the high priority task. -Semaphores don't have the logic to handle this, in part because Semaphores aren't 'owned' by the task that takes them. - -A mutex can also be recursive - if a task that holds the mutex takes it again, it will succeed, and the mutex will be released -for other tasks only when it is given the same number of times that it was taken. - -You can check the danger by commenting on the definition of USE_MUTEX which will disable the mutex and present the danger of concurrent access. - - -# Supported Targets - -This example supports all ESP32 SoCs. - -## How to Use Example - -Flash and observe the serial output. - -Comment the `USE_MUTEX` definition, save and flash again and observe the behavior of unprotected access to the shared variable. - -* How to install the Arduino IDE: [Install Arduino IDE](https://github.com/espressif/arduino-esp32/tree/master/docs/arduino-ide). - -#### Using Arduino IDE - -To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits). - -* Before Compile/Verify, select the correct board: `Tools -> Board`. -* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. - -## Example Log Output - -The expected output of shared variables protected by mutex demonstrates mutually exclusive access from tasks - they do not interrupt each other and do not rewrite the value before the other task has read it back. - -``` - Task 0 | Task 1 - | Starting - | 0 <- 227 - Starting | - | R: 227 - 227 <- 737 | - R: 737 | - | 737 <- 282 - | R: 282 - 282 <- 267 | -``` - -The output of unprotected access to shared variable - it happens often that a task is interrupted after writing and before reading the other task write a different value - a corruption occurred! - -``` - Task 0 | Task 1 - | Starting - | 0 <- 333 - Starting | - 333 <- 620 | - R: 620 | - 620 <- 244 | - | R: 244 - | Mismatch! - | 244 <- 131 - R: 131 | - Mismatch! | - 131 <- 584 | - | R: 584 - | Mismatch! - | 584 <- 134 - | R: 134 - | 134 <- 554 - R: 554 | - Mismatch! | - 554 <- 313 | -``` - -## Troubleshooting - -***Important: Make sure you are using a good quality USB cable and that you have a reliable power source*** - -## Contribute - -To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) - -If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! - -Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else. - -## Resources - -* Official ESP32 Forum: [Link](https://esp32.com) -* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) -* ESP32 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf) -* ESP32-S2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf) -* ESP32-C3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf) -* ESP32-S3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf) -* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) +# Mutex Example + +This example demonstrates the basic usage of FreeRTOS Mutually Exclusive Locks (Mutex) for securing access to shared resources in multi-threading. +Please refer to other examples in this folder to better understand the usage of tasks. +It is also advised to read the documentation on FreeRTOS web pages: +https://www.freertos.org/a00106.html + +This example creates 2 tasks with the same implementation - they write into a shared variable and then read it and check if it is the same as what they have written. +In single-thread programming like on Arduino this is of no concern and will be always ok, however when multi-threading is used the execution of the task is switched by the FreeRTOS and the value can be rewritten from another task before reading again. +The tasks print write and read operation - each in their column for better reading. Task 0 is on the left and Task 1 is on the right. +Watch the writes and read in secure mode when using the mutex (default) as the results are as you would expect them. +Then try to comment the USE_MUTEX and watch again - there will be a lot of mismatches! + +### Theory: +Mutex is a specialized version of Semaphore (please see the Semaphore example for more info). +In essence, the mutex is a variable whose value determines if the mute is taken (locked) or given (unlocked). +When two or more processes access the same resource (variable, peripheral, etc) it might happen, for example, that when one task starts to read a variable and the operating system (FreeRTOS) will schedule the execution of another task +which will write to this variable and when the previous task runs again it will read something different. + +Mutexes and binary semaphores are very similar but have some subtle differences: +Mutexes include a priority inheritance mechanism, whereas binary semaphores do not. +This makes binary semaphores the better choice for implementing synchronization (between tasks or between tasks and an interrupt), and mutexes the better +choice for implementing simple mutual exclusion. +What is priority inheritance? +If a low-priority task holds the Mutex but gets interrupted by a Higher priority task, which +then tries to take the Mutex, the low-priority task will temporarily ‘inherit’ the high priority so a middle-priority task can't block the low-priority task, and thus also block the high priority task. +Semaphores don't have the logic to handle this, in part because Semaphores aren't 'owned' by the task that takes them. + +A mutex can also be recursive - if a task that holds the mutex takes it again, it will succeed, and the mutex will be released +for other tasks only when it is given the same number of times that it was taken. + +You can check the danger by commenting on the definition of USE_MUTEX which will disable the mutex and present the danger of concurrent access. + + +# Supported Targets + +This example supports all ESP32 SoCs. + +## How to Use Example + +Flash and observe the serial output. + +Comment the `USE_MUTEX` definition, save and flash again and observe the behavior of unprotected access to the shared variable. + +* How to install the Arduino IDE: [Install Arduino IDE](https://github.com/espressif/arduino-esp32/tree/master/docs/arduino-ide). + +#### Using Arduino IDE + +To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits). + +* Before Compile/Verify, select the correct board: `Tools -> Board`. +* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. + +## Example Log Output + +The expected output of shared variables protected by mutex demonstrates mutually exclusive access from tasks - they do not interrupt each other and do not rewrite the value before the other task has read it back. + +``` + Task 0 | Task 1 + | Starting + | 0 <- 227 + Starting | + | R: 227 + 227 <- 737 | + R: 737 | + | 737 <- 282 + | R: 282 + 282 <- 267 | +``` + +The output of unprotected access to shared variable - it happens often that a task is interrupted after writing and before reading the other task write a different value - a corruption occurred! + +``` + Task 0 | Task 1 + | Starting + | 0 <- 333 + Starting | + 333 <- 620 | + R: 620 | + 620 <- 244 | + | R: 244 + | Mismatch! + | 244 <- 131 + R: 131 | + Mismatch! | + 131 <- 584 | + | R: 584 + | Mismatch! + | 584 <- 134 + | R: 134 + | 134 <- 554 + R: 554 | + Mismatch! | + 554 <- 313 | +``` + +## Troubleshooting + +***Important: Make sure you are using a good quality USB cable and that you have a reliable power source*** + +## Contribute + +To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) + +If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! + +Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else. + +## Resources + +* Official ESP32 Forum: [Link](https://esp32.com) +* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) +* ESP32 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf) +* ESP32-S2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf) +* ESP32-C3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf) +* ESP32-S3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf) +* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) diff --git a/libraries/ESP32/examples/FreeRTOS/Queue/README.md b/libraries/ESP32/examples/FreeRTOS/Queue/README.md index b1cc3f3e3ac..e81d6741e2a 100644 --- a/libraries/ESP32/examples/FreeRTOS/Queue/README.md +++ b/libraries/ESP32/examples/FreeRTOS/Queue/README.md @@ -1,71 +1,71 @@ -# Queue Example - -This example demonstrates the basic usage of FreeRTOS Queues which enables tasks to pass data between each other in a secure asynchronous way. -Please refer to other examples in this folder to better understand the usage of tasks. -It is also advised to read the documentation on FreeRTOS web pages: -[https://www.freertos.org/a00106.html](https://www.freertos.org/a00106.html) - -This example reads data received on the serial port (sent by the user) pass it via queue to another task which will send it back on Serial Output. - -### Theory: -A queue is a simple-to-use data structure (in the most basic way) controlled by `xQueueSend` and `xQueueReceive` functions. -Usually, one task writes into the queue and the other task reads from it. -Usage of queues enables the reading task to yield the CPU until there are data in the queue and therefore not waste precious computation time. - -# Supported Targets - -This example supports all ESP32 SoCs. - -## How to Use Example - -Flash and write anything to serial input. - -* How to install the Arduino IDE: [Install Arduino IDE](https://github.com/espressif/arduino-esp32/tree/master/docs/arduino-ide). - -#### Using Arduino IDE - -To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits). - -* Before Compile/Verify, select the correct board: `Tools -> Board`. -* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. - -## Example Log Output - -``` -Anything you write will return as echo. -Maximum line length is 63 characters (+ terminating '0'). -Anything longer will be sent as a separate line. - -``` -< Input text "Short input" - -``Echo line of size 11: "Short input"`` - -< Input text "An example of very long input which is longer than default 63 characters will be split." - -``` -Echo line of size 63: "An example of very long input which is longer than default 63 c" -Echo line of size 24: "haracters will be split." -``` - -## Troubleshooting - -***Important: Make sure you are using a good quality USB cable and that you have a reliable power source*** - -## Contribute - -To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) - -If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! - -Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else. - -## Resources - -* Official ESP32 Forum: [Link](https://esp32.com) -* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) -* ESP32 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf) -* ESP32-S2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf) -* ESP32-C3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf) -* ESP32-S3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf) -* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) +# Queue Example + +This example demonstrates the basic usage of FreeRTOS Queues which enables tasks to pass data between each other in a secure asynchronous way. +Please refer to other examples in this folder to better understand the usage of tasks. +It is also advised to read the documentation on FreeRTOS web pages: +[https://www.freertos.org/a00106.html](https://www.freertos.org/a00106.html) + +This example reads data received on the serial port (sent by the user) pass it via queue to another task which will send it back on Serial Output. + +### Theory: +A queue is a simple-to-use data structure (in the most basic way) controlled by `xQueueSend` and `xQueueReceive` functions. +Usually, one task writes into the queue and the other task reads from it. +Usage of queues enables the reading task to yield the CPU until there are data in the queue and therefore not waste precious computation time. + +# Supported Targets + +This example supports all ESP32 SoCs. + +## How to Use Example + +Flash and write anything to serial input. + +* How to install the Arduino IDE: [Install Arduino IDE](https://github.com/espressif/arduino-esp32/tree/master/docs/arduino-ide). + +#### Using Arduino IDE + +To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits). + +* Before Compile/Verify, select the correct board: `Tools -> Board`. +* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. + +## Example Log Output + +``` +Anything you write will return as echo. +Maximum line length is 63 characters (+ terminating '0'). +Anything longer will be sent as a separate line. + +``` +< Input text "Short input" + +``Echo line of size 11: "Short input"`` + +< Input text "An example of very long input which is longer than default 63 characters will be split." + +``` +Echo line of size 63: "An example of very long input which is longer than default 63 c" +Echo line of size 24: "haracters will be split." +``` + +## Troubleshooting + +***Important: Make sure you are using a good quality USB cable and that you have a reliable power source*** + +## Contribute + +To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) + +If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! + +Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else. + +## Resources + +* Official ESP32 Forum: [Link](https://esp32.com) +* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) +* ESP32 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf) +* ESP32-S2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf) +* ESP32-C3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf) +* ESP32-S3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf) +* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) diff --git a/libraries/ESP32/examples/FreeRTOS/Semaphore/README.md b/libraries/ESP32/examples/FreeRTOS/Semaphore/README.md index 0a076713e14..fcb38eed1d6 100644 --- a/libraries/ESP32/examples/FreeRTOS/Semaphore/README.md +++ b/libraries/ESP32/examples/FreeRTOS/Semaphore/README.md @@ -1,77 +1,77 @@ -# Semaphore Example - -This example demonstrates the basic usage of FreeRTOS Semaphores and queue sets for coordination between tasks for multi-threading. -Please refer to other examples in this folder to better understand the usage of tasks. -It is also advised to read the documentation on FreeRTOS web pages: -[https://www.freertos.org/a00106.html](https://www.freertos.org/a00106.html) - -### Theory: -Semaphore is in essence a variable. Tasks can set the value, wait until one or more -semaphores are set and thus communicate between each other their state. -A binary semaphore is a semaphore that has a maximum count of 1, hence the 'binary' name. -A task can only 'take' the semaphore if it is available, and the semaphore is only available if its count is 1. - -Semaphores can be controlled by any number of tasks. If you use semaphore as a one-way -signalization with only one task giving and only one task taking there is a much faster option -called Task Notifications - please see FreeRTOS documentation and read more about them: [https://www.freertos.org/RTOS-task-notifications.html](https://www.freertos.org/RTOS-task-notifications.html) - -This example uses a semaphore to signal when a package is delivered to a warehouse by multiple -delivery trucks, and multiple workers are waiting to receive the package. - -# Supported Targets - -This example supports all ESP32 SoCs. - -## How to Use Example - -Read the code and try to understand it, then flash and observe the Serial output. - -* How to install the Arduino IDE: [Install Arduino IDE](https://github.com/espressif/arduino-esp32/tree/master/docs/arduino-ide). - -#### Using Arduino IDE - -To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits). - -* Before Compile/Verify, select the correct board: `Tools -> Board`. -* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. - -## Example Log Output - -``` -Anything you write will return as echo. -Maximum line length is 63 characters (+ terminating '0'). -Anything longer will be sent as a separate line. - -``` -< Input text "Short input" - -``Echo line of size 11: "Short input"`` - -< Input text "An example of very long input which is longer than default 63 characters will be split." - -``` -Echo line of size 63: "An example of very long input which is longer than default 63 c" -Echo line of size 24: "haracters will be split." -``` - -## Troubleshooting - -***Important: Make sure you are using a good quality USB cable and that you have a reliable power source*** - -## Contribute - -To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) - -If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! - -Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else. - -## Resources - -* Official ESP32 Forum: [Link](https://esp32.com) -* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) -* ESP32 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf) -* ESP32-S2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf) -* ESP32-C3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf) -* ESP32-S3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf) -* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) +# Semaphore Example + +This example demonstrates the basic usage of FreeRTOS Semaphores and queue sets for coordination between tasks for multi-threading. +Please refer to other examples in this folder to better understand the usage of tasks. +It is also advised to read the documentation on FreeRTOS web pages: +[https://www.freertos.org/a00106.html](https://www.freertos.org/a00106.html) + +### Theory: +Semaphore is in essence a variable. Tasks can set the value, wait until one or more +semaphores are set and thus communicate between each other their state. +A binary semaphore is a semaphore that has a maximum count of 1, hence the 'binary' name. +A task can only 'take' the semaphore if it is available, and the semaphore is only available if its count is 1. + +Semaphores can be controlled by any number of tasks. If you use semaphore as a one-way +signalization with only one task giving and only one task taking there is a much faster option +called Task Notifications - please see FreeRTOS documentation and read more about them: [https://www.freertos.org/RTOS-task-notifications.html](https://www.freertos.org/RTOS-task-notifications.html) + +This example uses a semaphore to signal when a package is delivered to a warehouse by multiple +delivery trucks, and multiple workers are waiting to receive the package. + +# Supported Targets + +This example supports all ESP32 SoCs. + +## How to Use Example + +Read the code and try to understand it, then flash and observe the Serial output. + +* How to install the Arduino IDE: [Install Arduino IDE](https://github.com/espressif/arduino-esp32/tree/master/docs/arduino-ide). + +#### Using Arduino IDE + +To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits). + +* Before Compile/Verify, select the correct board: `Tools -> Board`. +* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. + +## Example Log Output + +``` +Anything you write will return as echo. +Maximum line length is 63 characters (+ terminating '0'). +Anything longer will be sent as a separate line. + +``` +< Input text "Short input" + +``Echo line of size 11: "Short input"`` + +< Input text "An example of very long input which is longer than default 63 characters will be split." + +``` +Echo line of size 63: "An example of very long input which is longer than default 63 c" +Echo line of size 24: "haracters will be split." +``` + +## Troubleshooting + +***Important: Make sure you are using a good quality USB cable and that you have a reliable power source*** + +## Contribute + +To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) + +If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! + +Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else. + +## Resources + +* Official ESP32 Forum: [Link](https://esp32.com) +* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) +* ESP32 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf) +* ESP32-S2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf) +* ESP32-C3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf) +* ESP32-S3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf) +* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) diff --git a/libraries/ESP32/examples/Template/ExampleTemplate/README.md b/libraries/ESP32/examples/Template/ExampleTemplate/README.md index 4c4f497f43c..91b50967e9e 100644 --- a/libraries/ESP32/examples/Template/ExampleTemplate/README.md +++ b/libraries/ESP32/examples/Template/ExampleTemplate/README.md @@ -1,119 +1,119 @@ -# Arduino-ESP32 Example/Library Name ==(REQUIRED)== - -==*Add a brief description of this example/library here!*== - -This example/library demonstrates how to create a new example README file. - -# Supported Targets ==(REQUIRED)== - -==*Add the supported devices here!*== - -Currently, this example supports the following targets. - -| Supported Targets | ESP32 | ESP32-S2 | ESP32-C3 | -| ----------------- | ----- | -------- | -------- | - -## How to Use Example/Library ==(OPTIONAL)== - -==*Add a brief description of how to use this example.*== - -* How to install the Arduino IDE: [Install Arduino IDE](https://github.com/espressif/arduino-esp32/tree/master/docs/arduino-ide). - -### Hardware Connection ==(OPTIONAL)== - -==*Add a brief description of wiring or any other hardware-specific connection.*== - -To use this example, you need to connect the LED to the `GPIOx`. - -SDCard GPIO connection scheme: - -| SDCard Pin | Function | GPIO | -| ----------- | -------- | ------ | -| 1 | CS | GPIO5 | -| 2 | DI/MOSI | GPIO23 | -| 3 | VSS/GND | GND | -| 4 | VDD/3V3 | 3V3 | -| 5 | SCLK | GPIO18 | -| 6 | VSS/GND | GND | -| 7 | DO/MISO | GPIO19 | - -To add images, please create a folder `_asset` inside the example folder to add the relevant images. - -### Configure the Project ==(OPTIONAL)== - -==*Add a brief description of this example here!*== - -Set the LED GPIO by changing the `LED_BUILTIN` value in the function `pinMode(LED_BUILTIN, OUTPUT);`. By default, the GPIO is: `GPIOx`. - -#### Example for the GPIO4: - -==*Add some code explanation if relevant to the example.*== - -```cpp -// the setup function runs once when you press reset or power the board -void setup() { -// initialize digital pin 4 as an output. -pinMode(4, OUTPUT); -} -``` - -#### Using Arduino IDE - -To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits). - -* Before Compile/Verify, select the correct board: `Tools -> Board`. -* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. - -## Example/Log Output ==(OPTIONAL)== - -==*Add the log/serial output here!*== - -``` -ets Jul 29 2019 12:21:46 - -rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) -configsip: 0, SPIWP:0xee -clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 -mode:DIO, clock div:1 -load:0x3fff0030,len:1412 -load:0x40078000,len:13400 -load:0x40080400,len:3672 -entry 0x400805f8 -ESP32 Chip model = ESP32-D0WDQ5 Rev 3 -This chip has 2 cores -Chip ID: 3957392 -``` - -## Troubleshooting ==(REQUIRED)== - -==*Add specific issues you may find by using this example here!*== - -***Important: Make sure you are using a good quality USB cable and that you have a reliable power source*** - -* **LED not blinking:** Check the wiring connection and the IO selection. -* **Programming Fail:** If the programming/flash procedure fails, try reducing the serial connection speed. -* **COM port not detected:** Check the USB cable and the USB to Serial driver installation. - -If the error persists, you can ask for help at the official [ESP32 forum](https://esp32.com) or see [Contribute](#contribute). - -## Contribute ==(REQUIRED)== - -==*Do not change! Keep it as is.*== - -To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) - -If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! - -Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else. - -## Resources ==(REQUIRED)== - -==*Do not change here! Keep it as is or add only relevant documents/info for this example. Do not add any purchase link/marketing stuff*== - -* Official ESP32 Forum: [Link](https://esp32.com) -* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) -* ESP32 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf) -* ESP32-S2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf) -* ESP32-C3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf) -* ESP32-S3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf) -* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) +# Arduino-ESP32 Example/Library Name ==(REQUIRED)== + +==*Add a brief description of this example/library here!*== + +This example/library demonstrates how to create a new example README file. + +# Supported Targets ==(REQUIRED)== + +==*Add the supported devices here!*== + +Currently, this example supports the following targets. + +| Supported Targets | ESP32 | ESP32-S2 | ESP32-C3 | +| ----------------- | ----- | -------- | -------- | + +## How to Use Example/Library ==(OPTIONAL)== + +==*Add a brief description of how to use this example.*== + +* How to install the Arduino IDE: [Install Arduino IDE](https://github.com/espressif/arduino-esp32/tree/master/docs/arduino-ide). + +### Hardware Connection ==(OPTIONAL)== + +==*Add a brief description of wiring or any other hardware-specific connection.*== + +To use this example, you need to connect the LED to the `GPIOx`. + +SDCard GPIO connection scheme: + +| SDCard Pin | Function | GPIO | +| ----------- | -------- | ------ | +| 1 | CS | GPIO5 | +| 2 | DI/MOSI | GPIO23 | +| 3 | VSS/GND | GND | +| 4 | VDD/3V3 | 3V3 | +| 5 | SCLK | GPIO18 | +| 6 | VSS/GND | GND | +| 7 | DO/MISO | GPIO19 | + +To add images, please create a folder `_asset` inside the example folder to add the relevant images. + +### Configure the Project ==(OPTIONAL)== + +==*Add a brief description of this example here!*== + +Set the LED GPIO by changing the `LED_BUILTIN` value in the function `pinMode(LED_BUILTIN, OUTPUT);`. By default, the GPIO is: `GPIOx`. + +#### Example for the GPIO4: + +==*Add some code explanation if relevant to the example.*== + +```cpp +// the setup function runs once when you press reset or power the board +void setup() { +// initialize digital pin 4 as an output. +pinMode(4, OUTPUT); +} +``` + +#### Using Arduino IDE + +To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits). + +* Before Compile/Verify, select the correct board: `Tools -> Board`. +* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. + +## Example/Log Output ==(OPTIONAL)== + +==*Add the log/serial output here!*== + +``` +ets Jul 29 2019 12:21:46 + +rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) +configsip: 0, SPIWP:0xee +clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 +mode:DIO, clock div:1 +load:0x3fff0030,len:1412 +load:0x40078000,len:13400 +load:0x40080400,len:3672 +entry 0x400805f8 +ESP32 Chip model = ESP32-D0WDQ5 Rev 3 +This chip has 2 cores +Chip ID: 3957392 +``` + +## Troubleshooting ==(REQUIRED)== + +==*Add specific issues you may find by using this example here!*== + +***Important: Make sure you are using a good quality USB cable and that you have a reliable power source*** + +* **LED not blinking:** Check the wiring connection and the IO selection. +* **Programming Fail:** If the programming/flash procedure fails, try reducing the serial connection speed. +* **COM port not detected:** Check the USB cable and the USB to Serial driver installation. + +If the error persists, you can ask for help at the official [ESP32 forum](https://esp32.com) or see [Contribute](#contribute). + +## Contribute ==(REQUIRED)== + +==*Do not change! Keep it as is.*== + +To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) + +If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! + +Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else. + +## Resources ==(REQUIRED)== + +==*Do not change here! Keep it as is or add only relevant documents/info for this example. Do not add any purchase link/marketing stuff*== + +* Official ESP32 Forum: [Link](https://esp32.com) +* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) +* ESP32 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf) +* ESP32-S2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf) +* ESP32-C3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf) +* ESP32-S3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf) +* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com)