Sistemas Tempo-Real
O sistema operativo de tempo-real FreeRTOS
UA/DETI, 2012 Paulo Pedreiras pbrp@ua.pt
V1.0, Set/2012
Agenda
1. Introduo ao FreeRTOS 2. Gesto de tarefas 3. Filas 4. Interrupes e Sincronizao 5. Gesto de recursos 6. Gesto de memria
V1.1 / Set 2012 - Paulo Pedreiras
STR - FreeRTOS
1 Introduo
V1.1 / Set 2012 - Paulo Pedreiras
STR - FreeRTOS
Introduo ao FreeRTOS
FreeRTOS
Open Source (http://www.freertos.org/) Simples, portvel e conciso Diversas famlias de processadores suportados (e.g. PIC18, PIC32, ARM7, AVR, 8051, x86, ...) Ferramentas de desenvolvimento para Windows e Linux (dependendo do tipo de processador) Poltica de escalonamento configurvel
Preemptiva (tarefas da mesma prioridade executam em roud robin)
Cooperativa
Tarefas cedem o CPU por invocao explicita de uma primitiva (taskYIELD()).
STR - FreeRTOS 4
V1.1 / Set 2012 - Paulo Pedreiras
Introduo ao FreeRTOS
IPC
Semforos Message Queues Maioria do cdigo comum s vrias famlias de processadores Executa em micro-controladores/processadores com recursos muito limitados (memria, capacidade de processamento processadores 8,16,32 bit/ Flash >= 32K/RAM>=16KB)
Kernel minimalista, mas muito eficiente e portvel
Gesto de alocao dinmica de memria flexvel
STR - FreeRTOS 5
V1.1 / Set 2012 - Paulo Pedreiras
Introduo ao FreeRTOS
Type casting excessivo
Forma de lidar com os requisitos de diversos compiladores
e.g. tipo char sem qualificador tratado como signed por alguns compiladores e como unsigned por outros
Regras:
Nomes de variveis so precedidas por
c: tipo char / s: tipo short / l: tipo long / v:void p: pointer e ... x: portBASE_TYPE (tipo que depende da arquitetura 8/16/32 bit)
V1.1 / Set 2012 - Paulo Pedreiras
STR - FreeRTOS
Introduo ao FreeRTOS
Regras (cont.):
Nomes de funes
tipo+ficheiro em que esto definidas
e.g. vTaskPrioritySet() devolve um void e est definida em task.c
Macros
Nomes em maisculas e com sufixos em minsculas identificando onde esto definidas
e.g. portMAX_DELAY Definida em port.h Chama-se MAX_DELAY
Algumas macros comuns
pdTRUE (1) ; pdFALSE (0) ; pdPASS (1) ; pdFAIL (0)
STR - FreeRTOS 7
V1.1 / Set 2012 - Paulo Pedreiras
Introduo ao FreeRTOS
Criar projetos
Recomendvel partir de uma demonstrao e adaptar de acordo com as necessidades
Abrir demo e verificar que compila sem erros Remover os ficheiros fonte especficos da demo (todos os ficheiros na pasta em .\Demo\Common podem ser removidos Remover todas as funes do main.c, exceto prvSetupHardware() Colocar a 0 as seguintes constantes em FreeRTOSConfig.h
config{USE_IDEL_HOOK;USE_TICK_HOOK;USE_MALLOC_F AILED_HOOK;CHECK_FOR_STACK_OVERFLOW}
V1.1 / Set 2012 - Paulo Pedreiras
STR - FreeRTOS
Introduo ao FreeRTOS
Criar projetos (cont)
Criar uma nova funo main() de acordo com a template abaixo Compilar Adicionar tarefas
short main( void ) { /* Init hardware */ prvSetupHardware(); /* Create application tasks */ ... /* Set the scheduler running. This function will not return unless a task calls vTaskEndScheduler(). Or there is no hep start the scheduler*/ vTaskStartScheduler(); return 0; } V1.1 / Set 2012 - Paulo Pedreiras STR - FreeRTOS 9
2 Gesto de Tarefas
V1.1 / Set 2012 - Paulo Pedreiras
STR - FreeRTOS
10
Gesto de tarefas
No FreeRTOS uma tarefa implementada como uma funo em linguagem C As tarefas apresentam a seguinte estrutura
Cabealho
Designao da funo + parmetros de entrada Funo devolve mandatoriamente void Variveis locais funo. Stack de cada tarefa deve acomodar espao para as variveis locais e salvaguarda de contexto Cdigo que executado apenas uma vez
STR - FreeRTOS 11
Variveis locais
Inicializao
V1.1 / Set 2012 - Paulo Pedreiras
Gesto de tarefas
As tarefas apresentam a seguinte estrutura (cont.)
Cabealho Variveis locais Inicializao Ciclo infinito
Corpo da tarefa (processamento/funcionalidade). Cada execuo denomina-se instncia ou job As tarefas nunca devem sair da funo associada sua implementao no h um return Quando se pretende terminar uma tarefa, tal deve ser efetuado explicitamente
STR - FreeRTOS 12
Eliminao da tarefa
V1.1 / Set 2012 - Paulo Pedreiras
Gesto de tarefas
Exemplo
Cabealho Variveis locais Inicializaes
int i; i=0; PORTAbits.RA0=0; while(1) { PORTAbits.RA0=~ PORTAbits.RA0;
void vTaskName(void *pvParameters) {
for(i=0;i<20000;i++); vTaskDelay(1000/portTICK_RATE_MS); } vTaskDelete(NULL); }
V1.1 / Set 2012 - Paulo Pedreiras
Corpo da tarefa - Ciclo - Processamento/funcionalidade - Bloqueio at novo perodo
Eliminar tarefa
STR - FreeRTOS
13
Gesto de tarefas
No FreeRTOS uma tarefa pode estar num de 4 estados
Running
vTaskSuspend()
Suspended
vTaskSuspend()
Cdigo da tarefas est em execuo Pronta a executar; Aguarda alocao do CPU
vTaskSuspend()
vTaskResume()
Ready
Ready queue
Ready
Preemption Dispatch
Running
Suspended
Init
Event (e.g. vSemaphoreGive)
Execuo suspensa
Blocked
Blocking sys call (e.g. vSemaphoreTake) 14
Blocked
Aguarda um recurso ou passagem do tempo V1.1 / Set 2012 Paulo Pedreiras para poder executar STR - FreeRTOS
Gesto de tarefas
Criao de tarefas
A criao de uma tarefa feita por via da funo xTaskCreate(), a qual possui como argumentos
pvTaskCode: ponteiro para a funo pcName: string com designao da funo
Puramente descritivo. Cada tarefa tem a sua stack individual O valor indica o numero de words que deve ter Valor difcil de estimar devido chamada de funes, etc. FreeRTOS define um valor configMINIMAL_STACK_SIZE (valor mnimo recomendado para qualquer aplicao)
usStackDepth: dimenso da stack.
V1.1 / Set 2012 - Paulo Pedreiras
STR - FreeRTOS
15
Gesto de tarefas
funo xTaskCreate() - continuao
*pvParameters: argumentos para a tarefa uxPriority: prioridade da tarefa
Valor entre 0 (menor prioridade) e configMAX_PRIORITIES-1 (maior prio.) Maior nmero de prioridades implica mais consumo de RAM Permite referenciar a tarefa em outras tarefas para e.g. alterar a prioridade, eliminar, ...
*pxCreatedTask: handle para a tarefa
Retorno
pdTRUE: sucesso err_COULD_NOT_ALLOCATE_REQUIRED_MEMORY
Tarefa no foi criada por falta de memria (TCB e stack)
STR - FreeRTOS 16
V1.1 / Set 2012 - Paulo Pedreiras
Gesto de tarefas
Criao de tarefas
A partir da funo main(); posteriormente inicia-se o escalonador Exemplo:
void main( void ) { int i,j; ... /Local vars /* Inicializaes */ TRISA = 0x00; /* Ports A all output */ ... /* Create tasks */ xTaskCreate(vTask1, (const portCHAR * const) "vTask1", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL); xTaskCreate(vTask2, ...); /* Start scheduler */ vTaskStartScheduler(); /* Main can't terminate */ while(1); } V1.1 / Set 2012 - Paulo Pedreiras STR - FreeRTOS 17
Gesto de tarefas
Prioridades no FreeRTOS
configMAX_PRIORITIES-1 ... tskIDLE_PRIORITY Idle Task27 Task1 Task34 Task22
- Prioridade +
Quando h vrias tarefas ready:
executada a de maior prioridade Dentro de cada nvel de prioridade h Round Robin Durao do slice configurvel (configTICK_RATE_HZ)
As tarefas do utilizador podem partilhar o nvel de prioridade idle
STR - FreeRTOS 18
V1.1 / Set 2012 - Paulo Pedreiras
Gesto de tarefas
Tarefas peridicas
Em aplicaes de controlo muitas tarefas so peridicas (e.g. malhas de controlo) A funo vTaskDelay permitir colocar uma tarefa no estado bloqueado durante um certo perodo de tempo
E.g.
while(1) { Funcionalidade; vTaskDelay(1000/portTICK_RATE_MS); }
vTaskDelay(1000/portTICK_RATE_MS);
T1
V1.1 / Set 2012 - Paulo Pedreiras
1000/portTICK_RATE_MS
T1
STR - FreeRTOS 19
Gesto de tarefas
Tarefas peridicas (continuao)
Problemas
Perodo pouco rigoroso. Dependente de variaes do tempo de execuo da tarefa, interferncia de outras tarefas, interrupes, ...
while(1) { Funcionalidade; vTaskDelay(1000/portTICK_RATE_MS); }
T1
1000/portTICK_RATE_MS
T2 P(k)
T1
1000/portTICK_RATE_MS
T1 P(k+1)
V1.1 / Set 2012 - Paulo Pedreiras
P(k) <> P(k+1) !!!!!
STR - FreeRTOS
20
Gesto de tarefas
Tarefas peridicas (continuao)
Soluo: vTaskDelayUntil()
Indica o tempo absoluto em que a ativao deve ocorrer Referenciada ativao anterior e no ao instante de invocao
void vTask1(void *pvParameters) { ... portTickType xLastWakeTime; ... xLastWakeTime=xTaskGetTickCount(); while(1) { Funcionalidade... vTaskDelayUntil(&xLastWakeTime,(1000/portTICK_RATE_MS)); } }
V1.1 / Set 2012 - Paulo Pedreiras
STR - FreeRTOS
21
Gesto de tarefas
Parmetros de entrada
Por vezes til passar parmetros a tarefas
E.g. tarefas que leiam valores de uma ADC multiplexada tm um cdigo idntico, variando apenas o ID do canal
void vTask1(void *pvParameters) { ... int adc_chan; ... adc_chan=*((int *)pvParameters); ... while(1) { Funcionalidade... vTaskDelayUntil(&xLastWakeTime,(1000/portTICK_RATE_MS)); } }
V1.1 / Set 2012 - Paulo Pedreiras STR - FreeRTOS 22
Gesto de tarefas
Alterar a prioridade de uma tarefa
A prioridade de uma tarefa pode ser alterada por meio da funo vTaskPrioritySet(xTaskHandle pxTask, unsigned portBASE_TYPE, uxNewPriority)
pxTask: handle da tarefa que se pretende modificar
NULL refere a prpria tarefa
UxNewPriority: valor da prioridade desejada
A prioridade de uma tarefa pode ser obtida com a system call vTaskPriorityGet()
STR - FreeRTOS 23
V1.1 / Set 2012 - Paulo Pedreiras
Gesto de tarefas
Eliminar uma tarefa
Uma tarefa pode ser eliminada por meio da funo vTaskDelete(xTaskHandle pxTaskToDelete)
pxTaskToDelete: handle da tarefa que se pretende modificar
NULL refere a prpria tarefa
Quando uma tarefa eliminada o TCB e stack so libertados Todavia podem no ficar disponveis para reutilizao
Depende do gestor de memria dinmica
STR - FreeRTOS 24
V1.1 / Set 2012 - Paulo Pedreiras
Gesto de tarefas
Suspender uma tarefa
A execuo de uma tarefa pode ser suspensa eliminada por meio da funo vTaskSuspend(xTaskHandle pxTaskToSuspend)
pxTaskToSuspend: handle da tarefa alvo
NULL refere a prpria tarefa
A sada do estado de suspenso d-se por invocao de vTaskResume(xTaskHandle pxTaskToResume)
pxTaskToResume: handle da tarefa alvo
STR - FreeRTOS 25
V1.1 / Set 2012 - Paulo Pedreiras
Gesto de tarefas
Suspender uma tarefa (continuao)
Quando a suspenso terminada a partir de uma ISR a system call : portBASE_TYPE vTaskResumeFromISR(xTaskHandle pxTaskToResume)
pxTaskToResume: handle da tarefa alvo pdTRUE: caso resulte da operao uma mudana de contexto pdFALSE: caso contrrio
Valor retornado:
V1.1 / Set 2012 - Paulo Pedreiras
STR - FreeRTOS
26
Gesto de tarefas
Outras funes
portTickType xTaskGetTickCount(void)
Devolve o nmero de ticks que decorreram desde que o scheduler foi iniciado (tempo absoluto) Valor em interrupt ticks; dependente da plataforma
A constante portTICK_RATE_MS permite efetuar a converso entre o tempo real e ticks
portBASE_TYPE uxTaskGetNumberOfTasks(void)
Devolve o nmero de tarefas no sistema A eliminao de tarefas no decrementa imediatamente este valor (parcialmente executado por cdigo associado idle task) Passa o controlo a outra tarefa sem esperar pelo final do time slot
STR - FreeRTOS
TaskYELD(void)
V1.1 / Set 2012 - Paulo Pedreiras
27
Gesto de tarefas
O Idle Task Hook
Permite executar cdigo do utilizador na tarefa idle Usos habituais:
Executar processamento contnuo de background Colocar o processador em modo de poupana de energia Nunca deve bloquear ou suspender a sua execuo
... unsigned long UidleCycleCount=0UL; ... /* Idle task hook */ void vApplicationIdleHook( void) { UIdleCycleCount++; } STR - FreeRTOS
Restries
E.g.
V1.1 / Set 2012 - Paulo Pedreiras
28
3 - Filas
V1.1 / Set 2012 - Paulo Pedreiras
STR - FreeRTOS
29
Filas
As aplicaes em FreeRTOS so estruturadas como tarefas semi-independentes Para atingir o objetivo da aplicao as tarefas tm de cooperar/partilhar informao
E.g. sensor tem de enviar dados para controlador
Em FreeRTOS as filas so o mecanismo privilegiado de comunicao entre tarefas Deste ponto em diante passa a usar-se a designao Queue
V1.1 / Set 2012 - Paulo Pedreiras
STR - FreeRTOS
30
Filas
Caractersticas das Queues
Armazenamento de dados
Uma queue pode armazenar um conjunto finito de items de um dado tipo (tamanho fixo) Normalmente usada uma poltica de acesso do tipo FIFO.
O FreeRTOS permite mtodos alternativos.
Escrever numa queue implica cpia dos dados para a queue Ler de uma queue implica cpia e remoo dos dados da queue
Leitura consome os dados
STR - FreeRTOS 31
V1.1 / Set 2012 - Paulo Pedreiras
Filas
Caractersticas das Queues (continuao)
Acesso
As queues so uma entidade de direito prprio
No pertencem a nenhuma tarefa especfica
Vrias tarefas podem escrever na mesma queue Vrias tarefas podem ler da mesma queue Leitura de uma queue vazia causa passagem ao estado bloqued A escrita na queue desbloqueia automaticamente uma tarefa que esteja bloqueada Caso haja vrias tarefas bloqueadas, a de maior prioridade desbloqueada
STR - FreeRTOS 32
Sincronizao - leitura
V1.1 / Set 2012 - Paulo Pedreiras
Filas
Caractersticas das Queues (continuao)
Sincronizao - leitura (continuao)
As tarefas podem especificar um tempo mximo de espera (timeout)
Se este tempo expirar a tarefa passa a ready, havendo uma falha na leitura da queue
Sincronizao escrita
A escrita numa fila cheia casa a passagem ao estado blocked Quando libertado espao na queue e h vrias tarefas bloqueadas a de maior prioridade desbloqueada Tal como na leitura, possvel especificar um timeout
STR - FreeRTOS 33
V1.1 / Set 2012 - Paulo Pedreiras
Filas
Criao de uma fila
Antes de ser usada, uma queue tem de ser explicitamente criada
xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize);
uxQueueLength: mximo numero de items que a queue comporta uxItemSize: tamanho, em bytes, de cada item Retorno:
NULL - erro. Queue no criada !NULL - Handle para acesso fila
STR - FreeRTOS 34
V1.1 / Set 2012 - Paulo Pedreiras
Filas
Escrita numa queue
portBASE_TYPE xQueueSend( xQueueHandle xQueue, const void *pvItemToQueue, portTickType xTicksToWait);
xQueue: handle da queue pvItem: ponteiro para dados a escrever na fila XticksToWait: tempo mximo que tarefa poder ficar bloqueada na escrita na fila
0 (zero): retorno imediato portMAX_DELAY: timeout infinito Valor especificado em ticks. Usar portTICK_RATE_MS para efetuar converso para tempo real
V1.1 / Set 2012 - Paulo Pedreiras
STR - FreeRTOS
35
Filas
Escrita numa queue (continuao)
Retorno
pdPASS escrita com sucesso errQUEUE_FULL dados no foram escritos por queue estar cheia (timeout expirado) xQueueSendToBack()
Variantes
Equivalente a xQueueSend Dados so escritos no incio da fila
xQueueSendToFront()
V1.1 / Set 2012 - Paulo Pedreiras
STR - FreeRTOS
36
Filas
Leitura duma queue
portBASE_TYPE xQueueReceive( xQueueHandle xQueue, const void *pvBuffer, portTickType xTicksToWait);
xQueue: handle da queue pvBuffer: ponteiro para zona de memria para onde os dados sero copiados XticksToWait: timeout para bloqueio pdPASS Leitura com sucesso errQUEUE_EMPTY dados no lidos devido a queue estar vazia (timeout expirado)
STR - FreeRTOS 37
Retorno
V1.1 / Set 2012 - Paulo Pedreiras
Filas
Estado duma queue
unsigned portBASE_TYPE uxQueueMessagesWaiting( xQueueHandle xQueue);
xQueue: handle da queue Nmero de items correntemente na fila.
Retorno
V1.1 / Set 2012 - Paulo Pedreiras
STR - FreeRTOS
38
Exemplo
... /* Application global vars */ xQueueHandle xQueue; ... Void main(void){ ... xQueue = xQueueCreate(QUEUE_LENGTH, sizeof(char)); ... void vTask1(void *pvParameters) { ... while(1) { ... Tarefa xStatus = xQueueSend(xQueue,(void *)(&ledStat), portMAX_DELAY); // Send ledStat to queue peridica ... vTaskDelay(TASK1_PERIOD_MS/portTICK_RATE_MS); } } void vTask2(void *pvParameters) { ... while(1) { xStatus=xQueueReceive(xQueue, (void *)(&ledStat), portMAX_DELAY); // Read Queue (blocking) Tarefa if(xStatus == pdPASS) //Read successfuly espordica PORTAbits.RA1=ledStat; } } V1.1 / Set 2012 - Paulo Pedreiras STR - FreeRTOS
39
Filas
Passagem de tipos de dados complexos
E.g. quando uma fila contm diferentes tipos de dados
Sensor 1 queue Sensor 2 Controlador Sensor n Tipo de dado Valor
V1.1 / Set 2012 - Paulo Pedreiras
STR - FreeRTOS
40
Filas
Passagem de tipos de dados complexos (cont.)
A passagem por ponteiros permite estruturas de dados arbitrrias
... /* Application global vars */ typedef struct { unsigned char ucType; unsigned char ucValue; } xData; ... void vTask1(void *pvParameters) { xData xReceiveData; ... xStatus=xQueueReceive(xQueue, &xReceiveData,0) ... if(xReceiveData.ucType == TEMP_SENS) { ... } ...
STR - FreeRTOS
V1.1 / Set 2012 - Paulo Pedreiras
41
4 - Interrupes e Sincronizao
V1.1 / Set 2012 - Paulo Pedreiras
STR - FreeRTOS
42
Interrupes
Os sistemas embutidos tm frequentemente que responder a eventos de diversas origens que ocorrem no ambiente onde esto integrados
Chegada de um caracter, alterao do estado de uma porta, pacote que chegou a uma interface de comunicao, etc. Estes eventos esto associados a diferentes overheads de processamento, importncia e requisitos de tempo de resposta Questes:
Que mtodos de deteco de eventos Qual a quantidade de processamento que deve ser efetuada na ISR? Como devem ser comunicados s tarefas?
STR - FreeRTOS 43
V1.1 / Set 2012 - Paulo Pedreiras
Interrupes e Sincronizao
Deteo de eventos
Em caso muito simples possvel efetuar poll uma tarefa verifica periodicamente se um dado evento ocorreu (e.g. l o estado da USART para saber se chegou algum caracter)
void vTask1(void *pvParameters) { ... while(1) { ... if(USART_STAT.RxC == 1) { ... } ... vTaskDelay(TASK1_PERIOD_MS/portTICK_RATE_MS); } }
Muito ineficiente, pois normalmente os eventos ocorrem muito esparsamente Difcil determinar o perodo timo
Curto: grande overhead Longo: latncia elevada
STR - FreeRTOS 44
V1.1 / Set 2012 - Paulo Pedreiras
Interrupes e Sincronizao
Processamento diferido de interrupes
Para colmatar os problemas anteriores pode efetuar-se a deteo de eventos por interrupo (se o hardware o permitir) O processamento de uma interrupo inibe o processamento de outras interrupes (pelo menos parcialmente)
A quantidade de trabalho dentro duma ISR deve ser to reduzido quanto possvel
Mecanismo vulgarmente usado: processamento diferido de interrupes
ISR faz processamento mnimo (fast handler) e Restante processamento efetuado a nvel de tarefa (slow handler)
Tj
Slow handler
Event Tk ISR
Tk(resume)
Activate Tj
V1.1 / Set 2012 - Paulo Pedreiras
STR - FreeRTOS
45
Interrupes e Sincronizao
Semforos binrios para sincronizao
Uma das formas de ativar o slow handler consiste no uso de semforos binrios
void vSemaphoreCreateBinary(xSemaphoreHandle xSemaphore)
xSempahore handle para o semforo Nota: esta system call implementada por meio de uma macro. xSemaphore deve passar-se diretamente e no por referncia
V1.1 / Set 2012 - Paulo Pedreiras
STR - FreeRTOS
46
Interrupes e Sincronizao
Semforos binrios para sincronizao (cont.)
Tomar o semforo (operao P() na notao clssica)
portBASE_TYPE xSemaphoreTake(xSemaphoreHandle xSemaphore, portTickTime xTicksToWait)
xSemaphore handle para o semforo XticksToWait Tempo mximo de bloqueio
Uso equivalente s queues pdPASS retornou antes do timeout pdFALSE timeout expirou
Retorno
V1.1 / Set 2012 - Paulo Pedreiras
STR - FreeRTOS
47
Interrupes e Sincronizao
Semforos binrios para sincronizao (cont.)
Dar o semforo (operao V() na notao clssica)
portBASE_TYPE xSemaphoreGiveFromISR(xSemaphoreHandle xSemaphore, portBASE_TYPE *pxHigherPriorityTaskWoken)
xSemaphore handle para o semforo pxHigherPriorityTaskWoken Indica se em resultado da operao uma tarefa com prioridade superior da tarefa correntemente em execuo passou a ready. Neste caso esta system call coloca *pxHigherPriorityTaskWoken com pdTRUE. Retorno
pdPASS retornou antes do timeout pdFALSE timeout expirou
STR - FreeRTOS 48
V1.1 / Set 2012 - Paulo Pedreiras
Interrupes e Sincronizao
Semforos binrios para sincronizao (cont.)
Exemplo
static void vHandlerTask( void *pvParameters ) { while(1) { xSemaphoreTake(xBinarySemaphore, portMAX_DELAY); /* Ocorreu evento! Fazer o seu processamento */ Event_Proc ... } }
static void __interrupt vExampleInterruptHandler( void ) { static portBASE_TYPE xHigherPriorityTaskWoken; xHigherPriorityTaskWoken = pdFALSE; /* 'Give' the semaphore to unblock the task. */ xSemaphoreGiveFromISR( xBinarySemaphore, &xHigherPriorityTaskWoken ); if( xHigherPriorityTaskWoken == pdTRUE ) { ... portSWITCH_CONTEXT(); }
Invocao do escalonador dentro da ISR faz com que retorno da ISR seja feito diretamente para o slow handler
49
No limite o tempo de resposta pode ser equivalente ao processamento integral dentro da ISR V1.1 / Set 2012 - Paulo Pedreiras STR - FreeRTOS
Interrupes e Sincronizao
Semforos de contagem
O uso de semforos binrios pode levar perda de eventos
Se vrios eventos se sucederem antes de o slow handler terminar sero perdidos
Semforo binrio tem apenas dois estados!
FreeRTOS disponibiliza semforos de contagem
Semforos convencionais Para alm da contagem de eventos, so tambm usados para gesto de recursos
Inicializados com um certo valor (nmero de recursos). Tarefas bloqueiam se o contador tiver valor nulo.
V1.1 / Set 2012 - Paulo Pedreiras
STR - FreeRTOS
50
Interrupes e Sincronizao
Semforos de contagem
Antes de serem usados tm de ser criados
xSemaphoreHandle xSemaphoreCreateCounting(
portBASE_TYPE uxMaxCount, portBASE_TYPE uxInitialCount)
uxMaxCount mximo valor que o semforo pode contar (mximo nmero de eventos que podem ser mantidos em espera / mximo nmero de recursos) usInitialCount valor inicial (deve sre zero no caso de eventos / uxMAxCount no caso de recursos)
Retorno
NULL erro (falta de memria heap) !NULL - sucesso
STR - FreeRTOS 51
V1.1 / Set 2012 - Paulo Pedreiras
Interrupes e Sincronizao
Uso de queues a partir de ISR
Por vezes pode ser desejvel o uso de queues a partir de ISR
Combina sincronizao com passagem de dados!
As seguintes system calls podem ser usadas
portBASE_TYPE xQueueSendFromISR() portBASE_TYPE xQueueSendToFrontFromISR() portBASE_TYPE xQueueSendToBackFromISR()
Utilizao semelhante s suas pares , mas podem ser usadas a partir de ISR
STR - FreeRTOS 52
V1.1 / Set 2012 - Paulo Pedreiras
Interrupes e Sincronizao
Uso eficiente de queues no contexto de execuo diferida de ISR
O acesso a queues e eventual bloqueio/desbloqueio de tarefas so operaes com custos computacionais elevados Pode ser efetuado algum processamento dentro da ISR para otimizar o consumo de recursos Exemplo receo de comandos via USART
Opo 1: envia cada caracter recebido Opo 2: pr-processar localmente ISR os caracteres e colocar na queue apenas comandos inteiros
Muito mais eficiente ... Mas ateno ao impacto nas outras interrupes e tarefas
STR - FreeRTOS 53
V1.1 / Set 2012 - Paulo Pedreiras
5 Gesto de recursos
V1.1 / Set 2012 - Paulo Pedreiras
STR - FreeRTOS
54
Gesto de recursos
As tarefas executam concorrentemente e podem partilhar recursos
Hardware - portas de I/O, buffers, LCD, USART, ... Software variveis partilhadas, funes no reentrantes, ...
Se uma tarefa sofre preempo durante o acesso a um recurso pode ocorrer uma situao de inconsistncia/corrupo de dados
Necessrio garantir excluso mutua durante o acesso a recursos partilhados
void vTask2( void *pvParameters ) { ... while(1) { ... tmp=PORTA; tmp |=0x02; PORTA=tmp; ... } }
void vTask1( void *pvParameters ) { ... while(1) { ... tmp=PORTA; tmp |=0x01; PORTA=tmp; ... } }
Resultado ????
55
V1.1 / Set 2012 - Paulo Pedreiras
STR - FreeRTOS
Gesto de recursos
Critical Sections
Seco de cdigo em que a preempo de tarefas inibida Define-se colocando o cdigo entre as primitivas taskENTER_CRITICAL() e taskEXIT_CRITICAL()
Nota: inibe as interrupes que possuam prioridade acima de configMAX_SYSCALL_INTERRUPT_PRIORITY vTaskSuspendAll(); / xTaskResumeAll() Interrupes no so afetadas
O escalonador pode ser diretamente ativado e desativado
V1.1 / Set 2012 - Paulo Pedreiras
STR - FreeRTOS
56
Gesto de recursos
Critical Sections (cont)
Outras formas de implementar regies criticas
Mutex (semforo binrio)
Apenas afeta as tarefas que partilham o recurso Ateno a possveis deadlocks!!!! Acesso ao recurso efetuado por uma nica tarefa Tarefas que pretendam aceder ao recurso comunicam com a Gatekeeper, e.g. via mensagens
Gatekeeper
V1.1 / Set 2012 - Paulo Pedreiras
STR - FreeRTOS
57
6 Gesto de memria
V1.1 / Set 2012 - Paulo Pedreiras
STR - FreeRTOS
58
Gesto de memria
Funes especficas para alocao dinmica de memria
pvPortMalloc() pvPortFree() Heap_1.c: verso bsica de pvPortMalloc() e no implementa pvPortFree()
Trs implementaes
Comportamento determinstico No permite libertao de memria!
Adequado quando todos os recursos (tarefas, message queues, ...) so reservados inicialmente e se mantm durante o funcionamento do sistema
STR - FreeRTOS 59
V1.1 / Set 2012 - Paulo Pedreiras
Gesto de memria
Trs implementaes (cont)
Heap_2.c: usa algoritmo best fit para alocao e implementa pvPortFree()
No combina segmentos adjacentes
Eventuais problemas de fragmentao
Pode ser usado em tarefas que criam e removem tarefas frequentemente desde que a stack seja constante
Heap_3.c: usa cdigo derivado das bibliotecas standard malloc() e free()
Menos determinstico No sofre de problemas de fragmentao
STR - FreeRTOS 60
V1.1 / Set 2012 - Paulo Pedreiras
Bibliografia
Manual do FreeRTOS Links
http://www.slideshare.net/amraldo/free-freertos-coursetask-management http://embedded-tips.blogspot.com/2010/07/freertos-course-semaphoremutex.html
V1.1 / Set 2012 - Paulo Pedreiras
STR - FreeRTOS
61