Back to TILs

Esp32 with FreeRTOS using Arduino - Blink

C FreeRTOS Arduino xTaskCreatePinnedToCore

Table of contents

File FreeRTOS_Esp32_blink.ino

// Define the onboard LED pin for ESP32 (typically GPIO 2)
#define LED_PIN 2
// Task handle
TaskHandle_t ledTaskHandle = NULL;
void ledTask(void *pvParameters) {
  // Retrieve the core number the task is running on
  int core = xPortGetCoreID();

  for (;;) {
    // Toggle the LED
    digitalWrite(LED_PIN, HIGH);
    Serial.printf("LED ON  - Running on core %d\n\r", core);
    vTaskDelay(100 / portTICK_PERIOD_MS);

    digitalWrite(LED_PIN, LOW);
    Serial.printf("LED OFF - Running on core %d\n\r", core);
    vTaskDelay(900 / portTICK_PERIOD_MS);
  }
}
void setup() {
  // Initialize serial communication
  Serial.begin(115200);

  // Initialize the onboard LED pin
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);

  TaskFunction_t   pvTaskCode         = ledTask;
  const char      *constpcName        = "LED Task";
  const uint32_t   usStackDepth       = 2048;
  void            *constpvParameters  = NULL;
  UBaseType_t      uxPriority         = 1;
  TaskHandle_t    *constpvCreatedTask = &ledTaskHandle;
  const BaseType_t xCoreID            = 1;

  // Create the LED task
  xTaskCreatePinnedToCore(pvTaskCode,         // Task function
                          constpcName,        // Task name
                          usStackDepth,       // Stack size
                          constpvParameters,  // Task parameters
                          uxPriority,         // Task priority
                          constpvCreatedTask, // Task handle
                          xCoreID             // Core number to run the task on (0 or 1)
  );
}
void loop() {
  // See p.43 of FreeRTOS for ESP32-Arduino
  // Delete self (main task)
  vTaskDelete(nullptr);
}

Compiling the project

# ESP32-WROOM-DA Module                              esp32:esp32:esp32da
# ESP32S3 Dev Module Octal (WROOM2)                  esp32:esp32:esp32s3-octal
# Fri3d Badge 2024 (ESP32-S3-WROOM-1)                esp32:esp32:fri3d_2024_esp32s3
# uPesy ESP32 Wroom DevKit                           esp32:esp32:uPesy_wroom

# LilyGo T-Display                                   esp32:esp32:lilygo_t_display
# LilyGo T-Display-S3                                esp32:esp32:lilygo_t_display_s3
# LilyGo T-ETH-Lite                                  esp32:esp32:lilygo_t_eth_lite
# LilyGo T-Watch-S3                                  esp32:esp32:twatchs3
# LilyGo T-Watch-Ultra                               esp32:esp32:twatch_ultra
# LilyGo T3-S3                                       esp32:esp32:lilygo_t3s3
# LilyGo-T-LoRa-Pager                                esp32:esp32:tlora_pager

BOARD?= esp32:esp32:esp32da
PORT?= /dev/ttyUSB0
BAUD?= 115200
PROJECT_NAME?= FreeRTOS_Esp32_blink
FILE_SYSTEM?=spiffs
# littlefs or spiffs

UPLOAD_SPEED?=921600
FLASH_SIZE?=4M
CPU_FREQ?=240
#PARTITION_SCHEME?= app3M_fat9M_16MB
PARTITION_SCHEME?= default
# VERBOSE?= --verbose
CLEAN?= --clean

BOARD_OPTIONS=FlashMode=qio,PartitionScheme=$(PARTITION_SCHEME),FlashSize=$(FLASH_SIZE),CPUFreq=$(CPU_FREQ)

# --board-options FlashMode=qio,FlashSize=16M,LoopCore=1,EventsCore=1,USBMode=hwcdc,CDCOnBoot=default,MSCOnBoot=default,DFUOnBoot=default,UploadMode=default,PartitionScheme=default_8MB,CPUFreq=240,UploadSpeed=921600,DebugLevel=none,EraseFlash=none

# board            := "esp32:esp32:esp32s3"
# monitor_speed    := "115200"
# flash_size       := "16M"
# cpu_freq         := "240"
# partition_scheme := "app3M_fat9M_16MB"

# Master Custom ESP32 Partitions in the Arduino IDE!
# https://youtu.be/EuHxodrye6E
# https://thelastoutpostworkshop.github.io/microcontroller_devkit/esp32partitionbuilder/

# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/min_spiffs.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/app3M_fat9M_16MB.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/app3M_fat9M_fact512k_16MB.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/app3M_spiffs9M_fact512k_16MB.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/bare_minimum_2MB.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/boot_app0.bin
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/default_16MB.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/default_32MB.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/default_8MB.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/default.bin
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/default.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/default_ffat_8MB.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/default_ffat.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/esp_sr_16.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/ffat.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/huge_app.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/large_fat_32MB.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/large_ffat_8MB.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/large_littlefs_32MB.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/large_spiffs_16MB.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/large_spiffs_8MB.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/m5stack_partitions_16MB_factory_4_apps.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/m5stack_partitions_16MB_factory_6_apps.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/max_app_4MB.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/max_app_8MB.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/minimal.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/min_spiffs.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/no_fs.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/noota_3g.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/noota_3gffat.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/no_ota.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/noota_ffat.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/ota_nofs_4MB.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/rainmaker_4MB_no_ota.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/rainmaker_8MB.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/rainmaker.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/tinyuf2-partitions-16MB.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/tinyuf2-partitions-16MB-noota.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/tinyuf2-partitions-4MB.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/tinyuf2-partitions-4MB-noota.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/tinyuf2-partitions-8MB.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/tinyuf2-partitions-8MB-noota.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/zigbee_2MB.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/zigbee_8MB.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/zigbee.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/zigbee_zczr_2MB.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/zigbee_zczr_8MB.csv
# /home/geraldo/.arduino15/packages/esp32/hardware/esp32/3.2.0/tools/partitions/zigbee_zczr.csv

#partitioncmd := --build-property build.partitions=${PARTITIONTYPE} --build-property upload.maximum_size=${PARTITIONMAX}

# There are a few advantages of using LittleFS over SPIFFS:
#
# LittleFS is optimized for low resource usage and it employs a wear-leveling algorithm that evenly distributes writes across the flash memory, prolonging its lifespan.
# LittleFS provides faster mount times and file access by utilizing a directory indexing structure.
# LittleFS minimizes the risk of data corruption during power loss or system failures.
# LittleFS is under active development.

all:
	$(Q)echo "Compiling $(PROJECT_NAME)..."
	$(Q)mkdir -p out
	$(Q)arduino-cli compile \
		$(VERBOSE) \
		$(CLEAN) \
		--fqbn $(BOARD) \
		--board-options "$(BOARD_OPTIONS)" \
		--output-dir out \
		$(PROJECT_NAME).ino
	$(MAKE) til
	$(MAKE) til_copy


clean:
	$(RM) -r out
	$(RM) -r til

Update config, toolchain, libraries

.PHONY: update
update:
	$(Q)echo create config at /home/geraldo/.arduino15/arduino-cli.yaml
	$(Q)arduino-cli config init || echo Config file already exists
	$(Q)arduino-cli config set network.connection_timeout 600s
	$(Q)arduino-cli config add board_manager.additional_urls https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
	$(Q)cat /home/geraldo/.arduino15/arduino-cli.yaml
	$(Q)arduino-cli core update-index
	$(Q)arduino-cli core install arduino:avr
	$(Q)arduino-cli core install esp32:esp32
	$(Q)arduino-cli lib uninstall AsyncTCP             # 1.1.4
	$(Q)arduino-cli lib uninstall ESPAsyncTCP          # 
	$(Q)arduino-cli lib uninstall ESPAsyncWebServer    # ESPAsyncWebServer@3.1.0
	$(Q)arduino-cli lib install LittleFS_esp32
	$(Q)arduino-cli lib install "ESP Async TCP"        # 2.0.0
	$(Q)arduino-cli lib install "Async TCP"            # 3.4.4
	$(Q)arduino-cli lib install "ESP Async WebServer"  # ESP Async WebServer@3.7.8
	$(Q)arduino-cli lib install "ESP32 LittleFS"
	$(Q)arduino-cli upgrade

Upload binary to the board

.PHONY: upload
upload:
	$(Q)arduino-cli upload \
		$(VERBOSE) \
		$(shell pwd) \
		--input-dir out/ \
		--port $(PORT) \
		--fqbn $(BOARD) \
		--board-options "$(BOARD_OPTIONS)" \
		--verify

Upload binary to the board

.PHONY: upload_with_data
upload_with_data:
	$(Q)arduino-cli upload \
		$(VERBOSE) \
		"$(shell pwd)","$(FILE_SYSTEM)" \
		--input-dir out/ \
		--port $(PORT) \
		--fqbn $(BOARD) \
		--board-options "$(BOARD_OPTIONS)" \
		--verify

Open serial monitor in another terminal

.PHONY: serial
serial10:
	$(Q)xfce4-terminal -x picocom $(PORT) \
		--baud $(BAUD) \
		--echo \
		--exit-after 10000

serial:
	$(Q)xfce4-terminal -x picocom $(PORT) \
		--baud $(BAUD) \
		--echo \