You are on page 1of 42

Embedded

Labworks

FreeRTOS

Gerenciamento de tarefas
Embedded
Labworks

GERENCIAMENTO DE TAREFAS
Cada tarefa se comporta como um programa
isolado:
Tem um ponto de entrada.
implementada normalmente com um loop infinito.
Normalmente no retorna. Se uma tarefa finalizar,
responsabilidade do desenvolvedor remov-la da lista
de tarefas do kernel.

voidATaskFunction(void*pvParameters);
Prottipo de uma tarefa:
Embedded
Labworks

ESQUELETO DE UMA TAREFA


voidATaskFunction(void*pvParameters)
{
for(;;)
{
/*taskcode*/
}
}
Embedded
Labworks

CRIANDO UMA TAREFA


#include"task.h"

/*createanewtaskandaddittothelistoftasksthat
arereadytorun*/
BaseType_txTaskCreate
(
TaskFunction_tpvTaskCode,
constchar*constpcName,
unsignedshortusStackDepth,
void*pvParameters,
UBaseType_tuxPriority,
TaskHandle_t*pvCreatedTask
);
Embedded
Labworks

TCB E STACK
Tarefa X
Nome

Prioridade

Top of Stack

Stack Pointer TCB (Task Control Block)


..........

0x1845
0x43BF
0x5FA4
0x96BF
Stack
Embedded
Labworks

TRABALHANDO COM TAREFAS


Uma aplicao pode conter diversas tarefas.

Em um microcontrolador com apenas um core, apenas


uma tarefa esta em execuo.

Portanto, isso significa que uma tarefa pode estar em


dois estados: Running (executando) ou Not
running (no executando, parada). Veremos mais para
frente que o estado Not running possui alguns sub-
estados.

Esta troca de estados realizada pelo scheduler ou


escalonador de tarefas.
Embedded
Labworks

INICIANDO O ESCALONADOR
#include"FreeRTOS.h"
#include"task.h"

intmain(void)
{

[...]

/*createtask1*/
xTaskCreate(task1,(signedchar*)"Task1",
configMINIMAL_STACK_SIZE,(void*)NULL,
1,NULL);

/*startthescheduler*/
vTaskStartScheduler();

/*shouldneverreachhere!*/
for(;;);
}
Embedded
Labworks

REMOVENDO UMA TAREFA


Antes de retornar, uma tarefa deve remover ela
mesma da lista de tarefas do kernel com a funo
vTaskDelete().

Para usar esta funo, habilite a opo


INCLUDE_vTaskDelete no arquivo FreeRTOSConfig.h.
Embedded
Labworks

REMOVENDO UMA TAREFA (cont.)


#include"task.h"

/*removeataskfromtheRTOSkernelmanagement*/
voidvTaskDelete(TaskHandle_txTask);
Embedded
Labworks

REMOVENDO UMA TAREFA (cont.)


#include"task.h"

voidATaskFunction(void*pvParameters)
{
for(;;)
{
/*taskcode*/
}

vTaskDelete(NULL);
}
Embedded
Labworks

LABORATRIO

Aplicao baseada em tarefas


Embedded
Labworks

TAREFAS EM EXECUO

TAREFA 1

TAREFA 2

t1 t2 Tempo tn
Embedded
Labworks

PRIORIDADES
A prioridade de uma tarefa definida no parmetro
uxPriority da funo xTaskCreate().

As prioridades vo de 0 (menor prioridade) at


(configMAX_PRIORITIES 1), definida no arquivo
FreeRTOSConfig.h.

Quanto maior o valor mximo, maior o consumo de


RAM!

Em tempo de execuo, tambm possvel alterar a


prioridade de uma tarefa com a funo
vTaskPrioritySet().
Embedded
Labworks

PRIORIDADES E O ESCALONADOR
As tarefas tero diferentes prioridades, dependendo
das suas caractersticas de tempo real.

Ao selecionar uma tarefa para execuo, o


escalonador ir executar sempre a tarefa de maior
prioridade.

O escalonador pode funcionar de forma


colaborativa ou preemptiva, dependendo do
valor da opo configUSE_PREEMPTION no arquivo
FreeRTOSConfig.h.
Embedded
Labworks

MODO COLABORATIVO
No modo colaborativo, as tarefas no so interrompidas
pelo kernel durante sua execuo.

Neste caso, uma tarefa precisa liberar a CPU de forma


voluntria para o escalonador selecionar uma outra tarefa
para execuo.

Para isso, a tarefa pode:


Bloquear esperando um evento.
Liberar a CPU atravs da macro taskYIELD().

Mesmo no modo colaborativo, as tarefas ainda podem ser


interrompidas para o tratamento de uma interrupo.
Embedded
Labworks

USANDO taskYIELD
#include"task.h"

voidATaskFunction(void*pvParameters)
{
for(;;){

process_something();

taskYIELD();
}
}
Embedded
Labworks

MODO PREEMPTIVO
No modo preemptivo, sempre que uma tarefa de maior
prioridade ficar pronta para execuo, o kernel ir
interromper a tarefa de menor prioridade para executar
a tarefa de maior prioridade.

Para tarefas de mesma prioridade, o kernel ir definir


uma fatia de tempo (time slice) da CPU para cada
tarefa, e ir chavear entre elas usando o algoritmo de
round robin.

Se necessrio, a preempo por time slice pode ser


desabilitada atravs da opo configUSE_TIME_SLICING no
arquivo FreeRTOSConfig.h.
Embedded
Labworks

TICK INTERRUPT
Para interromper a tarefa em execuo e trocar de
contexto para uma nova tarefa, o kernel usa uma
interrupo do sistema.

Esta interrupo chamada de tick interrupt


(system tick ou clock tick).

uma interrupo peridica cuja frequncia definida


em configTICK_RATE_HZ no arquivo FreeRTOSConfig.h.

Por exemplo, se estiver definida como 100 (Hz),


significa que a fatia de tempo ser de 10ms.
Embedded
Labworks

TICK INTERRUPT E PREEMPO


Tick interrupt e o
escalonador em ao

KERNEL

TAREFA 1

TAREFA 2

t1 t2 Tempo tn
Embedded
Labworks

TICK INTERRUPT HOOK


possvel configurar uma funo de callback para
ser chamada em cada tick interrupt:
Esta funo pode ser usada para executar uma rotina
peridica.
Como esta rotina roda em contexto de interrupo,
mantenha seu processamento o mais breve possvel.

Habilite a opo configUSE_TICK_HOOK no arquivo


FreeRTOSConfig.h e implemente a funo:
voidvApplicationTickHook(void);
Embedded
Labworks

LABORATRIO

Prioridades e escalonamento
Embedded
Labworks

EVENTOS
Nas atividades que desenvolvemos at agora, as
tarefas no bloqueiam ou esperam por algo, elas
simplesmente monopolizam a CPU.

Em um RTOS, se criarmos tarefas que monopolizam a


CPU, elas devero ter sempre a menor prioridade,
porque se elas tiverem uma prioridade mais alta,
tarefas de menor prioridade nunca sero executadas.

Por isso, sempre que possvel, as tarefas devem ser


orientadas eventos, ou seja, devem aguardar um
evento para realizar o processamento.
Embedded
Labworks

TAREFA ORIENTADA EVENTOS


voidATaskFunction(void*pvParameters)
{
for(;;)
{
wait_event();
process_event();
}
}
Embedded
Labworks

ESTADO BLOCKED
Uma tarefa esperando um evento est no estado
Blocked ou bloqueada.

Um tarefa pode estar bloqueada aguardando dois


tipos de eventos:
Eventos temporais: evento gerado pelo prprio
kernel. Ex: rotinas de delay.
Eventos de sincronizao: evento originado por
uma outra tarefa ou interrupo. Ex: mecanismos de
comunicao como queues e semforos.
Embedded
Labworks

ROTINAS DE DELAY
#include"task.h"

/*delayataskforagivennumberofticks*/
voidvTaskDelay(
constTickType_txTicksToDelay
);

/*delayataskuntilaspecifiedtime*/
voidvTaskDelayUntil(
TickType_t*pxPreviousWakeTime,
constTickType_txTimeIncrement
);
Embedded
Labworks

EXEMPLO ROTINA DELAY


/*blinkledevery500ms*/
voidtaskBlinkLed(void*pvParameters)
{
for(;;){
vTaskDelay(500/portTICK_RATE_MS);
blink_led();
}
}
Embedded
Labworks

ESTADO SUSPENDED
A funo vTaskSuspend() pode ser usada para colocar
uma tarefa no estado Suspended.

Tarefas no estado Suspended no so escalonadas


(executadas) pelo kernel.

A funo vTaskResume() pode ser usada para tirar


uma tarefa do estado Suspended.
Embedded
Labworks

ESTADO READY
Tarefas que no esto nos estados Blocked ou
Suspended esto no estado Ready.

Estas tarefas esto aguardando na fila, prontas para


serem selecionadas e executadas pelo escalonador.
Embedded
Labworks

DIAGRAMA DE ESTADOS DAS


TAREFAS
Running

vTaskSuspend Blocking
API

Ready

vTaskResume Event
xTaskCreat
e
Suspended Blocked
vTaskSuspend

Not running
Embedded
Labworks

LABORATRIO

Rotinas de delay
Embedded
Labworks

TAREFA IDLE
Quando trabalhamos com eventos, as tarefas esto a
maioria do tempo no estado Blocked.

Quando as tarefas esto neste estado, no podem ser


escolhidas e executadas pelo escalonador.

Mas a CPU precisa estar sempre executando alguma


coisa. por isso que existe a tarefa Idle!

Esta tarefa criada automaticamente quando iniciamos


o escalonador ao chamar a funo vTaskStartScheduler().

Esta tarefa tem prioridade 0 (menor prioridade possvel).


Embedded
Labworks

TAREFAS EM EXECUO

TAREFA 1

TAREFA 2

TAREFA IDLE

t1 t2 Tempo tn
Embedded
Labworks

IMPLEMENTAO DA TAREFA IDLE


princpio, a tarefa Idle uma tarefa que no
executa nada!
voididleTask(void*pvParameters)
{
for(;;)
{
/*donothing!*/
}
}
Embedded
Labworks

IMPLEMENTAO DA TAREFA IDLE


Porm, no FreeRTOS ela tem algumas
responsabilidades!
voididleTask(void*pvParameters)
{
for(;;)
{
check_deleted_tasks();

check_if_another_task_is_ready();

execute_idle_task_hook();

check_if_should_sleep();
}
}
Embedded
Labworks

IDLE TASK HOOK


possvel configurar uma funo de callback para
ser chamada quando a tarefa Idle for executada
para:
Executar um processamento contnuo em background.
Medir a quantidade de processamento livre disponvel.
Colocar o processador em modo de baixo consumo.

Para isso, habilite a opo configUSE_IDLE_HOOK no


arquivo FreeRTOSConfig.h e implemente a funo:
voidvApplicationIdleHook(void);
Embedded
Labworks

REGRAS PARA IMPLEMENTAR


A implementao da funo Idle Task Hook nunca
deve bloquear ou suspender, j que neste caso
pode acontecer um cenrio onde nenhuma tarefa
esta pronta para execuo.

dentro da funo Idle que feita a limpeza das


tarefas deletadas pela aplicao. Portanto, se a
aplicao usa a funo vTaskDelete(), ento a funo
Idle Task Hook sempre deve retornar, de forma que
a limpeza possa ser realizada dentro da tarefa Idle.
Embedded
Labworks

ECONOMIA DE ENERGIA
comum o uso da Idle Task Hook para colocar a CPU em um
modo de baixo consumo.

O problema que a interrupo do tick precisa continuar


ligada para que o kernel possa gerenciar a passagem do
tempo e acordar tarefas peridicas quando necessrio.

E se a frequncia do tick for muito alta, o tempo e a energia


consumida para entrar e sair do modo de baixo consumo a
cada interrupo do tick pode invalidar qualquer energia
economizada no modo de baixo consumo.

Para resolver este problema, o FreeRTOS possui uma


funcionalidade chamada de Tickless Idle Mode.
Embedded
Labworks

TICKLESS IDLE MODE


Esta funcionalidade capaz de parar a interrupo do
tick em perodos ociosos antes de colocar o sistema em
modo de baixo consumo.

Isso feito ajustando a frequncia da interrupo do


tick para a prxima tarefa dependente do tick do
sistema (Ex: tarefa peridica usando uma funo de
delay).

Na prxima interrupo do tick, o contador do tick


ajustado para o valor correto.

Tudo isso feito automaticamente pelo FreeRTOS!


Embedded
Labworks

TICKLESS IDLE MODE (cont.)


Esta funcionalidade suportada nativamente nos
portes de algumas arquiteturas, incluindo RX100 e
ARM Cortex-M3/M4.

Para us-la, basta definir a opo


configUSE_TICKLESS_IDLE com 1 no arquivo
FreeRTOSConfig.h.

Para os portes de arquiteturas que no possuem


esta funcionalidade implementada nativamente,
possvel definir a opo configUSE_TICKLESS_IDLE com
portSUPPRESS_TICKS_AND_SLEEP(xExpectedIdleTime);
2 e implementar a macro abaixo:
Embedded
Labworks

LABORATRIO

Idle Task Hook


Embedded
Labworks

UM RESUMO DO ESCALONADOR
Uma aplicao composta por uma ou mais tarefas.

Cada tarefa tem uma prioridade (se necessrio, as tarefas


podem compartilhar a mesma prioridade).

Cada tarefa pode estar em um determinado estado


(Running, Ready, Blocked, Suspended).

Apenas uma tarefa pode estar no estado Running em


determinado momento.

O escalonador preemptivo sempre seleciona a tarefa de


maior prioridade e no estado Ready para ser executada.
Embedded
Labworks

O KERNEL DO FREERTOS
Fixed Priority Preemptive Scheduling

TAREFA 1 (P3)

TAREFA 2 (P2)

TAREFA 3 (P1)

IDLE (P0)

t1 t2 Tempo tn

You might also like