Back to TILs

Esp32 with FreeRTOS using Arduino - Preferences

C FreeRTOS Arduino xTaskCreatePinnedToCore

Table of contents

File FreeRTOS_Esp32_preferences.ino


#include <Preferences.h>

// Define the onboard LED pin for ESP32 (typically GPIO 2)
#define LED_PIN 2

// https://randomnerdtutorials.com/esp32-save-data-permanently-preferences/
// https://forum.arduino.cc/t/esp32-getting-to-the-core-of-the-task/1161303
// https://docs.espressif.com/projects/esp-idf/en/v4.3/esp32/api-reference/system/freertos.html
// freertos/include/freertos/task.h
//
// BaseType_t xTaskCreatePinnedToCore(
//    TaskFunction_t   pvTaskCode,
//    const char *     constpcName,
//    const uint32_t   usStackDepth,
//    void *           constpvParameters,
//    UBaseType_t      uxPriority,
//    TaskHandle_t *   constpvCreatedTask,
//    const BaseType_t xCoreID
// )

// Task handle
TaskHandle_t ledTaskHandle = NULL;

struct TaskParams {
  unsigned int led_on_time  = 50;
  unsigned int led_off_time = 50;
};

// ----------------------------------------------------------------------
//
// ----------------------------------------------------------------------
void ledTask(void *pvParameters) {
  TaskParams *taskParams = (TaskParams *)(pvParameters);

  Serial.printf("ledTask: %d - %d\n\r", taskParams->led_on_time, taskParams->led_off_time);

  // 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 - %d\n\r", core, taskParams->led_on_time);
    vTaskDelay(taskParams->led_on_time / portTICK_PERIOD_MS);

    digitalWrite(LED_PIN, LOW);
    Serial.printf("LED OFF - Running on core %d - %d\n\r", core, taskParams->led_off_time);
    vTaskDelay(taskParams->led_off_time / portTICK_PERIOD_MS);
  }
}

// ----------------------------------------------------------------------
//
// ----------------------------------------------------------------------
void setup() {
  // Initialize serial communication
  Serial.begin(115200);

  Preferences preferences;

  // false - read and write
  // true  - read only
  preferences.begin("my-namespace", false);

  TaskParams taskParams{0, 0};

  // Get the value, if the key does not exist, return a default value of 0
  // Note: Key name is limited to 15 chars.
  taskParams.led_on_time = preferences.getUInt("led_on_time", 0);

  if (taskParams.led_on_time >= 800) {
    taskParams.led_on_time = 0;
  }

  taskParams.led_on_time += 200;
  taskParams.led_off_time = 1000 - taskParams.led_on_time;
  preferences.putUInt("led_on_time", taskParams.led_on_time);
  preferences.putUInt("led_off_time", taskParams.led_off_time);
  preferences.end();

  Serial.printf("Setup: %d - %d\n\r", taskParams.led_on_time, taskParams.led_off_time);

  delay(1000);

  // 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  = &taskParams;
  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)
  );

  // Wait 10 seconds
  Serial.println("Restarting in 10 seconds...");
  delay(10000);

  // Restart ESP
  ESP.restart();
}

// ----------------------------------------------------------------------
//
// ----------------------------------------------------------------------
void loop() {}

Compiling the project

# BOARD?=esp32:esp32:uPesy_wroom
BOARD?= esp32:esp32:esp32da
PORT?= /dev/ttyUSB0
BAUD?= 115200
PROJECT_NAME?=FreeRTOS_Esp32_blink

all:
	$(Q)echo "Compiling $(PROJECT_NAME)..."
	$(Q)mkdir -p out
	$(Q)arduino-cli compile \
		--clean \
		--fqbn $(BOARD) \
		--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)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 upgrade

Upload binary to the board

.PHONY: upload
upload:
	$(Q)arduino-cli upload \
		$(shell pwd) \
		--input-dir out/ \
		--port $(PORT) \
		--fqbn $(BOARD) \
		--verbose \
		--verify

Open serial monitor in another terminal

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