PRÁCTICA 4 SADQ
unknown
c_cpp
2 years ago
8.0 kB
1
Indexable
Never
#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)); } //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(USER_BTN,button_pressed_setup,CHANGE); //BUCLE WHILE que se asegura que el programa no siga hasta que el usuario pulse el botón. while (button_pressed_setup_switch) { Serial.print("Por favor, presione el botón.\n"); delay(10); } // 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 } }