Você está na página 1de 32

ELT048 - SOE

Requisitos temporais

Rodrigo Almeida
Universidade Federal de Itajubá
Revisão
● Kernel cooperativo
● Troca de processos
● Métodos de escalonamento
Exemplo
● Exemplo de kernel cooperativo
● O código apresentado pode ser compilado em
qualquer compilador C
● O kernel é composto por três funções:
● KernelInit(): Inicializa as variáveis internas
● KernelAddProc(): Adiciona processos no pool
● KernelLoop(): Inicializa o gerenciador de
processos
– Esta função possui um loop infinito pois ela só
precisa terminar quando o equipamento/placa for
desligado.
Exemplo
//return code
#define SUCESSO 0
#define FALHA 1
#define REPETIR 2

#define POOLSIZE 10
//function pointer declaration
typedef char(*ptrFunc)(void);

//process struct
typedef struct {
ptrFunc function;
} process;

process* pool[POOLSIZE];
Exemplo
char kernelInit(void){
ini = 0;
fim = 0;
return SUCESSO;
}
char kernelAddProc(process* newProc){
//checking for free space
if ( ((fim+1)%POOLSIZE) != ini){
pool[fim] = newProc;
fim = (fim+1)%POOLSIZE;
return SUCESSO;
}
return FALHA;
}
Exemplo
void kernelLoop(void){
for(;;){
//Do we have any process to execute?
if (ini != fim){
//check if there is need to reschedule
if (pool[start]->Func() == REPETIR){
kernelAddProc(pool[ini]);
}
//prepare to get the next process;
ini = (ini+1)%POOLSIZE;
}
}
}
Exemplo
● Os processos
void tst1(void){
printf("Process 1\n");
return REPETIR;
}
void tst2(void){
printf("Process 2\n");
return SUCESSO;
}
void tst3(void){
printf("Process 3\n");
return REPETIR;
}
Exemplo
void main(void){
//declaring the processes
process p1 = {tst1};
process p2 = {tst2};
process p3 = {tst3};
kernelInit();
//Test if the process was added successfully
if (kernelAddProc(p1) == SUCESSO){
printf("1st process added\n");}
if (kernelAddProc(p2) == SUCESSO){
printf("2nd process added\n");}
if (kernelAddProc(p3) == SUCESSO){
printf("3rd process added\n");}
kernelLoop();
}
Exemplo
Console Output:
---------------------------
1st process added
2nd process added
3rd process added
Ite. 0, Slot. 0: Process 1
Ite. 1, Slot. 1: Process 2
Ite. 2, Slot. 2: Process 3
Ite. 3, Slot. 3: Process 1
Ite. 4, Slot. 0: Process 3
Ite. 5, Slot. 1: Process 1
Ite. 6, Slot. 2: Process 3
Ite. 7, Slot. 3: Process 1
Ite. 8, Slot. 0: Process 3
...
---------------------------
Requisitos temporais

Na maioria dos sistemas embarcados é


necessário garantir que algumas funções
sejam executadas com uma certa frequência.
Alguns sistema podem até mesmo falhar caso
estes requisitos não sejam atingidos.
Requisitos temporais
● Tempo real
● Velocidade
● Instantâneadade
Real time

● Capacidade de um
sistema em garantir
a peridiocidade de
uma tarefa
● O importante é o
determinismo na
execução, não a
velocidade
business2community.com
Real time

● Capacidade de um
sistema em garantir
a peridiocidade de
uma tarefa
● Determinismo
Real time

● Hard real time ● Soft real time


Requisitos temporais

● Para implementar um sistema que trabalhe


com requisitos temporais:
1)Deve existir um relógio que trabalhe com uma
frequência precisa.
2)O kernel deve ser informado da frequência, ou
período, de execução de cada processo.
3)A soma dos tempos de cada processo deve
“caber” no tempo disponível do processador.
Requisitos temporais

1a condição:
● É necessário um timer que possa gerar uma
interrupção.

2a condição:
● Adicionar as informações na estrutura do
processo

3a condição:
● Testar, testar e testar.
● Em caso de falha:
– Chip mais rápido
– Otimização
Agendamento
● Agendamento dos processos:
● A utilização de um timer finito para medição de
tempo pode causar overflow
● Exemplo: agendamento de 2 processos para
10 e 50 segundos (1 bit = 1ms)
Agendamento

● E se os dois processos forem agendados


para o mesmo tempo?
Agendamento
● Suponha que o primeiro processo fosse
executado:
● Do diagrama de tempo abaixo o processo P2
está atrasado 10(s) ou foi agendado para
acontecer daqui 55(s)?
Agendamento

● Solução:
● Utilizar um contador temporizado decrescente
para cada processo ao invés de um valor de
agendamento.
● Problema:
● Cada um dos contadores devem ser
decrementados na rotina de interrupção.
● Isso é um problema pra sua aplicação?
Kernel com requisitos temporais
Kernel com requisitos temporais
● A primeira modificação é adicionar
● Um contador para cada processo
● Uma variável para armazenar o período de
execução
//process struct
typedef struct {
ptrFunc function;
int period;
int start;
} process;
Kernel com requisitos temporais
● Deve ser criada uma função de interrupção
para decrementar cada um dos contadores
dos processos
● Os detalhes intrínsecos do processo de
criação e manipulação de interrupções está
fora do escopo desta aula.
● Por facilidade será utilizado o Device
initialization
Device initialization
Device initialization
Rotina de Interrupção
Rotina de Interrupção

//colocar no MCUinit.c na função isrVrti()

#include “kernel.h”

__interrupt void isrVrti(void){

KernelClock();

//limpar a flag de interrupção


CRGFLG = 0x80;
}
Rotina de Interrupção

//colocar no kernel.c
#define MIN_INT -30000
void KernelClock(void){
unsigned char i;
i = ini;
while(i!=fim){
if((pool[i].start)>(MIN_INT)){
pool[i].start--;
}
i = (i+1)%SLOT_SIZE;
}
}

//colocar no kernel.h
void KernelClock(void);
Kernel com requisitos temporais
● A função de adição de processos deve
inicializar corretamente as variáveis
char AddProc(process* newProc){
//checking for free space
if ( ((fim+1)%POOLSIZE) != ini){
pool[fim] = newProc;
//increment start timer with period
pool[fim].start += newProc.period;
fim = (end+1)%POOLSIZE;
return SUCESSO;
}
return FALHA;
}
Kernel com requisitos temporais

● A função de execução do kernel apresenta


uma mudança maior.
● O processo de escalonamento muda de um
modelo FIFO (aula anterior) para um
escalonador baseado no menor tempo de
inicio.
if (ini != fim){
//Procurando o processo com menor tempo de inicio
j = (ini+1) % POOLSIZE;
next = ini;
while(j!=fim){
if (pool[j].start < pool[next].start){
next = j;
}
j = (j+1)%POOLSIZE;
}
//trocando as posições no pool
tempProc = pool[next];
pool[next] = pool[ini];
pool[ini] = tempProc;

while(pool[ini].start>0){
//ótimo lugar para economia de energia
}
if ( (pool[ini]->function)() == REPETIR ){
AddProc(&(pool[ini]));
}
ini = (ini+1)%POOLSIZE;
}
Exercício

● Montar um relógio binário onde cada led


pisca numa frequência diferente

4 8 segundos //Ligar o 1o led


PORTB = PORTB | 0x01;
3 4 segundos //Desligar o 1o led
PORTB = PORTB & ~0x01;
2 2 segundos
//Piscar o 1o led
1 1 segundo PORTB = PORTB ^ 0x01;

Você também pode gostar