You are on page 1of 321

FreeRTOS

Embedded Labworks

Por Sergio Prado. So Paulo, Janeiro de 2015


Copyright Embedded Labworks 2004-2015. All rights reserved.

Embedded Labworks

SOBRE O INSTRUTOR

Sergio Prado tem mais de 18 anos de experincia em


desenvolvimento de software para sistemas embarcados, em
diversas arquiteturas de CPU (ARM, PPC, MIPS, x86, 68K), atuando
em projetos com Linux embarcado e sistemas operacionais de
tempo real.
scio da Embedded Labworks, onde atua com consultoria,
treinamento e desenvolvimento de software para sistemas
embarcados:
http://e-labworks.com
Mantm um blog pessoal sobre sistemas embarcados em:
http://sergioprado.org

Embedded Labworks

AGENDA DO TREINAMENTO

DIA 1: Introduo, hardware e ambiente de desenvolvimento,


estudando e integrando os fontes do FreeRTOS, trabalhando com
tarefas, prioridades e escalonamento, rotinas de delay, idle task,
comunicao entre tarefas com queues.
DIA 2: Interrupo e mecanismos de sincronizao, semforos
binrios e contadores, deferindo trabalho com queues, protegendo e
controlando acesso recursos com mutex, tarefas gatekeeper,
gerenciamento de memria, trabalhando com o stack e com o heap.
DIA 3: Software timers, co-routines, queue sets, event groups,
integrao com bibliotecas, ferramentas de depurao, estatsticas
de execuo, projetando com um RTOS, projeto final.

Embedded Labworks

FreeRTOS

Introduo a sistemas de tempo real

Embedded Labworks

SISTEMAS DE TEMPO REAL

No contexto de desenvolvimento de software, um sistema


projetado para receber um estmulo (ou evento), que pode ser
interno ou externo, realizar o processamento e produzir uma sada.
Alguns sistemas trabalham com eventos que possuem restries
de tempo, ou seja, possuem um prazo ou tempo-limite para o
estmulo ser processado e gerar a sada correspondente.
Estes tipos de sistemas so chamados Sistemas de Tempo Real.

Embedded Labworks

SISTEMAS DE TEMPO REAL (cont.)

Portanto, um sistema de tempo real precisa garantir com que todos


os eventos sejam atendidos dentro das suas respectivas restries
de tempo.
por isso que um sistema de tempo real esta relacionado ao
determinismo, e no ao tempo de execuo!
Existem basicamente dois tipos de sistemas de tempo real,
classificados de acordo com a tolerncia s restries de tempo, e
as consequncias em no respeitar estas restries.

Embedded Labworks

CLASSIFICAO

Soft real-time: Uma restrio de tempo no atingida tem como


consequncia a percepo de baixa qualidade do sistema. Exemplo:
um display com touch que demora para responder ao tocar na tela.
Hard real-time: Uma restrio de tempo no atingida pode inutilizar
o sistema ou provocar consequncias catastrficas. Exemplo: um
sistema de airbag que no responde no tempo correto no momento
da coliso de um veculo.

Embedded Labworks

DESENVOLVIMENTO

Como desenvolver um sistema com caractersticas de


tempo real?

Embedded Labworks

FOREGROUND/BACKGROUND

Projetos pequenos e de baixa complexidade so desenvolvidos


como sistemas foreground/background (tambm chamados de
super-loop).

A aplicao consiste em um loop infinito que chama algumas funes


para realizar as operaes desejadas (background).
E rotinas de tratamento de interrupo tratam eventos assncronos
(foreground).

Embedded Labworks

O SUPER-LOOP
intmain(void)
{
init_hardware();

while(1){
I2C_ReadPkg();
UART_Receive();
USB_GetPacket();
Audio_Play();
ADC_Convert();
LCD_Show();
...
}
}

voidUSB_ISR(void)
{
Limpainterrupo;
Lpacote;
}

BACKGROUND

FOREGROUND

voidUART_ISR(void)
{
Limpainterrupo;
Tratabyterecebido;
}

Embedded Labworks

O SUPER-LOOP (cont.)
Foreground (ISR2)

Foreground (ISR1)

Background
----- Funo #1 ------

-------------------- Funo #2 ----------------Loop infinito

Linha de Tempo

Funo #3

Embedded Labworks

VANTAGENS DO SUPER-LOOP

Fcil e rpido de desenvolver.


No requer treinamento ou conhecimento de API's especficas de
um sistema operacional.
No consome recursos adicionais comparado soluo com um
sistema operacional.
Soluo tima em projetos pequenos e com requisitos modestos de
restries de tempo.

Embedded Labworks

DEFICINCIAS DO SUPER-LOOP

Difcil garantir que uma operao ir ser executada dentro das


restries de tempo.
Todo o cdigo em background tem a mesma prioridade.
Se uma das funes demorar mais do que o esperado, todo o
sistema ser impactado.

Embedded Labworks

DEFICINCIAS DO SUPER-LOOP (cont.)


while(1){
ADC_Read();
UART_Receive();
USB_GetPacket();
...
}

Delays e outras rotinas podem impactar


todas as funes rodando em background.

voidADC_Read(void){

configure_ADC();
while(conv_rdy==0){
;
}
...
}

Embedded Labworks

DEFICINCIAS DO SUPER-LOOP (cont.)

Tarefas de alta prioridade precisam ser colocadas em foreground


(ISR).
ISRs muito longas podem impactar o tempo de resposta do
sistema.
difcil coordenar a execuo de rotinas em background e em
foreground.

Embedded Labworks

DEFICINCIAS DO SUPER-LOOP (cont.)


while(1){
I2C_ReadPkg();
UART_Receive();
USB_GetPacket();
Audio_Play();
ADC_Convert();
LCD_Show();
...
}

voidUSB_ISR(void){
clear_interrupt();
read_packet();
}

Se um pacote USB recebido logo aps a


chamada desta funo, o tempo de
resposta ser maior.

Embedded Labworks

DEFICINCIAS DO SUPER-LOOP (cont.)

Qualquer alterao em determinada parte do cdigo pode impactar


o tempo de resposta de todo o sistema.

Difcil de garantir as restries de tempo da aplicao.

Sentimento de medo para alterar o cdigo.

Problemas podem aparecer quando o cdigo mantido por


mltiplos desenvolvedores. Como controlar?

Embedded Labworks

A SOLUO

Precisamos ento de uma soluo que gerencie


corretamente os requisitos de tempo real do sistema.
a que entra o kernel de tempo real!

Embedded Labworks

O KERNEL DE TEMPO REAL

Um kernel de tempo real um software que gerencia o tempo e os


recursos da CPU, e baseado no conceito de tarefas e prioridades.
Todas as funcionalidades do sistema so divididas em tarefas
(tasks ou threads).
O kernel decide quando uma tarefa deve ser executada baseado na
prioridade da tarefa.
Fica sob responsabilidade do desenvolvedor dividir o sistema em
tarefas e definir as prioridades de acordo com as caractersticas
de tempo real de cada uma delas.

Embedded Labworks

MULTITAREFA

Em um sistema multitarefa, temos a impresso de que todas as


tarefas esto sendo executadas ao mesmo tempo.

TAREFA 1
TAREFA 2
TAREFA 3

t1

t2

Tempo

tn

Embedded Labworks

MULTITAREFA (cont.)

Mas como o processador s pode executar uma tarefa de cada vez


(considerando-se uma CPU com apenas um ncleo), realizado um
chaveamento entre as tarefas:

TAREFA 1
TAREFA 2
TAREFA 3

t1

t2

Tempo

tn

Embedded Labworks

MULTITAREFA (cont.)

Este chaveamento ou troca de tarefas pode acontecer em


diferentes situaes:

Uma tarefa pode bloquear esperando um recurso (Ex: porta serial)


estar disponvel ou um evento acontecer (Ex: receber um pacote da
interface USB).
Uma tarefa pode dormir por um tempo (Ex: tarefas peridicas).
Uma tarefa pode ser suspensa involuntariamente pelo kernel. Neste
caso, chamamos o kernel de preemptivo.

Esta troca de tarefas tambm chamada de mudana de contexto


(context switching).

Embedded Labworks

MUDANA DE CONTEXTO

Enquanto uma tarefa est em execuo, ela possui determinado


contexto (stack, registradores da CPU, etc).
Ao mudar a tarefa em execuo, o kernel salva o contexto da tarefa
a ser suspensa e recupera o contexto da prxima tarefa a ser
executada.
O controle do contexto de cada uma das tarefas realizado atravs
de uma estrutura chamada TCB (Task Control Block).

Embedded Labworks

O ESCALONADOR

O escalonador de tarefas entra em ao durante as mudanas de


contexto.
Ele a parte do kernel responsvel por decidir qual a prxima
tarefa a ser executada em determinado momento.
O algoritmo responsvel por decidir qual a prxima tarefa a ser
executada chamado de poltica de escalonamento.

Embedded Labworks

ALGUMAS POLTICAS DE ESCALONAMENTO

First-in, First-out ou FirstCome, FirstServed.

Shortest remaining time.

Round-robin scheduling.

Fixed priority preemptive scheduling.

Dynamic priority preemptive scheduling.

Embedded Labworks

KERNEL DE TEMPO REAL

Alm de gerenciar o uso da CPU, um kernel de tempo real possui


normalmente outras responsabilidades, dentre elas:

Gerenciar a comunicao entre as tarefas.

Gerenciar a comunicao entre interrupes e tarefas.

Gerenciar o acesso aos recursos da aplicao (hardware, estruturas


de dados, etc).

Gerenciar o uso de memria.

Prover outras funcionalidades como timers, tracing, etc.

Embedded Labworks

RTOS E KERNEL

Para algumas literaturas, RTOS e kernel de tempo real so a


mesma coisa.
Para outras literaturas, alm de um kernel de tempo real, um RTOS
pode incluir outros servios de alto nvel como gerenciamento de
arquivos, pilhas de protocolo, interface grfica, etc.
Para ns, trataremos RTOS e kernel de tempo real da mesma
maneira!

Embedded Labworks

AS VANTAGENS DE UM RTOS

A vantagem mais clara a possibilidade de priorizar tarefas para


garantir que as restries de tempo da aplicao sejam atendidas.
O uso de um RTOS permite que voc trabalhe orientado eventos,
evitando por exemplo rotinas de polling, e melhorando a eficincia
do sistema. Polling igual desperdcio de CPU!
Como voc precisa dividir a aplicao em tarefas, incentiva uma
melhor arquitetura e modularidade do sistema.

Embedded Labworks

AS VANTAGENS DE UM RTOS (cont.)

Com um sistema modular, fica mais fcil dar manuteno.

Facilita os testes, j que cada tarefa uma entidade independente.

Como cada tarefa tem uma interface bem definida, facilita o


desenvolvimento em equipes com mltiplos desenvolvedores.
Incentiva o reuso de cdigo.

Embedded Labworks

CONSUMO DE RECURSOS

Um RTOS facilita bastante o desenvolvimento de sistemas com


caractersticas de tempo real, mas ele pode no ser a soluo
ideal para determinado projeto:

Os servios providos pelo kernel adicionam um overhead de


execuo, que pode variar entre 2% e 5% do uso da CPU, dependendo
do RTOS.
Um RTOS precisa de um espao extra de ROM (flash) para armazenar
o cdigo, que pode variar de algumas centenas de bytes at algumas
centenas de kilobytes.
Um RTOS consome RAM para armazenar o contexto e o stack de cada
tarefa, que pode variar de algumas centenas de bytes at algumas
dezenas de kilobytes.

Embedded Labworks

FreeRTOS

Hardware e ambiente de desenvolvimento

Embedded Labworks

FREESCALE FREEDOM PLATFORM

Plataforma de desenvolvimento e prototipao de baixo custo da


Freescale ($12 a $20).
http://www.freescale.com/freedom
Ideal para prototipar sistemas com microcontroladores da linha
Kinetis e sensores da Freescale.
Compatvel com shields Arduino (reviso 3).
http://arduino.cc/en/Main/ArduinoShields

Embedded Labworks

FRDM-KL46Z

Embedded Labworks

FRDM-KL46Z (cont.)

MCU MKL46Z256VLL4 (ARM Cortex-M0+) rodando a at 48MHz,


256KB de flash e 32KB de RAM.

Acelermetro MMA8451Q e magnetmetro MAG3110.

Sensor de luz ambiente e touch capacitivo deslizante.

Display LCD de 4 dgitos, 2 leds e 2 botes.

Interface USB device.

Depurao e gravao integrada (OpenSDA).

Embedded Labworks

FRDM-KL46Z (cont.)

Embedded Labworks

DOCUMENTAO

A documentao do hardware est disponvel no ambiente de


laboratrio em docs/hardware:

FRDM-KL46Z - User's Manual.pdf (manual da placa).

FRDM-KL46Z Schematic.pdf (esquemtico da placa).

KL46Z Data Sheet.pdf (datasheet do microcontrolador)

KL46Z Reference
microcontrolador).

Manual.pdf

(manual

de

referncia

do

Embedded Labworks

REFERNCIAS

Para mais informaes sobre esta placa, consulte a pgina oficial


da Freescale:
http://freescale.com/frdm-kl46z
O site da comunidade de microcontroladores Kinetis da Freescale
tambm pode ajudar no caso de dvidas ou problemas:
http://community.freescale.com/community/kinetis

Embedded Labworks

AMBIENTE DE DESENVOLVIMENTO

O Kinetis Design Studio o ambiente de desenvolvimento para


placas com microcontroladores da linha Kinetis da Freescale.
http://www.freescale.com/kds

Ferramenta gratuta e sem limitao de cdigo.

baseada no Eclipse e utiliza o GCC como toolchain.

Suporte oficial para Windows 7/8 e Linux (Ubuntu, Redhat, Centos).

Diversas bibliotecas e drivers prontos disponibilizados pelo Kinetis


SDK.

Embedded Labworks

KINETIS DESIGN STUDIO

Embedded Labworks

KINETIS DESIGN STUDIO (cont.)

Embedded Labworks

DOCUMENTAO DO KDS

A documentao do KDS est disponvel no ambiente de laboratrio


em docs/kds:

Kinetis Design Studio v2.0.0 User Guide.pdf (guia do usurio).


Software Development Kit for Kinetis MCUs - Fact Sheet.pdf
(descritivo do SDK).

Embedded Labworks

LABORATRIO

A primeira aplicao

Embedded Labworks

FreeRTOS

Introduo ao FreeRTOS

Embedded Labworks

O FreeRTOS

Criado por volta do ano 2000 por Richard Barry, e hoje mantindo
pela empresa Real Time Engineers Ltd.
http://www.freertos.org/

RTOS de cdigo aberto mais utilizado no mundo.

simples, pequeno e extremamente portvel.

Documentao da API disponvel no site do projeto.


http://www.freertos.org/a00106.html

Embedded Labworks

O FreeRTOS (cont.)

Cdigo-fonte disponvel no SourceForge.


http://sourceforge.net/projects/freertos/files/
Histrico de alteraes disponvel no site do projeto.
http://www.freertos.org/History.txt
Usaremos no treinamento o FreeRTOS V8.1.2 (novembro/2014).

Embedded Labworks

POSIO NO MERCADO

Linux

Funcionalidades

uClinux
FreeRTOS
Bare metal

Capacidade de processamento

Embedded Labworks

CARACTERSTICAS

Projetado para ser pequeno, simples e fcil de usar.

Escrito em C, extremamente portvel.

Suporta mais de 30 arquiteturas diferentes.

Em uma configurao tpica, o kernel do FreeRTOS pode ocupar de


4KB a 9KB de cdigo (ROM/flash) e em torno de 200 bytes de dados
(RAM).

Porte do RL78 com 13 tarefas, 2 queues and 4 software timers


consome menos que 4K de RAM!

Embedded Labworks

CARACTERSTICAS (cont.)

Kernel pode trabalhar de forma preemptiva ou colaborativa.

Mutex com suporte herana de prioridade.

Capacidades de trace e deteco de stack overflow.

Sem restrio de quantidade de tarefas que podem ser criadas, ou


da quantidade de prioridades que podem ser usadas.
Suporte aplicaes de baixo consumo (tickless mode).

Embedded Labworks

CARACTERSTICAS (cont.)

Diversos projetos e aplicaes de demonstrao para facilitar o


aprendizado.
Cdigo aberto, sem royalty e com frum gratuito disponvel.
http://sourceforge.net/p/freertos/discussion/

Ferramentas de desenvolvimento abertas e gratuitas.

Comunidade grande de usurios.

Suporte e licena comercial se necessrio.

Embedded Labworks

CDIGO-FONTE
FreeRTOS
Source
croutine.c
event_groups.c
include
list.c
portable
queue.c
readme.txt
tasks.c
timers.c
Demo
Common
CORTEX_A2F200_IAR_and_Keil
CORTEX_A2F200_SoftConsole
CORTEX_A5_SAMA5D3x_Xplained_IAR
License
license.txt
readme.txt

Embedded Labworks

CDIGO-FONTE (PORTE)
portable/
CCS
ARM_CortexR4
MSP430X
GCC
ARM7_AT91FR40008
ARM7_AT91SAM7S
ARM_CM0
port.c
portmacro.h
IAR
78K0R
ARM_CM0
V850ES
MemMang
heap_1.c
heap_2.c
heap_3.c
heap_4.c
heap_5.c

Embedded Labworks

FreeRTOSConfig.h
#defineconfigUSE_PREEMPTION1
#defineconfigCPU_CLOCK_HZ58982400
#defineconfigTICK_RATE_HZ250
#defineconfigMAX_PRIORITIES5
#defineconfigMINIMAL_STACK_SIZE128
#defineconfigTOTAL_HEAP_SIZE10240
#defineconfigMAX_TASK_NAME_LEN16
#defineconfigUSE_MUTEXES0
...
#defineINCLUDE_vTaskDelete1
#defineINCLUDE_vTaskDelay1
#defineINCLUDE_xTaskGetCurrentTaskHandle1
#defineINCLUDE_uxTaskGetStackHighWaterMark0
#defineINCLUDE_xTaskGetIdleTaskHandle0
...
http://www.freertos.org/a00110.html

Embedded Labworks

PADRO DE CODIFICAO

MISRA (Motor Industry Software Reliability Association) uma


associao de empresas (principalmente da rea automotiva) com
o objetivo de promover as melhores prticas para o
desenvolvimento de produtos eletrnicos automotivos.
Todo o cdigo comum do FreeRTOS baseado no padro MISRA C,
com algumas excees, por exemplo:

Algumas funes da API tem mais de um ponto de sada.

Uso de aritmtica de ponteiros.

Embedded Labworks

CONVENES

No FreeRTOS usa-se um prefixo no nome das variveis para indicar seu


tipo. Exemplos:

Variveis do tipo char comeam com "c".

Variveis do tipo short comeam com "s".

Outros tipos comeam com "x", como por exemplo estruturas.

Variveis sem sinal comeam com "u". Ex: "us".

Ponteiros comeam com "p". Ex: "pul".

Funes privadas em um arquivo comeam com "prv".


Funes da API so prefixadas com o tipo de retorno da funo (mesma
conveno usada no nome de variveis).

Embedded Labworks

LICENA

O FreeRTOS licenciado pela Real Time Engineers Ltd., sob uma verso
modificada da GPL.
Tem cdigo fonte aberto, no precisa pagar royalties e pode ser usado
livremente em aplicaes comerciais.
No precisa liberar os fontes da sua aplicao, desde que voc no crie
nenhuma funcionalidade j fornecida pelo FreeRTOS.

Precisa indicar que usa o FreeRTOS (um link para o site suficiente).

Qualquer alterao no kernel precisa ser liberada de forma open-source.

Embedded Labworks

OPENRTOS

Verso comercial do FreeRTOS provida pela WITTENSTEIN High


Integrity Systems.
http://www.openrtos.com/rtos/openrtos/
Praticamente o mesmo cdigo-fonte, mas sem nenhuma referncia
GPL.

Liberdade para alterar o kernel sem precisar liberar os fontes.

Acesso suporte tcnico e desenvolvimento.

Proteo legal e garantia.

Embedded Labworks

SAFERTOS

Verso comercial e modificada do FreeRTOS, projetada para


aplicaes crticas.
http://www.openrtos.com/rtos/safertos/
Todas as vantagens da verso comercial (suporte, garantia, etc).
Certificado para aplicaes industriais e mdicas (IEC 61508-3 SIL
3).

Embedded Labworks

LABORATRIO

Estudando e integrando o FreeRTOS

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.

Prottipo de uma tarefa:


voidATaskFunction(void*pvParameters);

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

opo configUSE_TICK_HOOK
FreeRTOSConfig.h e implemente a funo:
voidvApplicationTickHook(void);

no

arquivo

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

Blocking API

vTaskSuspend

Ready
vTaskResume
xTaskCreate

Suspended

vTaskSuspend

Not running

Event

Blocked

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 2 e implementar a macro
abaixo:
portSUPPRESS_TICKS_AND_SLEEP(xExpectedIdleTime);

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

Embedded Labworks

FreeRTOS

Gerenciamento de queues

Embedded Labworks

GERENCIAMENTO DE QUEUE

Vimos at aqui que uma aplicao usando o FreeRTOS


estruturada atravs de um conjunto de tarefas independentes.
bem provvel que estas tarefas precisem se comunicar entre si.
Queue um mecanismo de comunicao (troca de mensagens)
entre tarefas ou entre uma tarefa e uma interrupo.

Embedded Labworks

EXEMPLO

QUEUE

3
TAREFA 1

TAREFA 2
Send

Embedded Labworks

EXEMPLO (cont.)

QUEUE

8
TAREFA 1

3
TAREFA 2

Send

Embedded Labworks

EXEMPLO (cont.)

QUEUE

TAREFA 1

TAREFA 2
Receive

Embedded Labworks

EXEMPLO (cont.)

QUEUE

8
TAREFA 1

TAREFA 2

Embedded Labworks

O QUEUE

Um queue no pertence nenhuma tarefa em especfico.


Diversas tarefas e interrupes podem compartilhar o mesmo
queue, tanto para ler, quanto para escrever.

Cada queue armazena um conjunto finito de itens (queue lenght).

Cada item do queue pode ter um tamanho fixo de bytes (item size).

Ambos "queue lenght" e "item size" so definidos no momento da


criao do queue (o FreeRTOS aloca espao no heap para
armazenar o queue).

Embedded Labworks

CRIANDO E DELETANDO UM QUEUE


#include"queue.h"
/*createanewqueueinstance*/
QueueHandle_txQueueCreate(
UBaseType_tuxQueueLength,
UBaseType_tuxItemSize
);
/*deleteaqueue*/
voidvQueueDelete(QueueHandle_txQueue);
/*resetaqueuetoitsoriginalemptystate*/
BaseType_txQueueReset(QueueHandle_txQueue);

Embedded Labworks

USANDO UM QUEUE

Normalmente, os queues so usados como FIFO (First In First Out),


onde os dados so escritos no fim do queue e lidos no incio.
Mas tambm possvel escrever no incio do queue.
Escrever no queue significa copiar os dados byte a byte! Por este
motivo, se o elemento do queue for muito grande, o ideal
trabalhar com ponteiros.

Embedded Labworks

LENDO DO QUEUE

Ao ler do queue, uma tarefa entra no estado Blocked aguardando


um item do queue.
Uma tarefa pode definir um timeout de leitura (tempo que ficar no
estado Blocked esperando um item no queue).
Uma tarefa esperando um item no queue automaticamente
colocada no estado Ready quando:

Um item escrito no queue.

O timeout de leitura expira.

Embedded Labworks

LENDO DO QUEUE (cont.)

Queues podem ter mais de uma tarefa esperando a leitura de um


item.
Neste caso, se um item escrito no queue, apenas a tarefa de
maior prioridade passada para o estado Ready.
Se existir mais de uma tarefa com a mesma prioridade aguardando
um item no queue, a tarefa que esta esperando a mais tempo ser
passada para o estado Ready.

Embedded Labworks

LENDO DO QUEUE (cont.)


#include"queue.h"
/*receiveanitemfromaqueue*/
BaseType_txQueueReceive(
QueueHandle_txQueue,
void*pvBuffer,
TickType_txTicksToWait);
/*receiveanitemfromaqueuewithoutremoving
theitemfromthequeue*/
BaseType_txQueuePeek(
QueueHandle_txQueue,
void*pvBuffer,
TickType_txTicksToWait);

Embedded Labworks

LENDO DO QUEUE (cont.)


#include"queue.h"
/*returnthenumberoffreespacesinaqueue*/
UBaseType_tuxQueueSpacesAvailable(QueueHandle_txQueue);
/*returnthenumberofmessagesstoredinaqueue*/
UBaseType_tuxQueueMessagesWaiting(QueueHandle_txQueue);

Embedded Labworks

ESCREVENDO NO QUEUE

Ao escrever no queue, uma tarefa pode entrar no estado Blocked se


o queue estiver cheio, aguardando um espao no queue para salvar o
novo item.
Uma tarefa pode definir um timeout de escrita (tempo que ficar no
estado Blocked esperando um espao no queue para salvar o novo
item).
Uma tarefa escrevendo um item no queue automaticamente
colocada no estado Ready quando:

O elemento escrito no queue com sucesso.

O timeout de escrita expira.

Embedded Labworks

ESCREVENDO NO QUEUE (cont.)

possvel ter mais de uma tarefa escrevendo itens no queue.


Se o queue esta cheio, todas as tarefas que escrevem no queue so
colocadas no estado Blocked, esperando um espao no queue.
Quando um espao ficar livre no queue, apenas a tarefa de maior
prioridade colocada no estado Ready, de forma que ela possa
escrever no queue.
Se existir mais de uma tarefa com a mesma prioridade aguardando
um espao livre para escrever no queue, a tarefa que esta
esperando a mais tempo ser passada para o estado Ready.

Embedded Labworks

ESCREVENDO NO QUEUE (cont.)


#include"queue.h"
/*postanitemtothefrontofaqueue*/
BaseType_txQueueSendToFront(
QueueHandle_txQueue,
constvoid*pvItemToQueue,
TickType_txTicksToWait);
/*postanitemtothebackofaqueue*/
BaseType_txQueueSendToBack(
QueueHandle_txQueue,
constvoid*pvItemToQueue,
TickType_txTicksToWait);

Embedded Labworks

ESCREVENDO NO QUEUE (cont.)


#include"queue.h"
/*postanitemonaqueuesameasxQueueSendToBack()*/
BaseType_txQueueSend(
QueueHandle_txQueue,
constvoid*pvItemToQueue,
TickType_txTicksToWait);
/*AversionofxQueueSendToBack()thatwillwritetothe
queueevenifthequeueisfull,overwritingdatathat
isalreadyheldinthequeue.*/
BaseType_txQueueOverwrite(
QueueHandle_txQueue,
constvoid*pvItemToQueue);

Embedded Labworks

EM INTERRUPES

Nunca use estas funes em interrupes!


Em interrupes, use sempre as funes que terminam com
FromISR(). Exemplos:

xQueueSendToFrontFromISR() .

xQueueSendToBackFromISR().

xQueueReceiveFromISR().

Falaremos mais sobre este assunto no decorrer do treinamento.

Embedded Labworks

LABORATRIO

Comunicao entre tarefas com queues

Embedded Labworks

FreeRTOS

Interrupo e mecanismos de sincronizao

Embedded Labworks

INTERRUPO

Sistemas embarcados precisam tomar aes baseados em eventos


externos. Ex: um pacote chegando em uma interface Ethernet
precisa ser recebido e tratado imediatamente.
Normalmente, os eventos so tratados atravs de interrupes,
dentro de uma rotina de tratamento de interrupo (ISR).
Mas como uma interrupo pode interromper uma tarefa
importante ou ser executada com outras interrupes
desabilitadas, devemos manter o seu processamento o mais breve
possvel para no impactar o tempo de resposta da aplicao.

Embedded Labworks

DESENVOLVENDO UMA ISR

Resolvemos este problema dividindo o processamento da


interrupo entre a ISR e uma tarefa do RTOS.
Portanto, em uma ISR devemos:

Reconhecer a interrupo (ACK).

Receber os dados do evento.

Deferir o trabalho para uma tarefa (handler) da aplicao.

Forar a troca de contexto (se necessrio).

Embedded Labworks

ESQUELETO DE UMA ISR


voidisr_handler(void)
{
ack_int();
recebe_dados();
defere_trabalho();
troca_contexto();
}

Embedded Labworks

TRATANDO UMA ISR

ISR

TAREFA 2 (P2)
HANDLER
TAREFA 1 (P1)

IDLE (P0)

Tempo

Embedded Labworks

MECANISMOS DE SINCRONIZAO

Uma interrupo capaz de deferir trabalho para uma tarefa


atravs de mecanismos de sincronizao.
Principais mecanismos de sincronizao do FreeRTOS:

Semforos Binrios (Binary Semaphores).

Semforos Contadores (Counting Semaphores).

Queues.

Estes mecanismos de sincronizao podem ser usados tanto para


comunicao entre tarefas quanto para comunicao entre
interrupes e tarefas.

Embedded Labworks

SEMFOROS BINRIOS

Um Semforo Binrio (Binary Semaphore) um mecanismo de


sincronizao disponibilizado pelo FreeRTOS.
Ele pode ser usado para acordar (desbloquear) uma tarefa quando
determinada interrupo acontecer, sincronizando a interrupo
com a tarefa.
Desta forma, apenas o essencial executado na interrupo, o
restante do trabalho deferido para a tarefa correspondente ao
tratamento da interrupo.

Embedded Labworks

EXEMPLO

SEMFORO BINRIO

ISR

Take

TASK
HANDLER

Embedded Labworks

EXEMPLO (cont.)

SEMFORO BINRIO

ISR

Give

Take

TASK
HANDLER

Embedded Labworks

EXEMPLO (cont.)

SEMFORO BINRIO

ISR

Take

TASK
HANDLER

Embedded Labworks

CRIANDO UM SEMFORO BINRIO


#include"semphr.h"
/*createabinarysemaphore*/
SemaphoreHandle_txSemaphoreCreateBinary(void);
/*deleteasemaphore*/
voidvSemaphoreDelete(SemaphoreHandle_txSemaphore);

Embedded Labworks

PEGANDO UM SEMFORO BINRIO


#include"semphr.h"
/*obtainasemaphore*/
BaseType_txSemaphoreTake(
SemaphoreHandle_txSemaphore,
TickType_txTicksToWait);
/*obtainasemaphorefromanISR*/
BaseType_txSemaphoreTakeFromISR(
SemaphoreHandle_txSemaphore,
signedBaseType_t*pxHigherPriorityTaskWoken);

Embedded Labworks

LIBERANDO UM SEMFORO BINRIO


#include"semphr.h"
/*releaseasemaphore*/
BaseType_txSemaphoreGive(
SemaphoreHandle_txSemaphore);
/*releaseasemaphorefromanISR*/
BaseType_txSemaphoreGiveFromISR(
SemaphoreHandle_txSemaphore,
signedBaseType_t*pxHigherPriorityTaskWoken);

Embedded Labworks

TROCA DE CONTEXTO NA ISR

Para forar a troca de contexto e o chaveamento para uma tarefa


de maior prioridade, aps o processamento da ISR devemos
chamar a funo abaixo:
voidportEND_SWITCHING_ISR(BaseType_tflag);

No parmetro flag devemos usar o valor retornado na varivel


pxHigherPriorityTaskWoken das funes que terminam com
FromISR.

Embedded Labworks

EXEMPLO ISR
voiddummyISR(void)
{
BaseType_txHigherPriorityTaskWoken=pdFALSE;
/*ACKinterrupt,receivedata,etc*/
handle_dummy_int();

/*givesemaphoretounblockthetask*/
xSemaphoreGiveFromISR(dummy_semaphore,
&xHigherPriorityTaskWoken);
/*switchtotaskifit'sthehighestprioritytask
readytorun*/
portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
}

Embedded Labworks

LABORATRIO

Usando semforos binrios

Embedded Labworks

SEMFOROS CONTADORES

Semforos binrios so teis quando a frequncia de interrupes


baixa. Mas quando a frequncia de interrupes alta, existe a
possibilidade de perdermos interrupes.
O problema acontece quando mais de uma interrupo acontece no
momento em que a tarefa ainda esta tratando o trabalho deferido
pela interrupo anterior.
Para estes casos, podemos usar os semforos contadores
(counting semaphores) no lugar dos semforos binrios.

Embedded Labworks

EXEMPLO

SEMFORO CONTADOR

ISR

Take

TASK
HANDLER

Embedded Labworks

EXEMPLO (cont.)

SEMFORO CONTADOR

ISR

Give

Take

TASK
HANDLER

Embedded Labworks

EXEMPLO (cont.)

SEMFORO CONTADOR

ISR

Take

TASK
HANDLER

Embedded Labworks

EXEMPLO (cont.)

SEMFORO CONTADOR

ISR

Give

TASK
HANDLER

Embedded Labworks

EXEMPLO (cont.)

SEMFORO CONTADOR

ISR

Give

TASK
HANDLER

Embedded Labworks

CRIANDO UM SEMFORO CONTADOR


#include"semphr.h"
/*createacountingsemaphore*/
SemaphoreHandle_txSemaphoreCreateCounting(
UBaseType_tuxMaxCount,
UBaseType_tuxInitialCount);

As funes para pegar e liberar um semforo contador so as


mesmas usadas em um semforo binrio.

Embedded Labworks

GERENCIANDO RECURSOS

Um semforo contador tambm pode ser usado para gerenciar o


acesso uma quantidade limitada de recursos do sistema.
Para obter o controle de um recurso, uma tarefa precisa primeiro
obter um semforo (take), decrementando o contador de semforos.
Quando o contador atingir o valor de zero, significa que no existem
mais recursos disponveis.
Quando uma tarefa terminar o uso do recurso, deve devolver o
semforo (give).
Semforos contadores que so usados para gerenciar recursos so
inicializados com a quantidade de recursos disponveis.

Embedded Labworks

EXEMPLO
SEMFORO CONTADOR

TAREFA 1

TAREFA 2

TAREFA 3

Embedded Labworks

EXEMPLO (cont.)
SEMFORO CONTADOR

Take

TAREFA 1

TAREFA 2

TAREFA 3

Embedded Labworks

EXEMPLO (cont.)
SEMFORO CONTADOR

Take

TAREFA 1

TAREFA 2

TAREFA 3

Embedded Labworks

EXEMPLO (cont.)
SEMFORO CONTADOR

Take

TAREFA 1

TAREFA 2

TAREFA 3

Embedded Labworks

EXEMPLO (cont.)
SEMFORO CONTADOR

Give

TAREFA 1

TAREFA 2

TAREFA 3

Embedded Labworks

LABORATRIO

Trabalhando com semforos contadores

Embedded Labworks

USANDO QUEUES EM INTERRUPES

Semforos so usados para comunicar eventos entre tarefas, ou


entre uma tarefa e uma interrupo.
Queues so usados para comunicar eventos e transferir dados.
Portanto, voc pode usar queues para transferir dados e deferir
trabalho de uma interrupo para uma tarefa do RTOS.
Para trabalhar com queues em interrupes, use as funes que
terminam com FromISR.

Embedded Labworks

ESCREVENDO NO QUEUE
#include"queue.h"
/*postanitemtothefrontofaqueue(fromanISR)*/
BaseType_txQueueSendToFrontFromISR(
QueueHandle_txQueue,
constvoid*pvItemToQueue,
BaseType_t*pxHigherPriorityTaskWoken);
/*postanitemtothebackofaqueue(fromanISR)*/
BaseType_txQueueSendToBackFromISR(
QueueHandle_txQueue,
constvoid*pvItemToQueue,
BaseType_t*pxHigherPriorityTaskWoken);

Embedded Labworks

ESCREVENDO NO QUEUE (cont.)


#include"queue.h"
/*postanitemonaqueue(fromanISR)sameas
xQueueSendToBackFromISR()*/
BaseType_txQueueSendFromISR(
QueueHandle_txQueue,
constvoid*pvItemToQueue,
BaseType_t*pxHigherPriorityTaskWoken);
/*AversionofxQueueSendToBack()thatwillwritetothe
queueevenifthequeueisfull,overwritingdatathatis
alreadyheldinthequeue(tobeusedfromanISR)*/
BaseType_txQueueOverwrite(
QueueHandle_txQueue,
constvoid*pvItemToQueue,
BaseType_t*pxHigherPriorityTaskWoken);

Embedded Labworks

LENDO DO QUEUE
#include"queue.h"
/*receiveanitemfromaqueue(fromanISR)*/
BaseType_txQueueReceiveFromISR(
QueueHandle_txQueue,
void*pvBuffer,
BaseType_t*pxHigherPriorityTaskWoken);
/*receiveanitemfromaqueuewithoutremoving
theitemfromthequeue(fromanISR)*/
BaseType_txQueuePeekFromISR(
QueueHandle_txQueue,
void*pvBuffer);

Embedded Labworks

TCNICAS PARA TRANSFERIR DADOS

Voc pode usar algumas tcnicas para transferir dados de uma


interrupo para uma tarefa:

Se a taxa de transferncia for baixa, voc pode simplesmente


transferir byte a byte usando um queue.
Se a taxa de transferncia for alta, voc pode salvar os dados
transferidos em um buffer, e quando receber uma mensagem
completa, notificar a tarefa com um semforo ou enviar a mensagem
com um queue.
Voc pode tambm decodificar mensagens direto da ISR, e passar os
dados j interpretados via queue para a tarefa. Este tcnica s
vlida se a decodificao dos dados for rpida o suficiente para ser
executada de dentro da ISR.

Embedded Labworks

LABORATRIO

Deferindo trabalho com queues

Embedded Labworks

INTERRUPO NO ARM CORTEX-M

O controle das interrupes em um ARM Cortex-M realizado pelo


NVIC (Nested Vectored Interrupt Controller).
Esta arquitetura suporta at 240 interrupes e at 256 nveis de
prioridade (estes valores so definidos pelo fabricante do chip).
Para um microcontrolador com 16 nveis de prioridade de
interrupo, 0 o nvel de maior prioridade e 15 o nvel de menor
prioridade.
Se durante a execuo de uma interrupo, uma outra interrupo de
maior prioridade acontecer, a interrupo atual ser interrompida
para a execuo da interrupo de maior prioridade.

Embedded Labworks

INTERRUPO NO FREERTOS

O FreeRTOS usa 3 fontes de interrupo no porte para o ARM


Cortex-M:

SysTick (System Tick Timer): uma interrupo peridica usada pelo


kernel controlar o tick do sistema e forar a troca de contexto no
modo preemptivo, setando o registrador PENDSV do NVIC, e
consequentemente habilitando a exceo PendSV.
PendSV (Pended System Call): Esta exceo fica pendente e
executada assim que outras excees com maior prioridade forem
tratadas. ela que faz a troca de contexto.
SVCall (System Service Call): uma interrupo de software que
pode ser usada para gerar chamadas de sistema. usada pelo kernel
basicamente para executar a primeira tarefa da aplicao.

Embedded Labworks

CONFIGURANDO AS PRIORIDADES

Existem duas opes no arquivo de configurao do FreeRTOS para


configurar as prioridades das interrupes usadas pelo kernel:

configKERNEL_INTERRUPT_PRIORITY : configura a prioridade

das interrupes usadas pelo kernel (SysTick e PendSV).


normalmente configurada com a menor prioridade possvel.

configMAX_SYSCALL_INTERRUPT_PRIORITY :

define
a
interrupo de maior prioridade que pode usar a API do FreeRTOS.
Isso porque, ao executar uma seo crtica, o kernel desabilita todas
as interrupes de prioridade menor ou igual definida por esta
constante. Isso significa que o FreeRTOS nunca desabilita todas as
interrupes por completo, mesmo dentro de sees crticas!

Embedded Labworks

EXEMPLO
configKERNEL_INTERRUPT_PRIORITY=15
configMAX_SYSCALL_INTERRUPT_PRIORITY=5
Prioridade 0
...
Interrupes que NO usam
a API do FreeRTOS podem
ter qualquer prioridade.

Estas interrupes tem maior


prioridade que o kernel, mas no
podem usar a API do FreeRTOS.

Prioridade 4
Prioridade 5
Prioridade 6
...
Prioridade 15

Interrupes que podem usar a


API do FreeRTOS, mas sero
desabilitadas em regies crticas

Embedded Labworks

NA PRTICA

A constante configKERNEL_INTERRUPT_PRIORITY deve sempre


estar configurada com a menor prioridade possvel.
Como todas as interrupes tem prioridade mxima (valor 0) por
padro no boot, as rotinas de tratamento de interrupo que usam
servios do FreeRTOS precisam ser inicializadas com um valor
maior ou igual que configMAX_SYSCALL_INTERRUPT_PRIORITY .
Rotinas de interrupo extremamente crticas podem ter uma
prioridade maior, implicando um valor menor que
configMAX_SYSCALL_INTERRUPT_PRIORITY , mas no podem
usar nenhuma funo da API do FreeRTOS.

Embedded Labworks

FreeRTOS

Gerenciamento de recursos

Embedded Labworks

GERENCIAMENTO DE RECURSOS

Em um sistema multitarefa, existe a possibilidade de uma tarefa


ser interrompida durante o acesso um recurso, deixando este
recurso em um estado inconsistente, e podendo causar problemas
se uma outra tarefa tentar acessar este mesmo recurso.
Exemplos:

Acesso variveis globais.

Acesso perifricos.

Compartilhamento de cdigo.

Embedded Labworks

ACESSO VARIVEIS GLOBAIS

Imagine o seguinte cdigo em C:


contador+=10;

Agora imagine seu correspondente em um assembly genrico:


LOADR,[#1234]
SUMR,10
STORER,[#1234]

A operao em C acima no atmica, porque precisa de mais de


uma instruo da CPU para completar. Qual a consequncia disso?

Embedded Labworks

ACESSO VARIVEIS GLOBAIS (cont.)

Imagine a seguinte situao:

Tarefa A interrompida pela tarefa B.

Tarefa B altera o valor da varivel global, e depois dorme.

Tarefa A carrega o valor da varivel para o registrador (primeira


instruo assembly).

Tarefa A retorna do ponto onde parou, e executa as outras duas


instrues em assembly, mas usando um valor antigo da varivel global,
j que esta foi alterada pela tarefa B.

Neste caso, como a varivel global pode ser acessada por mais de
uma tarefa ao mesmo tempo, necessrio um controle no acesso
esta varivel para garantir sua consistncia.

Embedded Labworks

ACESSO PERIFRICOS

Considere um cenrio onde duas tarefas escrevem no display LCD:

Tarefa A comea a escrever Digitesuasenhanodisplay:.


Enquanto escrevia no display, a tarefa A interrompida pela tarefa B,
e consegue escrever apenas Digitesuasen.

Tarefa B escreve Erronacomunicao no display.

Tarefa A continua de onde parou e escreve hanodisplay.

No fim, o display exibe a seguinte mensagem: Digite sua


senErronacomunicaohanodisplay!

O acesso concorrente qualquer recurso de hardware por mais de


uma tarefa da aplicao precisa ser gerenciado corretamente.

Embedded Labworks

FUNES THREAD-SAFE

Em um ambiente multitarefa, se uma determinada funo pode ser


chamada por mais de uma thread (tarefa), esta funo deve ser
thread-safe.
Isso comum quando compartilhamos cdigo entre tarefas, por
exemplo atravs do uso de uma biblioteca.
Uma funo thread-safe proteje o acesso aos recursos
compartilhados pelas tarefas, garantindo o acesso concorrente
com segurana.

Embedded Labworks

EXEMPLO
//EstaimplementaoNO
//threadsafe

...
LOCK()
getDate();
UNLOCK();
...

LOCK();
d.day=getDay();
d.month=getMon();
d.year=getYear();
UNLOCK();

structDated;
voidgetDate()
{
d.day=getDay();
d.month=getMon();
d.year=getYear();
}

Embedded Labworks

CRITICAL SESSION E MUTUAL EXCLUSION

Critical Sessions so regies de cdigo que acessam um recurso


compartilhado, e no devem ser acessados concorrentemente por
mais de uma tarefa.
O acesso um recurso que compartilhado entre tarefas deve ser
gerenciado com a tcnica de mutual exclusion, para garantir a
consistncia no acesso.
A idia garantir que apenas uma tarefa tenha acesso exclusivo ao
recurso em determinado momento.
O FreeRTOS prov diversos mecanismos para implementar mutual
exclusion.

Embedded Labworks

MUTEX (MUTUAL EXCLUSION)

O mutex um tipo especial de semforo binrio usado para proteger o


acesso um recurso compartilhado por mais de uma tarefa.

Um mutex basicamente um token associado determinado recurso.

Para uma tarefa acessar o recurso, ela precisa antes pegar o token (take).

Se o recurso estiver ocupado, ela dever esperar a liberao do recurso para


poder us-lo.

Ao terminar de usar o recurso, ela dever liber-lo (give).

Este mecanismo totalmente dependente da disciplina do desenvolvedor!

Embedded Labworks

EXEMPLO
TAREFA 1
MUTEX

TAREFA 2

RECURSO
COMPARTILHADO

Embedded Labworks

EXEMPLO (cont.)
TAREFA 1
Take

MUTEX

TAREFA 2

RECURSO
COMPARTILHADO

Embedded Labworks

EXEMPLO (cont.)
TAREFA 1
MUTEX

TAREFA 2

RECURSO
COMPARTILHADO

Embedded Labworks

EXEMPLO (cont.)
TAREFA 1
MUTEX

Take

TAREFA 2

RECURSO
COMPARTILHADO

Embedded Labworks

EXEMPLO (cont.)

Give

TAREFA 1

MUTEX

Take

TAREFA 2

RECURSO
COMPARTILHADO

Embedded Labworks

EXEMPLO (cont.)
TAREFA 1
MUTEX

Take

TAREFA 2

RECURSO
COMPARTILHADO

Embedded Labworks

EXEMPLO (cont.)
TAREFA 1
MUTEX

TAREFA 2

RECURSO
COMPARTILHADO

Embedded Labworks

USANDO UM MUTEX
#include"semphr.h"
/*createamutex*/
SemaphoreHandle_txSemaphoreCreateMutex(void);
/*obtainamutex*/
BaseType_txSemaphoreTake(
SemaphoreHandle_txSemaphore,
TickType_txTicksToWait);
/*releaseamutex*/
BaseType_txSemaphoreGive(
SemaphoreHandle_txSemaphore);

Embedded Labworks

USANDO UM MUTEX RECURSIVO


#include"semphr.h"
/*createarecursivemutex*/
SemaphoreHandle_txSemaphoreCreateRecursiveMutex(void);
/*obtainarecursivemutex*/
BaseType_txSemaphoreTakeRecursive(
SemaphoreHandle_txSemaphore,
TickType_txTicksToWait);
/*releasearecursivemutex*/
BaseType_txSemaphoreGiveRecursive(
SemaphoreHandle_txSemaphore);

Embedded Labworks

PAUSANDO O ESCALONADOR

Em alguns casos, no possvel utilizar um mutex. Exemplos:

Cdigo do kernel.
Bibliotecas utilizadas pelo kernel (Ex: rotinas de alocao de
memria).

Para estes casos, pode-se pausar o escalonador com a funo


vTaskSuspendAll().

Embedded Labworks

PAUSANDO O ESCALONADOR (cont.)

Ao pausar o escalonador, as interrupes continuam habilitadas,


mas no haver mudana de contexto, e outras tarefas no sero
executadas.
Para

reiniciar

xTaskResumeAll().

escalonador,

pode-se

usar

funo

Embedded Labworks

PAUSANDO O ESCALONADOR (cont.)


void*pvPortMalloc(size_txWantedSize)
{
void*pvReturn;
vTaskSuspendAll();
{
pvReturn=malloc(xWantedSize);
traceMALLOC(pvReturn,xWantedSize);
}
(void)xTaskResumeAll();
[...]

Embedded Labworks

PAUSANDO O ESCALONADOR (cont.)

A tarefa que pausou o escalonador nunca dever bloquear


esperando um evento.
Normalmente apenas o kernel utiliza esta funcionalidade.
Para a aplicao, um mutex dever ser suficiente, a no ser que
seja necessrio executar um trecho de cdigo sem ser interrompido
por outra tarefa.

Embedded Labworks

DESABILITANDO INTERRUPES

Caso o recurso seja compartilhado entre uma tarefa e uma


interrupo, a nica forma de gerenciar o acesso compartilhado
este recurso desabilitando as interrupes.
Para isso, existem duas famlias de funes:

taskDISABLE_INTERRUPTS() e taskENABLE_INTERRUPTS() :

desabilita e habilita as interrupes, respectivamente.

taskENTER_CRITICAL() e taskEXIT_CRITICAL(): mesmo

comportamento, porm permite chamadas aninhadas.

Embedded Labworks

DESABILITANDO INTERRUPES (cont.)

Estas funes desabilitam todas as interrupes at a interrupo


com
prioridade
definida
na
constante
configMAX_SYSCALL_INTERRUPT_PRIORITY .
Desabilitam tambm a preempo, j que a preempo realizada
pela interrupo de tick.
Para evitar problemas em chamadas aninhadas, aconselhvel o
uso
das
funes
taskENTER_CRITICAL()
e
taskEXIT_CRITICAL().

Embedded Labworks

DESABILITANDO INTERRUPES (cont.)

Por questes de performance, pode-se avaliar o uso destas funes


ao invs de um mutex para gerenciar o acesso recursos
compartilhados entre tarefas.
Mas lembre-se sempre que desabilitar as interrupes aumenta o
tempo de latncia do sistema!

Embedded Labworks

RESUMO

Para compartilhar um recurso entre tarefas e interrupes, use as


funes taskENTER_CRITICAL() e taskEXIT_CRITICAL().
Para compartilhar recursos entre tarefas:

Por padro, use um mutex.


Caso a performance seja importante, e a seo crtica seja pequena,
avalie o uso das funes taskENTER_CRITICAL() e
taskEXIT_CRITICAL().

Regra geral: quanto menos recursos compartilhados, melhor!

Embedded Labworks

LABORATRIO

Controlando acesso com mutex

Embedded Labworks

INVERSO DE PRIORIDADE
1) T1 pega o mutex e interrompida
para a execuo da tarefa T3.
2) T3 tenta usar o mutex, mas dorme
porque o mutex esta com T1.
3) T1 resume execuo, e antes de
liberar o mutex interrompida
por T2, que tem maior prioridade.
4) T2 executada, e enquanto isso,
T3, que tem maior prioridade,
continua esperando!

2
High priority task T3

4
Medium priority task T2

1
Low priority task T1

Tempo

Embedded Labworks

HERANA DE PRIORIDADE

A inverso de prioridade acontece quando uma tarefa de maior


prioridade precisa esperar uma tarefa de menor prioridade ser
executada.
Para diminuir o impacto da inverso de prioridade, o FreeRTOS usa
a tcnica de herana de prioridade.
No nosso exemplo, a prioridade da tarefa T1, que contm o mutex,
aumentada momentaneamente para a mesma prioridade de T3 para
finalizar o processamento, liberar o mutex, e possibilitar a
execuo da tarefa T3.

Embedded Labworks

HERANA DE PRIORIDADE (cont.)

1) T1 pega o mutex e interrompida


para a execuo da tarefa T3.
2) T3 tenta usar o mutex, mas dorme
porque o mutex esta com T1.
3) T1 resume execuo, e como esta
usando um mutex requisitado por
T3, sua prioridade aumentada
para a mesma de T3. T2 entra na
lista de Ready e aguarda.
4) T3 executada, pega o mutex
liberado por T1 e executa seu
trabalho.

High priority task T3

Medium priority task T2

1
Low priority task T1

Tempo

Embedded Labworks

DEADLOCK
TAREFA 1
MUTEX A

MUTEX B

TAREFA 2

Embedded Labworks

DEADLOCK (cont.)
TAREFA 1
MUTEX A

Take

MUTEX B

TAREFA 2

Embedded Labworks

DEADLOCK (cont.)
TAREFA 1
MUTEX A

MUTEX B

Take

TAREFA 2
B

Embedded Labworks

DEADLOCK (cont.)
TAREFA 1
A

MUTEX A

MUTEX B

Take

TAREFA 2
B

Embedded Labworks

DEADLOCK (cont.)
TAREFA 1
Take

MUTEX A

MUTEX B

Take

TAREFA 2
B

Embedded Labworks

DEADLOCK (cont.)

Deadlocks acontecem quando duas ou mais tarefas esto


simultaneamente aguardando por recursos que esto sendo
ocupados por outra(s) tarefa(s).

Neste caso, nenhuma das tarefas ser executada novamente!

Deadlocks so erros de design da aplicao.

Embedded Labworks

GATEKEEPER

Gatekeeper uma tcnica para implementar um mecanismo de


mutual exclusion sem os riscos de inverso de prioridade ou
deadlocks.
Uma tarefa do tipo gatekeeper possui acesso exclusivo
determinado recurso, fornecendo servios para outras tarefas
acessarem este recurso.
Todas as tarefas que querem acessar o recurso protegido, devem
utilizar os servios fornecidos pela tarefa gatekeeper.
Essa tcnica permite tambm que uma interrupo acesse um
recurso mais facilmente!

Embedded Labworks

GATEKEEPER (cont.)
QUEUE
MSG1

TAREFA 1

RECURSO

MSG2

TAREFA
GATEKEEPER
TAREFA 2

Embedded Labworks

LABORATRIO

Trabalhando com tarefas Gatekeeper

Embedded Labworks

FreeRTOS

Gerenciamento de memria

Embedded Labworks

GERENCIAMENTO DE MEMRIA

O FreeRTOS ir alocar memria dinamicamente toda vez que


precisar criar um objeto do sistema (tarefa, queue, semforo, etc).
Por este motivo, o FreeRTOS precisa de rotinas de alocao de
memria.
muito comum a biblioteca do sistema disponibilizar estas
rotinas, normalmente chamadas de malloc() e free().
Podemos us-las? Nem sempre!

Embedded Labworks

GERENCIAMENTO DE MEMRIA

Cada aplicao pode ter necessidades diferentes com relao


alocao de memria:

Tamanho ocupado em disco.

Determinismo.

Algoritmo de desfragmentao.

Nem sempre as rotinas de alocao de memria do sistema so


capazes de atender as necessidades da aplicao.
Por este motivo, no FreeRTOS a alocao de memria tratada na
camada portvel. Ou seja, o usurio deve prover ao sistema a
implementao das rotinas de alocao e desalocao de memria.

Embedded Labworks

GERENCIAMENTO DE MEMRIA

Para alocar memria, ao invs de chamar malloc() diretamente, o


FreeRTOS chama pvPortMalloc().
Da mesma forma, para liberar memria, ao invs de chamar a
funo free(), o FreeRTOS chama a funo vPortFree().
Cabe ao desenvolvedor da aplicao fornecer uma implementao
para as rotinas de alocao de memria pvPortMalloc() e
vPortFree().

Embedded Labworks

ALOCAO NO FREERTOS

O FreeRTOS fornece 5 diferentes implementaes para estas


rotinas em Source/portable/MemMang.
Cada uma destas implementaes possuem diferentes
caractersticas, e podem ser selecionadas conforme as
necessidades da aplicao.

Embedded Labworks

ALOCAO NO FREERTOS (cont.)

heap_1.c: apenas aloca memria.

heap_2.c: aloca e desaloca memria, mas no trata fragmentao.

heap_3.c:

heap_4.c:

heap_5.c:

usa a implementao padro de malloc() e free() da


biblioteca C.
aloca e desaloca memria, trata fragmentao e mais
eficiente que a maioria das implementaes da biblioteca C padro.
utiliza o mesmo algoritmo que a heap_4.c, porm
permite utilizar como heap regies no contnuas de memria.

Embedded Labworks

HEAP_1

Implementao bsica de pvPortMalloc().

No implementa vPortFree().

Este algoritmo implementa o heap atravs de um array de bytes


definido em tempo de compilao, que ser dividido em pequenos
blocos a cada chamada a pvPortMalloc().
O tamanho deste heap pode ser configurado na constante
configTOTAL_HEAP_SIZE
definida
no
arquivo
FreeRTOSConfig.h.

Embedded Labworks

HEAP_1 (cont.)

Como a alocao do heap esttica (em tempo de compilao),


pode ser que o compilador reclame que o programa est usando
muita memria RAM.
Esta implementao sempre determinstica, ou seja, o tempo de
execuo sempre constante em qualquer chamada
pvPortMalloc().
Quando usar: em aplicaes que apenas alocam, mas no
desalocam memria.

Embedded Labworks

HEAP_2

Implementa tanto a funo de alocao pvPortMalloc() quanto a


funo de desalocao vPortFree().
Tambm implementa o heap atravs de um array de bytes definido em
tempo de compilao, que ser dividido em pequenos blocos a cada
chamada a pvPortMalloc().
O tamanho deste heap pode ser configurado na constante
configTOTAL_HEAP_SIZE definida no arquivo FreeRTOSConfig.h.
Da mesma forma que heap_1, como a alocao do heap esttica,
pode ser que o compilador reclame que o programa esta usando
muita memria RAM!

Embedded Labworks

HEAP_2 (cont.)

Ao alocar, o algoritmo procura pelo menor bloco de memria


possvel para realizar a alocao requisitada.
Mas como no combina blocos de memria livres e adjacentes,
pode sofrer de fragmentao.
Quando usar: em aplicaes que sempre alocam e desalocam uma
quantidade fixa de bytes. Por exemplo, quando uma aplicao cria
e remove tarefas com o mesmo tamanho de stack frequentemente.

Embedded Labworks

HEAP_3

Usa a implementao de malloc() e free() da biblioteca do


sistema.
Suspende o escalonador para tornar estas funes thread-safe.
Nesta implementao, NO usa um buffer alocado estaticamente
em tempo de compilao.

Embedded Labworks

HEAP_3 (cont.)

Utiliza as configuraes do linker para definir a localizao e o


tamanho do heap.
Quando usar: em aplicaes que alocam e desalocam
constantemente buffers de tamanhos diferentes, e quando voc
confia na sua biblioteca de sistema!

Embedded Labworks

HEAP_4

Disponvel a partir da verso 7.2.0 do FreeRTOS.

Aloca e desaloca memria, igual ao heap_2.

Mas tem um algoritmo capaz de combinar regies adjacentes de


memria, diminuindo bastante os riscos de fragmentao de
memria.
Quando usar: em aplicaes que alocam
constantemente buffers de tamanhos diferentes.

desalocam

Embedded Labworks

HEAP_5

Disponvel a partir da verso 8.1.0 do FreeRTOS.

Utiliza o mesmo algoritmo da heap_4.c.

Capaz de utilizar como heap regies no contnuas de memria.

Quando usar: em sistemas onde a memria RAM endereada de


forma no contnua.

Embedded Labworks

HEAP_5 (cont.)
/*allocatetwoblocksofRAMforusebytheheap*/
constHeapRegion_txHeapRegions[]=
{
{(uint8_t*)0x80000000UL,0x10000},
{(uint8_t*)0x90000000UL,0xa0000},
{NULL,0}
};
/*passthearrayintovPortDefineHeapRegions()*/
vPortDefineHeapRegions(xHeapRegions);

Embedded Labworks

LENDO O TAMANHO LIVRE DO HEAP

Se a sua aplicao estiver usando as implementaes heap_1,


heap_2, heap_4 ou heap_5, possvel ler o tamanho livre do heap
com a funo abaixo:
/*returnfreeheapmemorysize(inbytes)*/
size_txPortGetFreeHeapSize(void);

Embedded Labworks

DE ONDE VEM A MEMRIA?


0X00000
TEXT
DATA
BSS

128K

HEAP

0X1FFFF

STACK

Embedded Labworks

LABORATRIO

Monitorando e ajustando o heap

Embedded Labworks

STACK

O stack uma regio de memria usada para armazenar variveis


locais e salvar registradores e parmetros durante as chamadas
de funo.
Cada tarefa tem o seu stack, definido na criao da tarefa.
Se o tamanho do stack for subdimensionado, existe a possibilidade
da tarefa ultrapassar o espao alocado para o stack na criao da
tarefa.
Chamamos este problema de estouro de pilha ou stack overflow.

Embedded Labworks

STACK OVERFLOW

Stack overflow uma das principais causas de problemas


encontrados no FreeRTOS, principalmente por novos usurios.
Existem algumas tcnicas que podem ser usadas para monitorar o
uso do stack e detectar stack overflow.

Embedded Labworks

HIGH WATER MARK

O FreeRTOS prov uma funo para a aplicao requisitar o quanto


uma tarefa esta perto de ultrapassar o espao alocado para o
stack.
Quanto mais perto de zero, mais prximo da ocorrncia de stack
overflow.
Este valor chamado de "high water mark", e pode ser obtido
atravs da funo uxTaskGetStackHighWaterMark().

Embedded Labworks

HIGH WATER MARK (cont.)


/*returntheminimumamountofremainingstackspace
(inwords)thatwasavailabletothetasksincethe
taskstartedexecuting*/
UBaseType_tuxTaskGetStackHighWaterMark(
TaskHandle_txTask);

Embedded Labworks

LABORATRIO

Monitorando o stack de uma tarefa

Embedded Labworks

STACK OVERFLOW HOOK

O FreeRTOS prov dois mecanismos para monitorar o stack das


tarefas em tempo de execuo.
Estes

mecanismos

so

habilitados

configCHECK_FOR_STACK_OVERFLOW
FreeRTOSConfig.h.

atravs
no

da

constante
arquivo

Se um destes mecanismos for habilitado, o kernel ir monitorar o


stack das tarefas e executar uma funo de callback (stack overflow
hook) caso identifique stack overflow.
Ambos os mtodos aumentam o tempo necessrio para realizar a
troca de contexto.

Embedded Labworks

STACK OVERFLOW HOOK (cont.)

Para usar este mecanismo de checagem do stack, basta configurar a


constante configCHECK_FOR_STACK_OVERFLOW com 1 ou 2, e prover
a implementao da funo de callback de stack overflow, conforme
abaixo:
voidvApplicationStackOverflowHook(
TaskHandle_txTask,signedchar*pcTaskName);

Use esta funo para identificar e corrigir problemas de stack


durante o desenvolvimento da aplicao.
O objetivo desta funo simplificar a depurao de problemas com o
stack. De qualquer forma, no existe nenhum jeito fcil de se
recuperar de um stack overflow.

Embedded Labworks

MTODO 1

O mtodo 1 de checagem do stack selecionado quando


configuramos configCHECK_FOR_STACK_OVERFLOW com 1.
Neste mtodo, aps a troca de contexto de uma tarefa, o kernel
verifica se o stack pointer esta dentro dos limites do stack da
tarefa. Se no estiver, chamar a funo de stack overflow hook
definida pela aplicao.
Este mtodo rpido, mas pode perder alguns stack overflows, j
que apenas verifica o stack pointer na troca de contexto, ou seja,
este mtodo no sabe se durante algum momento na execuo da
tarefa o stack pointer ultrapassou os limites do stack.

Embedded Labworks

MTODO 2

O mtodo 2 de checagem do stack selecionado quando


configuramos configCHECK_FOR_STACK_OVERFLOW com 2.
Este mtodo realiza checagens adicionais alm das descritas no
mtodo 1.
Quando uma tarefa criada, o stack preenchido com um padro
conhecido. Este mtodo verifica se este padro foi sobreescrito nos
ltimos 20 bytes do stack. Em caso afirmativo, a funo de stack
overflow hook ser chamada.
O mtodo 2 no to rpido quanto o mtodo 1, mas tem a vantagem
de garantir quase que 100% de acerto.

Embedded Labworks

LABORATRIO

Monitorando o stack com callbacks

Embedded Labworks

FreeRTOS

Outras APIs do FreeRTOS

Embedded Labworks

TRATANDO MLTIPLOS EVENTOS

Um problema comum em aplicaes com um RTOS quando temos


uma tarefa que pode receber mltiplos eventos de outras tarefas do
sistema.
Se estes eventos tiverem caractersticas diferentes (uns apenas
notificam, outros enviam um byte, outros enviam um buffer de dados,
etc), voc no pode usar apenas um queue ou semforo para receber
estes eventos.
Um design pattern comum usado nestes casos a criao de uma
estrutura para representar estes eventos, contendo o ID do evento e
um ponteiro para os dados do evento, e enviar elementos desta
estrutura atravs de queues.

Embedded Labworks

TRATANDO MLTIPLOS EVENTOS (cont.)


/*applicationeventsstructure*/

typedefstruct
{
intid;
void*data;
}AppEvent;

Embedded Labworks

TRATANDO MLTIPLOS EVENTOS (cont.)


voidvTaskEvent(void*pvParameters)
{
AppEventevent;
for(;;)
{
/*waitevent*/
xQueueReceive(eventQueue,&event,portMAX_DELAY);
/*handleevent*/
switch(event.id){
caseEVENT_KEY:
processEventKey(event.data);
break;
caseEVENT_PRINTER:
processEventPrinter();
break;
[...]

Embedded Labworks

QUEUE SETS

A partir da verso 7.4.0, o FreeRTOS possibilita solucionar este


problema com uma nova API chamada Queue Sets.
Com os queue sets possvel fazer com que uma tarefa bloqueie
esperando por mltiplos semforos e/ou queues ao mesmo tempo.
Para usar esta funcionalidade necessrio:

Criar um queue set com a funo xQueueCreateSet().

Agrupar semforos e/ou queues com a funo xQueueAddToSet().

Bloquear esperando pela recepo de um destes elementos com a


funo xQueueSelectFromSet().

Embedded Labworks

EXEMPLO: QUEUE SETS


voidvTaskEvent(void*pvParameters)
{
xQueueSetMemberHandlexActivatedMember;
xQueueSetHandlexQueueSet;
unsignedcharkey;
/*createqueueset*/
xQueueSet=xQueueCreateSet(EVENT_MAX);
/*addqueuestoqueueset*/
xQueueAddToSet(xQueueKey,xQueueSet);
/*addsemaphorestoqueueset*/
xQueueAddToSet(xSemaphoreDisplay,xQueueSet);
xQueueAddToSet(xSemaphorePrinter,xQueueSet);
[...]

Embedded Labworks

EXEMPLO: QUEUE SETS (cont.)


[...]
for(;;)
{
/*waitevent*/
xActivatedMember=xQueueSelectFromSet(xQueueSet,portMAX_DELAY);
/*handleevent*/
if(xActivatedMember==xQueueKey){
xQueueReceive(xActivatedMember,&key,0);
processEventKey(key);
}
elseif(xActivatedMember==xSemaphoreDisplay){
xSemaphoreTake(xActivatedMember,0);
processEventDisplay();
}

[...]

Embedded Labworks

DESVANTAGENS

Comparado soluo inicial, o uso de queue sets possui algumas


desvantagens:

A implementao usando queue sets utiliza mais memria RAM, j


que precisamos criar um queue ou semforo para cada tipo de
evento.
O cdigo fica maior, ocupando mais espao em flash.
Consome mais ciclos de CPU, j que verificar um queue set leva mais
tempo do que verificar um simples queue.

Embedded Labworks

QUANDO USAR?

A principal motivao para o uso desta API a migrao de


aplicaes para o FreeRTOS.
muito comum os RTOSs de mercado terem uma funo que
bloqueia em mltiplos objetos do kernel. O uC/OSIII por
exemplo tem a funo OSPendMulti().
Ento uma API deste tipo facilitaria a migrao de aplicaes que
rodam em outros RTOSs para o FreeRTOS.

Embedded Labworks

EVENT GROUPS

O FreeRTOS possui uma funcionalidade interessante chamada Event


Groups, disponvel a partir da verso 8.0.0.
A idia agrupar bits (Event Bits) em grupos (Event Groups), que
podem ser usados como mecanismo de sincronizao (notificao)
entre tarefas.
Um

Event

Group

pode
xEventGroupCreate().

ser

criado

com

funo

Embedded Labworks

EVENT GROUPS (cont.)

Uma tarefa pode bloquear esperando por uma mudana em um ou


mais Event Bits com a funo xEventGroupWaitBits().
Outra tarefa pode setar um ou mais Event Bits com a funo
xEventGroupSetBits().

Embedded Labworks

EVENT GROUPS API


/*createaneweventgroup*/
EventGroupHandle_txEventGroupCreate(void);
/*waitforabitorgroupofbitstobecomeset*/
EventBits_txEventGroupWaitBits(
constEventGroupHandle_txEventGroup,
constEventBits_tuxBitsToWaitFor,
constBaseType_txClearOnExit,
constBaseType_txWaitForAllBits,
TickType_txTicksToWait);
/*setabitorgroupofbits*/
EventBits_txEventGroupSetBits(
EventGroupHandle_txEventGroup,
constEventBits_tuxBitsToSet);

Embedded Labworks

CASOS DE USO

Avalie o uso desta API sempre que uma tarefa precisar esperar por
mais de um evento do sistema.
Usando semforos e Queue Sets, podemos ter uma funcionalidade
parecida com a oferecida por esta API.
Mas alm de ser mais leve, esta API possui algumas diferenas
conceituais bem importantes:

Uma tarefa consegue ser notificada apenas quando um grupo de Event Bits
forem setados.
Quando vrias tarefas estiverem esperando no mesmo bit do Event Group,
todas sero acordadas quando o evento acontecer (broadcast).

Embedded Labworks

SOFTWARE TIMER

Um software timer basicamente um timer que possibilita uma


funo ser executada em determinado tempo no futuro.
A funo executada pelo software timer chamada de funo de
callback, e o tempo entre o inicializao do timer e a execuo da
funo de callback chamada de perodo do timer.
Portanto, com o software timer voc consegue configurar uma
funo de callback para ser executada quando um timer expirar.

Embedded Labworks

TIPOS DE SOFTWARE TIMERS

One-shot: executa a funo de callback apenas uma vez, mas pode


ser reiniciado manualmente.
Auto-reload: aps a execuo da funo de callback, reinicia sua
execuo automaticamente. Ou seja, executa a funo de callback
periodicamente.

Embedded Labworks

SOFTWARE TIMER (cont.)

A funcionalidade de software timer do FreeRTOS no faz parte do


ncleo do kernel, e foi implementada de forma a no adicionar
overhead de processamento aplicao.
Por este motivo, o FreeRTOS no usa o tick interrupt e no executa
as funes de callback do timer em contexto de interrupo.
Basicamente, a implementao de software timer do FreeRTOS atua
como uma tarefa usando os recursos providos pelo FreeRTOS.
Ela composta por um conjunto de APIs que se comunicam com a
tarefa de timer atravs de queues.

Embedded Labworks

HABILITANDO

Para habilitar esta funcionalidade, adicione o arquivo timers.c ao


seu projeto e configure as seguintes opes no arquivo de
configurao FreeRTOSConfig.h:

configUSE_TIMERS: 1 para habilitar a funcionalidade de timer.

configTIMER_TASK_PRIORITY: prioridade da tarefa de timer.

configTIMER_QUEUE_LENGTH: tamanho do queue de comandos da

tarefa de timer.

configTIMER_TASK_STACK_DEPTH: tamanho do stack da tarefa

de timer.

Embedded Labworks

SOFTWARE TIMER API


/*createsanewsoftwaretimerinstance*/
TimerHandle_txTimerCreate(
constchar*constpcTimerName,
constTickType_txTimerPeriod,
constUBaseType_tuxAutoReload,
void*constpvTimerID,
TimerCallbackFunction_tpxCallbackFunction);
/*deletesasoftwaretimer*/
BaseType_txTimerDelete(
TimerHandle_txTimer,
TickType_txBlockTime);

Embedded Labworks

SOFTWARE TIMER API (cont.)


/*startsasoftwaretimer*/
BaseType_txTimerStart(
TimerHandle_txTimer,
TickType_txBlockTime);
/*stopsasoftwaretimer*/
BaseType_txTimerStop(
TimerHandle_txTimer,
TickType_txBlockTime);
/*restartsasoftwaretimer*/
BaseType_txTimerReset(
TimerHandle_txTimer,
TickType_txBlockTime);

Embedded Labworks

CO-ROUTINES

As co-routines so uma funcionalidade disponvel a partir da


verso 4.0.0 do FreeRTOS.
Elas tem os mesmos conceitos de uma tarefa, mas com duas
diferenas fundamentais:

Todas as co-routines de uma aplicao compartilham o mesmo


stack, reduzindo drasticamente o uso de memria RAM. Por este
motivo, existem algumas restries no uso de RAM e da API do kernel
em uma co-routine.
O escalonamento de co-routines controlado pelo usurio, e
realizado de forma cooperativa. possvel ter em uma mesma
aplicao tarefas preemptivas e co-routines cooperativas.

Embedded Labworks

CO-ROUTINES (cont.)

Tem o objetivo de ser usada em sistemas com pouqussimos


recursos de RAM, normalmente em microcontroladores de 8 bits, e
por isso no comum seu uso em arquiteturas de 32 bits.

Co-routines s podem estar nos estados Running, Ready e Blocked.

As

prioridades

de

uma

co-routine

vo de 0 at
configMAX_CO_ROUTINE_PRIORITIES 1 , definida no arquivo
FreeRTOSConfig.h.

Embedded Labworks

CRIANDO UMA CO-ROUTINE


/*createanewcoroutineandaddittothelistof
coroutinesthatarereadytorun*/
BaseType_txCoRoutineCreate(
crCOROUTINE_CODEpxCoRoutineCode,
UBaseType_tuxPriority,
UBaseType_tuxIndex);

Embedded Labworks

APLICAO COM CO-ROUTINES


#include"task.h"
#include"croutine.h"
voidmain(void)
{
/*createacoroutine*/
xCoRoutineCreate(vFlashCoRoutine,PRIORITY_0,0);
//NOTE:Taskscanalsobecreatedhere!
/*startthescheduler*/
vTaskStartScheduler();
}

Embedded Labworks

EXEMPLO DE UMA CO-ROUTINE


voidvFlashCoRoutine(xCoRoutineHandlexHandle,
unsignedportBASE_TYPEuxIndex)
{
/*coroutinesmuststartwithacalltocrSTART()*/
crSTART(xHandle);
for(;;)
{
/*delayforafixedperiod*/
crDELAY(xHandle,10);
/*toggleaLED*/
vParTestToggleLED(0);
}
/*coroutinesmustendwithacalltocrEND()*/
crEND();
}

Embedded Labworks

ESCALONANDO CO-ROUTINES
/*schedulethecoroutinesintheidletaskhook*/
voidvApplicationIdleHook(void)
{
vCoRoutineSchedule(void);
}

Embedded Labworks

FreeRTOS

Integrao com bibliotecas

Embedded Labworks

INTEGRAO DE BIBLIOTECAS

Durante o desenvolvimento de um projeto com o FreeRTOS,


diversas bibliotecas podem ser integradas aplicao:

Bibliotecas disponibilizadas pelo fabricante do hardware.

Bibliotecas de cdigo-aberto disponibilizadas pela comunidade.

Bibliotecas disponibilizadas por parceiros da Real Time Engineers


(FreeRTOS+).

Embedded Labworks

SELECIONANDO UMA BIBLIOTECA

Alguns fatores devem ser levados em considerao ao selecionar


uma biblioteca para integrao com o FreeRTOS:

Thread-safe.

Consumo de recursos.

Determinismo.

Licena.

Acesso ao cdigo-fonte.

Facilidade de adaptao e impacto na licena.

Embedded Labworks

FreeRTOS+

Conjunto de bibliotecas e ferramentas disponibilizadas por


parceiros para facilitar o desenvolvimento e a depurao de
aplicaes com o FreeRTOS.
http://www.freertos.org/FreeRTOS-Plus/index.shtml
A maioria dos projetos com cdigo-fonte disponvel em FreeRTOS
Plus/Source/.
A maioria com licena comercial paga (alguns so gratuitos para
determinados chips/fabricantes).

Embedded Labworks

FreeRTOS+ (cont.)

Nabto: soluo de IoT para conexo remota pela Internet.

FAT SL: sistema de arquivos FAT12, FAT16 e FAT32.

Embedded TCP/IP: stack de rede TCP/IP (IPv4/IPv6).

Trace: ferramenta de diagnstico e depurao em tempo de


execuo.

Embedded Labworks

FreeRTOS+ (cont.)

UDP: stack de rede UDP/IP (IPv4).

CLI: interpretador de linha de comando.

CyaSSL: biblioteca TLS/SSL.

IO: implementao do padro POSIX (open(), read(), write(),


ioctl(), etc) para interfacear com drivers de dispositivo.

Embedded Labworks

FreeRTOS LABS

Espao reservado para bibliotecas e ferramentas ainda em fase de


desenvolvimento, testes e consolidao.
http://www.freertos.org/FreeRTOS-Labs/index.shtml
No momento possui apenas o projeto TCP, que implementa uma
pilha de protocolos TCP/IP.
Assim que as bibliotecas deste projeto estiverem consolidadas e
testadas, faro parte do FreeRTOS+.

Embedded Labworks

BIBLIOTECAS DA COMUNIDADE

uIP: pilha de protocolos TCP/IP para microcontroladores de 8/16


bits (agora parte do projeto Contiki).
https://github.com/adamdunkels/uip
lwIP: pilha de protocolos TCP/IP para sistemas embarcados.
http://savannah.nongnu.org/projects/lwip/
FatFs: sistema de arquivos FAT para sistemas embarcados.
http://elm-chan.org/fsw/ff/00index_e.html

Embedded Labworks

BIBLIOTECAS DE FABRICANTES

A maioria dos fabricantes de hardware liberam junto com as


ferramentas de desenvolvimento um conjunto de bibliotecas,
incluindo drivers e pilhas de protocolo, para agregar valor
soluo com o seu chip.

Freescale: SDK For Kinetis Microcontrollers.

Texas Instruments: TivaWare Software.

Atmel: Atmel Software Framework (ASF).

Microchip: MPLAB Harmony Integrated Software Framework.

NXP: LPCWare.

ST: STM32Cube.

Embedded Labworks

BIBLIOTECAS DE FABRICANTES (cont.)

A grande vantagem do uso destas bibliotecas a facilidade de


integrao com a plataforma de hardware do fabricante.
A principal desvantagem o desenvolvimento de um produto cujo
software ser dependente de uma plataforma ou fabricante de
hardware.

Embedded Labworks

INTEGRANDO COM O FREERTOS

Se a biblioteca no for thread-safe, crie funes para abstrair o


acesso biblioteca e proteja este acesso com um mutex.
Se necessrio, altere a biblioteca para utilizar as rotinas de
alocao de memria e de delay do FreeRTOS.
Implemente uma ou mais tarefas do FreeRTOS para paralelizar a
execuo das rotinas da biblioteca.
Analise o cdigo ou mea o consumo de CPU das tarefas que usam
a biblioteca para identificar possveis problemas de
implementao (ex: polling).

Embedded Labworks

FreeRTOS

Ferramentas

Embedded Labworks

LISTA DE TAREFAS EM EXECUO

O FreeRTOS prov a funo vTaskList(), que retorna em tempo


real uma string formatada com todas as tarefas em execuo, o
status das tarefas e o uso do stack.
voidvTaskList(char*pcWriteBuffer);

Para us-la, basta habilitar as opes configUSE_TRACE_


FACILITY e configUSE_STATS_FORMATTING_FUNCTIONS no
arquivo FreeRTOSConfig.h.
Esta rotina s deve ser usada para fins de teste e depurao,
porque ela lenta e desabilita todas as interrupes durante sua
execuo.

Embedded Labworks

LISTA DE TAREFAS EM EXECUO (cont.)

Embedded Labworks

ESTATSTICAS DE EXECUO

O FreeRTOS tem a capacidade de calcular e armazenar o tempo de


processamento alocado para cada tarefa.
A funo vTaskGetRunTimeStats() pode ser usada para
formatar estas informaes para serem melhor visualizadas.
voidvTaskGetRunTimeStats(char*pcWriteBuffer);

Para cada tarefa, dois valores so apresentados:

Abs Time: Tempo total de execuo da tarefa.


% Time: Porcentagem de execuo da tarefa comparada ao tempo
total disponvel.

Embedded Labworks

RUNTIME STATISTICS

Embedded Labworks

HABILITANDO

Para usar esta funcionalidade necessrio:

Habilitar

as

opes

configGENERATE_RUN_TIME_STATS
configUSE_STATS_FORMATTING_FUNCTIONS.

Definir a macro portCONFIGURE_TIMER_FOR_RUN_TIME_STATS(), que


dever configurar o timer que ser usado para gerar as estatsticas. Para
que as estatsticas sejam mais precisas, este timer deve ser de 10 a 100
vezes mais rpido que a interrupo do tick.
Definir a macro portGET_RUN_TIME_COUNTER_VALUE(), que dever
retornar a leitura atual do timer.

Esta rotina s deve ser usada para fins de teste e depurao, porque ela
lenta e desabilita todas as interrupes durante sua execuo.

Embedded Labworks

uxTaskGetSystemState

As funes vTaskList() e vTaskGetRunTimeStats() usam internamente


a funo uxTaskGetSystemState() para coletar informaes sobre as
tarefas do sistema e formatar uma string para o usurio.
Para usar a funo uxTaskGetSystemState(), basta habilitar a opo
configUSE_TRACE_FACILITY no arquivo FreeRTOSConfig.h.
Informaes sobre cada tarefa sero retornadas em uma estrutura do tipo
TaskStatus_t.
Esta rotina s deve ser usada para fins de teste e depurao, porque ela
desabilita o escalonador durante sua execuo.

Embedded Labworks

uxTaskGetSystemState (cont)
#include"task.h"
/*returnsthestateofthesystem,populatinga
TaskStatus_tstructureforeachtask*/
UBaseType_tuxTaskGetSystemState(
TaskStatus_t*constpxTaskStatusArray,
constUBaseType_tuxArraySize,
unsignedlong*constpulTotalRunTime);
);

Embedded Labworks

uxTaskGetSystemState (cont)
typedefstructxTASK_STATUS
{
TaskHandle_txHandle;
constsignedchar*pcTaskName;
UBaseType_txTaskNumber;
eTaskStateeCurrentState;
UBaseType_tuxCurrentPriority;
UBaseType_tuxBasePriority;
unsignedlongulRunTimeCounter;
unsignedshortusStackHighWaterMark;
}TaskStatus_t;

Embedded Labworks

LABORATRIO

Exibindo estatsticas da aplicao

Embedded Labworks

TRACING

Em engenharia de software, tracing a tcnica usada para


armazenar informaes sobre a execuo de um programa.
Estas informaes so normalmente usadas para entender o fluxo
de execuo de uma aplicao, e para diagnosticar e corrigir
problemas.
O FreeRTOS possui alguns mecanismos de tracing, de forma que
possamos analisar o fluxo de execuo da aplicao.

Embedded Labworks

LEGACY TRACE UTILITY

As verses do FreeRTOS anteriores V7.1.0 possuam uma


implementao de tracing, que armazenava a sequncia e o tempo
de execuo de cada uma das tarefas.
Para usar esta funcionalidade, bastava habilitar a opo
configUSE_TRACE_FACILITY no arquivo de configurao
FreeRTOSConfig.h.
E

depois

usar

as funes vTaskStartTrace()
ulTaskEndTrace() para iniciar e finalizar o tracing.

Embedded Labworks

LEGACY TRACE UTILITY (cont.)


#include"task.h"
/*startsakernelactivitytrace*/
voidvTaskStartTrace(
char*pcBuffer,
unsignedlongulBufferSize);
/*stopsakernelactivitytrace*/
unsignedlongulTaskEndTrace(void);

Embedded Labworks

LEGACY TRACE UTILITY (cont.)

As informaes do trace so armazenadas em um buffer, e o trace


finalizado se no houver espao suficiente no buffer para armazenar
mais informaes.
Depois possvel transferir este buffer atravs de um meio de
comunicao (RS232, Ethernet, USB) ou de uma mdia removvel
(carto SD, pendrive, etc).
Existe uma ferramenta para DOS/Windows chamada tracecon.exe
que converte este buffer em um arquivo com campos separados por
TAB, e que pode ser aberto por qualquer programa de planilhas para
gerar relatrios do fluxo de execuo da aplicao.

Embedded Labworks

LEGACY TRACE UTILITY (cont.)

Fonte: Site freertos.org

Embedded Labworks

TRACE HOOK MACROS

A partir da verso 7.1.0, as macros de tracing so a implementao


padro do FreeRTOS para realizar tracing em aplicaes.
Esta funcionalidade composta por um conjunto de macros que
permitem coletar dados sobre o funcionamento da aplicao.
Alguns pontos-chave no cdigo-fonte do FreeRTOS chamam macros
(vazias por padro), mas que podem ser definidas pela aplicao
para prover funcionalidades de tracing para o desenvolvedor.
Com estas macros possvel capturar as trocas de contexto, medir
os tempos de execuo de cada tarefa, fazer log de eventos do
kernel, realizar integrao com ferramentas de depurao, etc.

Embedded Labworks

ALGUMAS MACROS DE TRACING

Macro chamada durante a interrupo de tick:


traceTASK_INCREMENT_TICK(xTickCount)

Macro chamada antes de uma tarefa ser selecionada para


execuo:
traceTASK_SWITCHED_OUT()

Macro chamada logo aps uma tarefa ser selecionada para


execuo:
traceTASK_SWITCHED_IN()

Embedded Labworks

ALGUMAS MACROS DE TRACING (cont.)

Macro chamada se der erro ao criar um queue:


traceQUEUE_CREATE_FAILED()

Macro chamada ao enviar um item para o queue:


traceQUEUE_SEND(pxQueue)

Embedded Labworks

EXEMPLO 1
voidvTask1(void*pvParameters)
{
vTaskSetApplicationTaskTag(NULL,(void*)1);
for(;;)
{
}
}
voidvTask1(void*pvParameters)
{
vTaskSetApplicationTaskTag(NULL,(void*)2);
for(;;)
{
}
}
#definetraceTASK_SWITCHED_IN()\
vSetAnalogueOutput(0,(int)pxCurrentTCB>pxTaskTag)

Embedded Labworks

EXEMPLO 2
#definetraceBLOCKING_ON_QUEUE_RECEIVE(pxQueue)\
ulSwitchReason=reasonBLOCKING_ON_QUEUE_READ;
#definetraceBLOCKING_ON_QUEUE_SEND(pxQueue)\
ulSwitchReason=reasonBLOCKING_ON_QUEUE_SEND;
...
#definetraceTASK_SWITCHED_OUT()\
log_event(pxCurrentTCB,ulSwitchReason);

Embedded Labworks

MACROS DE TRACING

Existem macros para quase todas as chamadas de funo do


FreeRTOS, possibilitando criar um sistema de tracing bem
completo.
A documentao de todas as macros de tracing est disponvel no
site do FreeRTOS.
http://www.freertos.org/rtos-trace-macros.html
O FreeRTOS+Trace da Percepio uma ferramenta de tracing que
implementa estas macros do FreeRTOS, e que se comunica com
uma ferramenta no PC para visualizao dos dados coletados.

Embedded Labworks

FreeRTOS+TRACE

Embedded Labworks

STATEVIEWER PLUGIN

O STATEVIEWER um plugin para Eclipse e IAR que prov um


ambiente de depurao para o FreeRTOS.
desenvolvido pela WITTENSTEIN High Integrity Systems, mesma
empresa responsvel pelo OpenRTOS e pelo SafeRTOS.
Pode ser baixado gratuitamente no site abaixo:
http://www.highintegritysystems.com/
Prov um status atual das tarefas em execuo, recursos em uso
(semforos, queues, etc), consumo do stack por cada tarefa, etc.

Embedded Labworks

SATEVIEWER NO IAR

Embedded Labworks

SIMULADORES

FreeRTOS Windows Simulator um porte do FreeRTOS para rodar no


Windows, funciona no Visual Studio 2010 e no Eclipse, e est
disponvel a partir do FreeRTOS V6.1.1.
Posix/Linux Simulator for FreeRTOS um porte do FreeRTOS para
rodar em mquinas com sistemas operacionais GNU/Linux,
funciona no Eclipse e esta disponibilizado separadamente da
verso oficial do FreeRTOS.

Embedded Labworks

FreeRTOS

Projetando com o FreeRTOS

Embedded Labworks

DEFININDO TAREFAS

melhor ter mais ou menos tarefas?

Vantagens de ter mais tarefas:

Maior controle sobre os tempos de resposta das diferentes partes do


sistema.

Aplicao mais modular, facilitando o desenvolvimento e testes.

Cdigo mais limpo, facilitando a manuteno.

Embedded Labworks

DEFININDO TAREFAS (cont.)

Desvantagens de ter mais tarefas:

Aumenta o compartilhamento de dados e o uso da API do kernel para


sincronismo e troca de informaes entre as tarefas.

Exige mais memria RAM, j que cada tarefa requer um stack.

Consome mais tempo de CPU para realizar a troca de contexto.

Embedded Labworks

DIVIDINDO EM TAREFAS

Pense e divida as funes do seu sistema em tarefas.


Atividades que podem ser executadas em paralelo devem ser
implementadas atravs de uma tarefa.
Funes com prioridades diferentes exigem tarefas diferentes.

Embedded Labworks

DIVIDINDO EM TAREFAS (cont.)

Funes peridicas devem ser implementadas em uma tarefa.


Implemente uma tarefa para cada dispositivo de hardware
compartilhado entre as diversas funes do sistema.
Interrupes devem sincronizar ou transferir dados para tarefas,
portanto bem provvel que cada interrupo que gere um evento
no sistema tenha uma ou mais tarefas associadas ela.

Embedded Labworks

DEFININDO PRIORIDADES

relativamente fcil atribuir prioridades s tarefas em sistemas


mais simples. Normalmente est bem evidente que, por exemplo,
determinada tarefa de controle tem mais prioridade que uma tarefa
que gerencia a interface com o usurio.
Mas na maioria das vezes, no to simples assim, devido
complexidade de sistemas de tempo real.
Como regra geral, tarefas hard real-time devem ter maior prioridade
sobre tarefas soft real-time.
Mas outras caractersticas como frequncia de execuo e uso da
CPU devem ser levadas em considerao.

Embedded Labworks

RATE MONOTONIC SCHEDULING

Uma tcnica interessante chamada Rate Monotonic Scheduling


(RMS) atribui prioridades s tarefas de acordo com sua frequncia
de execuo.
Com o RMS, quanto maior a frequncia de execuo de uma tarefa,
maior sua prioridade.

Embedded Labworks

FRMULA RMS

Dado um conjunto de tarefas que receberam prioridades de acordo


com a tcnica RMS, garantido que o deadline de todas as tarefas
sero atingidos se a seguinte equao for verdadeira:

Ei o tempo mximo de execuo da tarefa i


Ti a frequncia de execuo da tarefa i
Ei/Ti a frao da CPU necessria para executar a tarefa i

Embedded Labworks

TABELA RMS

Embedded Labworks

DEADLINES COM O RMS

Portanto, segundo a tcnica RMS, para atingir o deadline das


tarefas, a soma do uso da CPU de todas as tarefas precisa ser
menor que 69,3%.
Esta tcnica possui algumas restries, como por exemplo as
tarefas no devem se comunicar entre si.
De qualquer forma, pode ser um ponto de partida para definir as
prioridades das tarefas do sistema.

Embedded Labworks

OUTRAS TCNICAS

Existem algumas outras tcnicas comuns para atribuir prioridades


s tarefas, dentre elas:

Tarefas com processamento intensivo devem ter menor prioridade,


para evitar o uso excessivo da CPU (starving).
Tarefas peridicas que rodam em unidades de milisegundos devem
ser executadas em uma tarefa com prioridade maior.
Tarefas peridicas que rodam em unidades de microsegundos para
menos devem ser executadas em uma ISR.
Rotinas que manipulam interface com o usurio devem ser
executadas na ordem de centenas de milisegundos em uma
prioridade que deve refletir seu deadline.

Embedded Labworks

TAMANHO DO STACK

O tamanho do stack de cada tarefa depende da aplicao.


Ao definir o tamanho do stack, necessrio levar em considerao
todas as chamadas de funo, variveis locais e contexto da CPU
para as rotinas de interrupo.
possvel calcular o stack de uma tarefa manualmente, mas pode
ser algo trabalhoso e sujeito erros.

Embedded Labworks

TAMANHO DO STACK (cont.)

Na prtica, defina um tamanho padro para o stack de cada tarefa.


E durante o desenvolvimento e testes da aplicao, monitore o
stack e ajuste-o de acordo com sua utilizao.
Como regra geral, evite escrever funes recursivas.

Embedded Labworks

STACK OVERFLOW

Stack overflow uma das principais causas de problemas


encontrados no FreeRTOS, principalmente por novos usurios.
Existem algumas tcnicas que podem ser usadas para monitorar o
uso do stack e detectar stack overflow.
possvel monitorar o stack de uma tarefa com a funo
uxTaskGetStackHighWaterMark() .
O FreeRTOS prov dois mecanismos para monitorar o stack das
tarefas em tempo de execuo, habilitando a opo
configCHECK_FOR_STACK_OVERFLOW .

Embedded Labworks

PRINTF E STACK OVERFLOW

O uso do stack pode ficar muito maior quando funes da


biblioteca C padro so usadas, especialmente as que manipulam
I/O e string como a famlia de funes printf().
O FreeRTOS possui uma verso simples e eficiente do sprintf()
no arquivo printfstdarg.c, que pode ser usada pela aplicao,
e que consome muito menos stack que a implementao padro da
biblioteca C.

Embedded Labworks

COMUNICAO ENTRE TAREFAS

Use semforos para sincronizar (notificar) tarefas.


Quando, alm de sincronizar, necessrio trocar dados, use
queues.
Sempre proteja o acesso regies crticas.
Crie tarefas gatekeeper para compartilhar acesso recursos de
hardware.

Embedded Labworks

INTERRUPES

Uma interrupo nunca deve usar uma funo do RTOS que


bloqueia.

Use sempre funes do FreeRTOS que terminam com fromISR().

Implemente rotinas de tratamento de interrupo curtas.

Sempre que possvel, transfira o trabalho para uma tarefa, usando


semforos ou queues.

Embedded Labworks

INTERRUPES (cont.)

No use funes da API do FreeRTOS em interrupes cuja


prioridade
esto
acima
de
configMAX_SYSCALL_INTERRUPT_PRIORITY .
S habilite as interrupes que usam funes do kernel aps iniciar
o escalonador de tarefas com a funo vTaskStartScheduler().

Embedded Labworks

HEAP

no heap que o kernel aloca memria para armazenar os dados das


tarefas, dos queues e dos semforos usados na aplicao.
Conforme evoluimos na implementao da aplicao, precisamos de
um espao maior no heap. E se faltar espao no heap, o kernel no
conseguir alocar memria para criar os objetos requisitados.
Por isso, verifique sempre o retorno das funes de criao de
tarefas, queues e semforos para identificar problemas de alocao
de memria.
Monitore tambm erros de alocao de memria atravs da funo
de callback vApplicationMallocFailedHook() .

Embedded Labworks

ESCALONADOR

Os seguintes modos de escalonamento de processos esto


disponveis no FreeRTOS:

Colaborativo.

Preemptivo sem time slice.

Preemptivo.

Embedded Labworks

ESCALONADOR E TROCA DE CONTEXTO


Bloquear ou liberar
CPU

Retorno de uma API


do FreeRTOS

Fim do time slice

Retorno de uma ISR

Colaborativo

SIM

NO

NO

SIM

Preemptivo sem time


slice

SIM

SIM

NO

SIM

Preemptivo

SIM

SIM

SIM

SIM

Embedded Labworks

QUAL USAR?

mais fcil desenvolver e garantir tempos de resposta no modo


preemptivo, com a desvantagem de aumentar o uso de CPU devido s
trocas de contexto.
J no modo colaborativo o overhead de CPU menor, porm
impactamos negativamente os tempos de resposta da aplicao.
Sistemas hard real-time tendem a usar o escalonador no modo
preemptivo.
Sistemas mais simples, com caractersticas de soft real-time ou com
foco maior em processamento, podem avaliar o uso do escalonador
no modo colaborativo ou preemptivo com time slice desabilitado.

Embedded Labworks

LABORATRIO

Projeto final

Embedded Labworks

FreeRTOS

E agora?

Embedded Labworks

RECURSOS ONLINE

Site do projeto:
http://freertos.org
Forum do projeto:
http://sourceforge.net/p/freertos/discussion/
Blog do Sergio Prado:
http://sergioprado.org

Embedded Labworks

OUTROS RTOS'S OPEN SOURCE

BRTOS:
http://code.google.com/p/brtos/
BeRTOS:
http://www.bertos.org/
eCos:
http://ecos.sourceware.org/

Embedded Labworks

OUTROS RTOS'S OPEN SOURCE (cont.)

RTEMS Real Time Operating System:


http://www.rtems.com/
CooCox CoOS (ARM Cortex-M):
http://www.coocox.org/CoOS.htm

Embedded Labworks

ALGUNS RTOS'S COMERCIAIS

UC/OS-III (Micrium):
http://micrium.com/page/products/rtos/os-iii
MQX (Freescale):
http://www.freescale.com/mqx
TI-RTOS (Texas Instruments):
http://www.ti.com/tool/ti-rtos
RTX (Keil):
http://www.keil.com/rtos/

Embedded Labworks

ALGUNS RTOS'S COMERCIAIS (cont.)

ThreadX (Express Logic):


http://rtos.com/products/threadx/
Nucleus OS (Mentor Graphics):
http://www.mentor.com/embedded-software/nucleus/
VxWorks (Wind River):
http://www.windriver.com/products/vxworks/

Embedded Labworks

LIVROS FREERTOS

Embedded Labworks

OUTROS LIVROS

Embedded Labworks

OUTROS LIVROS (cont.)

OBRIGADO!
E-mail
Website

sergio.prado@e-labworks.com
http://e-labworks.com

Embedded Labworks

Por Sergio Prado. So Paulo, Julho de 2012


Copyright Embedded Labworks 2004-2012. All rights reserved.