kernel cooperativo
DESCRIPTION
Desenvolvimento de um kernel cooperativo para utilização em sistemas embarcadosTRANSCRIPT
ELT048 - SOE
Kernel Cooperativo
Rodrigo AlmeidaUniversidade Federal de Itajubá
Revisão● Processos
typedef int (*ptrFunc)(void* param);
//código antigotypedef struct { char* nomeDoProcesso; ptrFunc funcao; int prioridade; int tempo;}process;
Exercício● Adaptar o código e executá-lo no kit de
desenvolvimento.● Reunir todas as funções relacionadas à
operação com o buffer circular numa biblioteca.
● Utilizar o debugger da placa para verificar o funcionamento do programa.
Exercíciovoid main (void){ process p1 = {"F1\n",1,func1}; process p2 = {"F2\n",2,func2}; long int i; MCU_init(); ini = 0; fim = 0; PTJ = 0x00; for(;;){ addProc(p1); addProc(p2); exec(); for(i=0;i<10000;i++); removeProc(); exec(); for(i=0;i<10000;i++); removeProc(); }}
int func1(void* param){ PORTB=0xF0;}int func2(void* param){ PORTB=0x0F;}
Inicialização do HW
Kernel● Na área de computação o kernel é a parte
do código responsável por implementar e gerenciar a interface entre o hardware e a aplicação.
● Os recursos de hardware mais críticos neste quesito são o processador, a memória e os drivers.
Projeto de um kernel
Kernel● Um kernel possui três responsabilidades
principais:● Gerenciar e coordenar a execução dos
processos através de algum critério● Manusear a memória disponível e coordenar o
acesso dos processos a ela● Intermediar a comunicação entre os drivers de
hardware e os processos
Kernel● Gerenciamento dos processos
● Deve levar em conta um critério para o escalonemento do processo: tempo de execução, prioridade, criticidade, “justiça”, etc.
● Os processos devem ser “armazenados” de modo a ficarem facilmente disponíveis ao kernel.
● O kernel deve prover funções para o gerenciamento destes processos: adicionar, remover, pausar, etc.
Kernel● Gerenciamento da memória disponível
● A gestão do espaço disponível para cada processo é de responsabilidade do kernel
● Um ponto crítico é garantir que cada processo só possa acessar sua região de memória. Isto só pode ser feito se houver um hardware dedicado a este ponto: MMU
Kernel● Intermediar a comunicação entre os drivers
de hardware e os processos● O kernel deve prover uma camada de acesso
ao hardware.● Esta camada é responsável por implementar as
questões de permissão e segurança, como também padronizar as chamadas de aplicação.
Gestão dos processos● A gestão dos
processo é feita através de um buffer circular (process pool).
● O acesso a este buffer deve ser restrito ao kernel.
http://learnyousomeerlang.com/building-applications-with-otp
Gestão dos processos● O exemplo a seguir apresenta um modelo de
gerenciamento de processos.● Note que o pool é implementado como um buffer
circular utilizando a mesma estrutura das aulas anteriores
● Uma das poucas diferenças é a mudança do pool para ser um vetor de ponteiros para a struct process● Isto permite uma manipulação mais rápida e
simples dos elementos do pool● Uma movimentação nas posições envolve apenas
uma cópia de ponteiros e não da estrutura inteira.
//definição do ponteiro de funçãotypedef int (*ptrFunc)(void* param);
//definição da estrutura processotypedef struct { char* nome; void* ptr; ptrFunc func;} process;
//definição do pool#define POOLSIZE 10process* pool[POOLSIZE];//a utilização de ponteiros de processo//facilita a manipulação dos processos
Gestão dos processos
//função de adição de “process” no poolvoid addProc(process nProcesso){ //checagem de espaço disponível if ( ((fim+1)%POOLSIZE) != ini){ //Atualização da posição atual buffer[fim] = nProcesso; //incremento da posição fim = (fim+1)%(POOLSIZE); }}//função de remoção de um “process” do poolvoid removeProc (void){ //checagem se existe alguem pra retirar if ( ini != fim ){ //incremento da posição ini = (ini+1)%(POOLSIZE); }}
Gestão dos processos
Escalonador● É o responsável por escolher qual é o próximo
processo a ser executado.
● Existem alguns parâmetros a serem considerados:● Throughtput: quantidade de processos por tempo.● Latência:
– Turnaround time – tempo entre o inicio e fim de um processo.
– Response time: valor entre uma requisição e a primeira resposta do processo.
● Fairness / Waiting Time – conceder uma quantidade de tempo igual para cada processo.
Escalonador● First in first out● Shortest remaining time● Fixed priority pre-emptive scheduling● Round-robin scheduling● Multilevel queue scheduling
EscalonadorScheduling algorithm CPU
OverheadThroughput
Turnaround time
Response time
First In First Out Low Low High Low
Shortest Job First Medium High Medium Medium
Priority based scheduling
Medium Low High High
Round-robin scheduling
High Medium Medium High
Multilevel Queue scheduling
High High Medium Medium
EscalonadorOperating System Preemption Algorithm
Amiga OS Yes Prioritized Round-robin scheduling
FreeBSD Yes Multilevel feedback queue
Linux pre-2.6 Yes Multilevel feedback queue
Linux 2.6-2.6.23 Yes O(1) scheduler
Linux post-2.6.23 Yes Completely Fair Scheduler
Mac OS pre-9 None Cooperative Scheduler
Mac OS 9 Some Preemptive for MP tasks, Cooperative Scheduler for processes and threads
Mac OS X Yes Multilevel feedback queue
NetBSD Yes Multilevel feedback queue
Solaris Yes Multilevel feedback queue
Windows 3.1x None Cooperative Scheduler
Windows 95, 98, Me Half Preemptive for 32-bit processes, Cooperative Scheduler for 16-bit processes
Windows NT (XP, Vista, 7, 2k)
Yes Multilevel feedback queue
Escalonadores● Considerações para o ambiente embarcado
● Com a escassez de recursos computacionais, um algoritmo muito complexo pode minar a capacidade de processamento muito rapidamente. Algoritmos mais simples são preferidos.
● Os sistemas de tempo real possuem algumas necessidades que em geral só são satisfeitas por escalonadores “injustos” que possam privilegiar alguns processos. Ex: priority based scheduler
Kernel● Preempção
● Permite ao kernel pausar um processo para executar um segundo sem que as variáveis e fluxo de código do primeiro sejam alteradas.
● Necessita de suporte de hardware por interrupções
● Só é programado em assembly
Kernel● Cooperativo
● É necessário que os processos terminem dando oportunidade para outros processos serem executados pelo processador
● Loops infinitos podem travar todo o sistema● Pode ser programado inteiro em C e não
necessita de hardware especial
Kernel● Reagendamento de processos
● Para um kernel cooperativo é importante que todos os processos terminem voluntariamente para ceder espaço na CPU para os outros processos.
● Nos casos em que o processo precisa ser executado constantemente ele deve ser reagendado na CPU
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.
//return code#define SUCCESS 0#define FAIL 1#define REPEAT 2
//function pointer declarationtypedef char(*ptrFunc)(void);
//process structtypedef struct {
ptrFunc function;} process;
process* pool[POOLSIZE];
Exemplo
char kernelInit(void){ini = 0;fim = 0;return SUCCESS;
}char kernelAddProc(process newProc){
//checking for free spaceif ( ((fim+1)%POOL_SIZE) != ini){
pool[fim] = newProc;fim = (fim+1)%POOL_SIZE;return SUCCESS;
}return FAIL;
}
Exemplo
void kernelLoop(void){int i=0;for(;;){
//Do we have any process to execute?if (ini != fim){
printf("Ite. %d, Slot. %d: ", i, start);//check if there is need to rescheduleif (pool[start]->Func() == REPEAT){
kernelAddProc(pool[ini]);}//prepare to get the next process; ini = (ini+1)%POOL_SIZE;
i++; // only for debug;}
}}
Exemplo
void tst1(void){ printf("Process 1\n"); return REPEAT;}void tst2(void){ printf("Process 2\n"); return SUCCESS;}void tst3(void){ printf("Process 3\n"); return REPEAT;}
● Os processos
Exemplo
void main(void){//declaring the processesprocess p1 = {tst1};process p2 = {tst2};process p3 = {tst3};kernelInit();//Test if the process was added successfullyif (kernelAddProc(p1) == SUCCESS){
printf("1st process added\n");}if (kernelAddProc(p2) == SUCCESS){
printf("2nd process added\n");}if (kernelAddProc(p3) == SUCCESS){
printf("3rd process added\n");}kernelLoop();
}
Exemplo
Console Output:---------------------------1st process added2nd process added3rd process addedIte. 0, Slot. 0: Process 1Ite. 1, Slot. 1: Process 2Ite. 2, Slot. 2: Process 3Ite. 3, Slot. 3: Process 1Ite. 4, Slot. 0: Process 3Ite. 5, Slot. 1: Process 1Ite. 6, Slot. 2: Process 3Ite. 7, Slot. 3: Process 1Ite. 8, Slot. 0: Process 3...---------------------------
Exemplo
Exercício● Criar os arquivos kernel.c, kernel.h,
kernel_prm.h e kernel_types.h.● Adaptar os códigos apresentados para a
placa.● Testar o reagendamento dos processos.● Criar um processo para ligar um segmento
do display de cada vez (PORTB).● Criar um segundo processo para mudar de
display (PTJ)