#define __STM32__
//#define __ESP32__
//#define __ESP8266__
#include <Arduino.h>
#include <STM32TimerInterrupt.h>
#include "TimerInterrupt_Generic.h"
// INCLUDES FOR AVR BOARDS using Library "FreeRTOS" by Richard Barry
#if defined(__AVR__)
#include <Arduino_FreeRTOS.h>
#include <semphr.h> // add the FreeRTOS functions for Semaphores (or Flags).
typedef void * xTaskHandle;
#endif
// INCLUDES FOR STM32 BOARDS using Library "STM32duino FreeRTOS" by STM32duino
#if defined(__STM32__)
#include <STM32FreeRTOS.h>
#endif
// INCLUDES FOR ESPRESSIF BOARDS (ESP32). DO NOT NEED ANY FreeRTOS LIBRARY but needs to include
// <esp_task_wdt.h> to disable teh WATCHDOG timer
#if defined(__ESP32__)
#include <esp_task_wdt.h>
#endif
// If no default pin for user button (USER_BTN) is defined, define it
#ifndef USER_BTN
#define USER_BTN 2
#endif
// Set LED_BUILTIN if it is not defined by Arduino framework
// #define LED_BUILTIN 13
uint8_t pushButton = USER_BTN;
// Declare a mutex Semaphore Handle which we will use to manage the Serial Port.
// It will be used to ensure only only one Task is accessing this resource at any time.
SemaphoreHandle_t xSerialSemaphore;
xTaskHandle xTask1Handle, xTask2Handle, xTaskPriorityHandle;
int PriorityTask1,PriorityTask2;
// define two Tasks for DigitalRead & AnalogRead
void Task1( void *pvParameters );
void Task2( void *pvParameters );
void TaskPriority( void *pvParameters );
// definir la función de interrupción para la pulsación del botón en el setup() APARTADO 5.3.1
bool button_pressed_setup_switch = true;
void button_pressed_setup() {
button_pressed_setup_switch = false;
Serial.print("\nEl botón ha sido pulsado");
Serial.print("\nA continuación se crearán las tareas.");
detachInterrupt(digitalPinToInterrupt(USER_BTN));
return;
}
void bucle() {
while (button_pressed_setup_switch) {
Serial.print("Por favor, presione el botón.\n");
delay(10);
if (digitalRead(pushButton) == HIGH ) {
return;
}
}
}
//Declaración de variables tipo BaseType_t para comprobar el estatus de las tareas.
BaseType_t task1Status,task2Status,task3Status;
BaseType_t taskarr[3] = {task1Status, task2Status, task3Status };
// the setup function runs once when you press reset or power the board
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB, on LEONARDO, MICRO, YUN, and other 32u4 based boards.
}
// Semaphores are useful to stop a Task proceeding, where it should be paused to wait,
// because it is sharing a resource, such as the Serial port.
// Semaphores should only be used whilst the scheduler is running, but we can set it up here.
if ( xSerialSemaphore == NULL ) // Check to confirm that the Serial Semaphore has not already been created.
{
xSerialSemaphore = xSemaphoreCreateMutex(); // Create a mutex semaphore we will use to manage the Serial Port
if ( ( xSerialSemaphore ) != NULL )
xSemaphoreGive( ( xSerialSemaphore ) ); // Make the Serial Port available for use, by "Giving" the Semaphore.
}
// make the pushbutton's pin an input:
pinMode(pushButton, INPUT_PULLUP);
attachInterrupt(pushButton,button_pressed_setup,CHANGE);
//BUCLE WHILE que se asegura que el programa no siga hasta que el usuario pulse el botón.
bucle();
// Now set up three Tasks to run independently.
task1Status = xTaskCreate(
TaskPriority
, "TaskPriority"
, 1000 // Stack size
, NULL
, 3 // Priority
, &xTaskPriorityHandle);
task2Status = xTaskCreate(
Task1
, "Task1" // A name just for humans
, 1000 // This stack size can be checked & adjusted by reading the Stack Highwater
, NULL
, 1 // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
, &xTask1Handle);
task3Status = xTaskCreate(
Task2
, "Task2"
, 1000 // Stack size
, NULL
, 2 // Priority
, &xTask2Handle);
for (int i = 0; i < 3; i++) {
if (taskarr[i] != pdPASS) {
Serial.printf("\nLa tarea", i, " no se ha inicializado correctamente");
continue;
}
Serial.printf("\nLa tarea", i, "se ha inicializado correctamente.");
}
// start scheduler
#if !defined(__ESP32__)
vTaskStartScheduler(); // THIS LINE MUST BE COMMENTED FOR ESPRESSIF BOARDS. THEY ALLREADY CALL THIS FUNCTION INTERNALLY
#endif
}
void loop()
{
// Idle task.
}
//--------------------------------------------------
//---------------------- Tasks ---------------------
//--------------------------------------------------
void TaskPriority( void *pvParameters __attribute__((unused)) ) // This is a Task.
{
#if defined(__ESP32__)
esp_task_wdt_init(30, false); // Disable the HW watchdog for 30 seconds, only for ESPRESSIF BOARDS (ESP32)
#endif
for (;;) // A Task shall never return or exit.
{
// read the input pin:
int buttonState = digitalRead(pushButton);
if (buttonState==1){
PriorityTask1 = 1;
PriorityTask2 = 2;
} else {
PriorityTask1 = 2;
PriorityTask2 = 1;
}
vTaskPrioritySet(xTask1Handle, PriorityTask1);
vTaskPrioritySet(xTask2Handle, PriorityTask2);
vTaskDelay(1000); // one tick delay == 1ms
}
}
void Task1(void* pvParameters __attribute__((unused))) // This is a Task.
{
int i;
#if defined(__ESP32__)
esp_task_wdt_init(30, false); // Disable the HW watchdog for 30 seconds, only for ESPRESSIF BOARDS (ESP32)
#endif
for (;;)
{
// See if we can obtain or "Take" the Serial Semaphore.
// If the semaphore is not available, wait 500 ticks of the Scheduler to see if it becomes free.
//if ( xSemaphoreTake( xSerialSemaphore, ( TickType_t ) 500 ) == pdTRUE )
{
// We were able to obtain or "Take" the semaphore and can now access the shared resource.
// We want to have the Serial Port for us alone, as it takes some time to print,
// so we don't want it getting stolen during the middle of a conversion.
// print out the value you read:
Serial.print("{");
for (i = 0; i < 150; i++) {
Serial.print("_");
}
Serial.print("T1: "); Serial.print(PriorityTask1);
Serial.print(" T2: "); Serial.print(PriorityTask2);
Serial.println("}");
//xSemaphoreGive( xSerialSemaphore ); // Now free or "Give" the Serial Port for others.
}
//vTaskDelay(15); // 15 ticks delay (15ms) in between reads for stability
}
}
void Task2( void *pvParameters __attribute__((unused)) ) // This is a Task.
{
// Task1: Higher priority (initially)
int i;
#if defined(__ESP32__)
esp_task_wdt_init(30, false); // Disable the HW watchdog for 30 seconds, only for ESPRESSIF BOARDS (ESP32)
#endif
for (;;) // A Task shall never return or exit.
{
// See if we can obtain or "Take" the Serial Semaphore.
// If the semaphore is not available, wait 500 ticks of the Scheduler to see if it becomes free.
//if ( xSemaphoreTake( xSerialSemaphore, ( TickType_t ) 500 ) == pdTRUE )
{
// We were able to obtain or "Take" the semaphore and can now access the shared resource.
// We want to have the Serial Port for us alone, as it takes some time to print,
// so we don't want it getting stolen during the middle of a conversion.
// print out the state of the button:
Serial.print("[");
for (i=0;i<2;i++){
Serial.print("1");
}
Serial.print("]");
//xSemaphoreGive( xSerialSemaphore ); // Now free or "Give" the Serial Port for others.
}
vTaskDelay(15); // 15 ticks delay (15ms) in between reads for stability
}
}