Documentos de Académico
Documentos de Profesional
Documentos de Cultura
01101010011001010110000101101110
PRACTICA 11
FreeRTOS
1
Sistemas Embebidos
011000010111001101100001011011100111101001100001
Lista de Software:
Objetivos
01101010011001010110000101101110
• Familiarización con Sistema operativo FreeRTOS.
Arduino
2
Sistemas Embebidos
011000010111001101100001011011100111101001100001
FreeRTOS
01101010011001010110000101101110
https://www.freertos.org/RTOS.html 3
Sistemas Embebidos
011000010111001101100001011011100111101001100001
Structure of FreeRTOS
01101010011001010110000101101110
4
Sistemas Embebidos
011000010111001101100001011011100111101001100001
FreeRTOS
Tipos de multitareas
01101010011001010110000101101110
Cooperativa: da el control a un proceso y este es el que cede de nuevo el
control cuando decide voluntariamente que no puede seguir su ejecución,
pasando a esta en espera. Al depender del propio proceso en ejecución puede
ser problemático, ya que, si el proceso de usuario se interrumpe y no cede la
CPU al sistema operativo, todo el sistema quedará bloqueado, es decir, sin
poder hacer nada.
Apropiativa o preventiva: el sistema operativo es el encargado de administrar
el o los procesadores repartiendo el tiempo de uso entre los procesos que
estén esperando para utilizarlo. Cada proceso utiliza el procesador durante
lapsos cortos, pero el resultado final es virtualmente igual a ejecutarse todo al
mismo tiempo.
Real: solo se da en sistemas con multiprocesador; varios procesos se ejecutan
realmente al mismo tiempo en distintos microprocesadores, suele ser también
preferente.
https://www.freertos.org/RTOS.html 5
Sistemas Embebidos
011000010111001101100001011011100111101001100001
Free RTOS en Arduino
01101010011001010110000101101110
6
Sistemas Embebidos
011000010111001101100001011011100111101001100001
Free RTOS en Arduino
01101010011001010110000101101110
7
Sistemas Embebidos
011000010111001101100001011011100111101001100001
Free RTOS en Arduino
01101010011001010110000101101110
8
Sistemas Embebidos
011000010111001101100001011011100111101001100001
Proteus
01101010011001010110000101101110
9
Sistemas Embebidos
011000010111001101100001011011100111101001100001
Ejemplo 1
void setup() {
01101010011001010110000101101110
Serial.begin(9600);
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
led();
enviar();
}
* Expectativa del código:
* Parpadear un led cada segundo void led(){
* Simular el envío del estado del led a una plataforma digitalWrite(LED_BUILTIN, HIGH);
IOT en la nube cada 500 ms, delay(1000);
* se esparía recibir al menos 1 estado en alto y 1 en digitalWrite(LED_BUILTIN, LOW);
bajo delay(1000);
}
void enviar(){
String estado = (digitalRead(LED_BUILTIN))?"Encendido":"Apagado ";
int delay_ms = random(1000,5000);
Serial.print("Enviando");
for(int i = 0; i<3; i++){
delay(delay_ms/3);
Serial.print('.');
}
Serial.println();
Serial.print("Estado del led: " + estado);
Serial.println("\tRetardo: " + String((float)delay_ms/1000,3) + " seg\r\n");
delay(500);
}
10
Sistemas Embebidos
011000010111001101100001011011100111101001100001
Ejemplo 2
#include <Arduino_FreeRTOS.h>
01101010011001010110000101101110
void led( void *pvParameters );
void enviar( void *pvParameters );
void setup() {
//int min_delay_ms = 2000;
Serial.begin(9600);
pinMode(13, OUTPUT);
xTaskCreate(
led
, "BlinkLed" // Nombre descriptivo de la función (MAX 8 caracteres)
, 128 // Tamaño necesario en memoria STACK
, NULL // Parámetro INICIAL a recibir
, 3 // Prioridad, priridad = 3 (configMAX_PRIORITIES - 1) es la mayor, prioridad = 0 es la menor.
* Expectativa del código: , NULL ); // Variable que apunta al task (opcional)
//void led(){
void led(void *pvParameters){
while(1){
digitalWrite(LED_BUILTIN, HIGH);
//delay(1000);
vTaskDelay( 1000 / portTICK_PERIOD_MS );
digitalWrite(LED_BUILTIN, LOW);
//delay(1000);
vTaskDelay( 1000 / portTICK_PERIOD_MS );
}
}
//void enviar(){
void enviar(void *pvParameters){
for(;;){
String estado = (digitalRead(LED_BUILTIN))?"Encendido":"Apagado ";
int delay_ms = random(1000,5000);
Serial.println("Enviando");
for(int i = 0; i<3; i++){
vTaskDelay( (delay_ms/3) / portTICK_PERIOD_MS );
Serial.print('.');
}
Serial.println();
Serial.print("Estado del led: " + estado);
Serial.println("\tRetardo: " + String((float)delay_ms/1000,3) + " seg\r\n");
//delay(500);
}
vTaskDelay( 1000 / portTICK_PERIOD_MS ); 11
Sistemas Embebidos }
011000010111001101100001011011100111101001100001
Proteus
01101010011001010110000101101110
12
Sistemas Embebidos
011000010111001101100001011011100111101001100001
Ejemplo 3
#include <Arduino_FreeRTOS.h>
01101010011001010110000101101110
int min_max_delay_ms[] = {2000,5000};
int delay_envio = 500;
int delay_led = 250;
void setup() {
Serial.begin(9600);
pinMode(LED_BUILTIN, OUTPUT);
xTaskCreate(
led
, "BlinkLed" // Nombre descriptivo de la función (MAX 8 caracteres)
, 128 // Tamaño necesario en memoria STACK
, NULL // Parámetro INICIAL a recibir (void *)
* Expectativa del código: , 0 // Prioridad, priridad = 3 (configMAX_PRIORITIES - 1) es la mayor, prioridad = 0 es la menor.
, NULL ); // Variable que apunta al task (opcional)
* Parpadear un led cada segundo
xTaskCreate(
* Simular el envío del estado del led a una plataforma enviar
IOT en la nube cada 500 ms, , "envioIOT"
, 128
// Nombre descriptivo de la función (MAX 8 caracteres)
// Tamaño necesario en memoria STACK
* se esparía recibir al menos 1 estado en alto y 1 en , NULL // Parámetro INICIAL a recibir (void *)
, 0 // Prioridad, priridad = 3 (configMAX_PRIORITIES - 1) es la mayor, prioridad = 0 es la menor.
bajo , NULL ); // Variable que apunta al task (opcional)
}
void loop() {
}
void led(){
while(1){
digitalWrite(LED_BUILTIN, HIGH);
vTaskDelay(delay_led / portTICK_PERIOD_MS); //250 ms
digitalWrite(LED_BUILTIN, LOW);
vTaskDelay(delay_led / portTICK_PERIOD_MS); //250 ms
}
}
void enviar(){
for(;;){
String estado = (digitalRead(LED_BUILTIN))?"Encendido":"Apagado ";
int delay_ms = random(min_max_delay_ms[0],min_max_delay_ms[1]); //[2000 - 3000)
Serial.print("Enviando");
for(int i = 0; i<3; i++){
vTaskDelay((delay_ms/3) / portTICK_PERIOD_MS);
Serial.print('.');
}
Serial.println();
Serial.print("Estado del led: " + estado);
Serial.println("\tRetardo: " + String((float)delay_ms/1000,3) + " seg\r\n");
vTaskDelay(delay_envio / portTICK_PERIOD_MS); //500
} 13
Sistemas Embebidos }
011000010111001101100001011011100111101001100001
#include <Arduino_FreeRTOS.h>
01101010011001010110000101101110
void led( void *pvParameters );
void enviar( void *pvParameters );
void analogico( void *pvParameters );
void setup() {
Serial.begin(9600);
pinMode(LED_BUILTIN, OUTPUT);
xTaskCreate(
led
, "BlinkLed" // Nombre descriptivo de la función (MAX 8 caracteres)
, 128 // Tamaño necesario en memoria STACK
, NULL // Parámetro INICIAL a recibir (void *)
, 0 // Prioridad, priridad = 3 (configMAX_PRIORITIES - 1) es la mayor, prioridad = 0 es la menor.
, NULL ); // Variable que apunta al task (opcional)
xTaskCreate(
enviar
, "envioIOT" // Nombre descriptivo de la función (MAX 8 caracteres)
* Expectativa del código: , 128
, NULL
// Tamaño necesario en memoria STACK
// Parámetro INICIAL a recibir (void *)
, 0 // Prioridad, priridad = 3 (configMAX_PRIORITIES - 1) es la mayor, prioridad = 0 es la menor.
* Tomar 100 muestras de un voltaje analógico, sacar su , &TaskEnviar_Handler); // Variable que apunta al task (opcional)
vTaskSuspend(TaskEnviar_Handler);
}
void loop() {
}
vTaskSuspend(TaskEnviar_Handler);
}
}
01101010011001010110000101101110
15
Sistemas Embebidos
011000010111001101100001011011100111101001100001
Desafío:
01101010011001010110000101101110
• Agregar una tarea que utilice TaskEnviar_Handler para ser activada al
momento que debe enviar el dato promediado almacenado en la variable
Datos1. El dato a enviar deberá ser enviado utilizando la trama de
comunicación con el ID del coordinador.
• Agregar una tarea que utilice TaskPWM_Handler para setear un valor PWM en
una de sus salidas.
16
Sistemas Embebidos
011000010111001101100001011011100111101001100001
Trama Comunicación Serial:
01101010011001010110000101101110
17
Sistemas Embebidos
011000010111001101100001011011100111101001100001
Serial Communication:
01101010011001010110000101101110
Start byte ID byte Byte Task Byte Data Byte Checksum
0x00
. XOR (Start byte,
0x31 (1) – ED 0x41 (A) – Read
0x24 ($) 0x30 (0) ID byte, byte
0x36 (6) – C 0x42 (B) - PWM
. Task, byte Data)
0xFF ()
Sensor1
18
Sistemas Embebidos http://www.ginsei-jp.com/ZigBee.html
011000010111001101100001011011100111101001100001
Codigo a editar
#include <Arduino_FreeRTOS.h>
01101010011001010110000101101110
TaskHandle_t TaskLed_Handler;
//variables globales
int led = 13;
int led_pwm=11;
float ADCsensor,Dato = 0;
int estado =0;
int RXTrama[5];
int TramaS[5] ={0x24,0x31,0x41,0x00,0x54};//sensor
int TramaA[5] ={0x24,0x31,0x42,0x00,0x57};//actuador
int IdCoordinador =0x36;//'6'
// Sensor AD-0
//24 31 41 00 54
// Actuador PWM-11
//24 31 42 FF A8
//24 31 42 7F 28
//24 31 42 00 57
// End Device
void TaskBlink( void *pvParameters );
void TaskRxTrama( void *pvParameters );
void TaskAnalogRead( void *pvParameters );// Sensor
void setup() {
pinMode(led, OUTPUT);
pinMode(led_pwm, OUTPUT);
Serial.begin(9600);
xTaskCreate(
TaskBlink
, "Blink" // A name just for humans
, 128 // Stack size
Trama: , NULL
, 0 // priority
, &TaskLed_Handler); // Variable que apunta al task (opcional)
xTaskCreate(
TaskRxTrama
//24 31 41 00 54 xTaskCreate(
TaskAnalogRead
, "AnalogRead"
, 128 // This stack size can be checked & adjusted by reading Highwater
, NULL
, 3 // priority
// Actuador PWM-11 }
, NULL );
vTaskSuspend(TaskLed_Handler);
void loop()
//24 31 42 FF A8 {
}
/*---------------------- Tasks ---------------------*/
void TaskBlink(void *pvParameters) // This is a task.
{
for (;;){
//24 31 42 00 57 }
19
Sistemas Embebidos
011000010111001101100001011011100111101001100001
Proteus
01101010011001010110000101101110
20
Sistemas Embebidos
011000010111001101100001011011100111101001100001
(Adicional) Semáforos binarios usados
para sincronización
01101010011001010110000101101110
• FreeRTOS posee los siguientes elementos para la sincronización de eventos :
colas, semáforos binarios, semáforos contadores, semáforos recursivos y mutex.
• Aunque la finalidad de los semáforos es permitir el acceso de forma segura a un
recurso compartido entre varias tareas, también puede usarse para sincronizar
dos tareas entre si, o una tarea con una rutina de atención a interrupción.
• La rutina de atención a interrupción realiza la interacción con el hardware y
libera el semáforo para permitir desbloquear la tarea que queremos sincronizar
con la interrupción.
• El código implementado dentro de una rutina de atención a interrupción debe
ocupar pocos ciclos de procesador.
21
Sistemas Embebidos
011000010111001101100001011011100111101001100001
Semáforos binarios usados para
sincronización
01101010011001010110000101101110
22
Sistemas Embebidos
011000010111001101100001011011100111101001100001
01101010011001010110000101101110
#include <Arduino_FreeRTOS.h>
#include <semphr.h> // add the FreeRTOS functions for Semaphores (or Flags).
// 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;
// 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);
// 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.
}
xTaskCreate(
TaskAnalogRead
, "AnalogRead"
, 128 // This stack size can be checked & adjusted by reading Highwater
, NULL
, 1 // priority
, NULL );
}
void loop()
{
Serial.println("this is main Task");
delay(1000);
}
xSemaphoreGive( xSerialSemaphore ); // Now free or "Give" the Serial Port for others.
vTaskDelay( 1000 / portTICK_PERIOD_MS ); // wait for one second
}
}
}
xSemaphoreGive( xSerialSemaphore ); // Now free or "Give" the Serial Port for others.
vTaskDelay( 1000 / portTICK_PERIOD_MS ); // wait for one second
}
}
23
Sistemas Embebidos }
https://www.hackster.io/feilipu/using-freertos-semaphores-in-arduino-ide-b3cd6c
011000010111001101100001011011100111101001100001
Proteus
01101010011001010110000101101110
24
Sistemas Embebidos
011000010111001101100001011011100111101001100001
Free RTOS en Arduino
01101010011001010110000101101110
25
Sistemas Embebidos https://www.hackster.io/feilipu/using-freertos-semaphores-in-arduino-ide-b3cd6c
011000010111001101100001011011100111101001100001
Recursos:
• Algunos contenidos vistos en clase como presentaciones,
01101010011001010110000101101110
ejercicios resueltos, entre otros. Serán almacenados y
compartidos en el siguiente Drive:
26
Sistemas Embebidos