Você está na página 1de 6

Sistemas de Tempo Real

FreeRTOS - Multicore

ESP32 possui 2 processadores (core) Xtensa 32-bit LX6:


● Core 0
● Core 1

A seguinte função permite descobrir em qual core o programa carregado está rodando:

xPortGetCoreID()

No FreeRTOS, é possível direcionar uma tarefa para um determinado núcleo usando a


sintaxe para definição de tarefas:
Note que é usada a função xTaskCreatePinnedToCore, com o último parâmetro definindo
qual o core que irá executar a tarefa.

Após a definição da tarefa, a programação da tarefa se dá normalmente:

Tarefa: blink multicore

Monte o circuito a seguir:

Abra sua IDE de desenvolvimento e cole o seguinte programa:

TaskHandle_t Task1;
TaskHandle_t Task2;

// LED pins
const int led1 = 2;
const int led2 = 4;

void setup() {
Serial.begin(115200);
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);

//create a task that will be executed in the Task1code() function, with


priority 1 and executed on core 0
xTaskCreatePinnedToCore(
Task1code, /* Task function. */
"Task1", /* name of task. */
10000, /* Stack size of task */
NULL, /* parameter of the task */
1, /* priority of the task */
&Task1, /* Task handle to keep track of created task
*/
0); /* pin task to core 0 */

//create a task that will be executed in the Task2code() function, with


priority 1 and executed on core 1
xTaskCreatePinnedToCore(
Task2code, /* Task function. */
"Task2", /* name of task. */
10000, /* Stack size of task */
NULL, /* parameter of the task */
1, /* priority of the task */
&Task2, /* Task handle to keep track of created task
*/
1); /* pin task to core 1 */
}

//Task1code: blinks an LED every 1000 ms


void Task1code( void * pvParameters ){
Serial.print("Task1 running on core ");
Serial.println(xPortGetCoreID());

for(;;){
digitalWrite(led1, HIGH);
vTaskDelay(1000);
digitalWrite(led1, LOW);
vTaskDelay(1000);
}
}

//Task2code: blinks an LED every 700 ms


void Task2code( void * pvParameters ){
Serial.print("Task2 running on core ");
Serial.println(xPortGetCoreID());

for(;;){
digitalWrite(led2, HIGH);
vTaskDelay(700);
digitalWrite(led2, LOW);
vTaskDelay(700);
}
}

void loop() {

Compile, grave o programa e observe o resultado esperado:

FreeRTOS - Prática (semáforos)

Iremos aplicar semáforos para controlar o acesso exclusivo à porta serial do ESP32. Para
esta aplicação, precisaremos de um interpretador python instalado na máquina ou utilizar
um monitor serial do seu ambiente de simulação para enviar/receber os dados.

Abra sua IDE de desenvolvimento e cole o seguinte programa:

SemaphoreHandle_t xSerialSem;

void TaskLeituraSerial(void *param);

void setup()
{
Serial.begin(115200);
while (!Serial) {}

// Cria o semáforo na memória


if (xSerialSem == NULL)
{
xSerialSem = xSemaphoreCreateMutex();
if ( xSerialSem != NULL )
xSemaphoreGive( xSerialSem );
}

// Cria a tarefa na memória e carrega no escalonador


xTaskCreate( TaskLeituraSerial, "Leitura Serial", 1024, NULL, 1, NULL );
}

void loop() { }

void TaskLeituraSerial(void *param)


{
for (;;)
{
if ( xSemaphoreTake( xSerialSem, (TickType_t) 5 == pdTRUE ) )
{
while (Serial.available())
Serial.write(Serial.read());
xSemaphoreGive( xSerialSem );
}
vTaskDelay(10);
}
}

Caso opte por usar um interpretador Python, abra um programa em branco e cole o
seguinte programa:

import serial

ser = serial.Serial()

ser.baudrate = 115200

ser.port = 'COM4'

ser.open()

values = bytearray([4, 9, 62, 144, 56, 30, 147, 3, 210, 89, 111, 78, 184,
151, 17, 129])
ser.write(values)

total = 0

while total < len(values):


print(ord(ser.read(1)))
total=total+1

ser.close()

Especifique a porta serial onde está localizado o ESP32 (‘COM4’ em meu computador). A
seguir rode o programa. O resultado esperado é o seguinte.
Note que a mesma sequencia que é enviada para o processador do ESP32 é retornada
para o programa.

Caso tenha optado por rodar o programa no simulador Wokwi, o resultado esperado é o
seguinte:

Você também pode gostar