Arquivo de 3 agosto, 2010

Sistema operacional de tempo real: faça você mesmo (II)

Quando se coloca o requisito de executar mais de uma tarefa no sistema, o problema a ser resolvido imediatamente é o de como compartilhar o processador nesta missão. A estratégia comumente adotada em sistemas com um processador só é dividir o uso do processador entre todas as tarefas, dando uma fatia de tempo para cada uma delas (chamado de time slicing) e criando uma forma de ir alternando as tarefas ciclicamente.

Isto exige que você crie um mecanismo de tempo que lhe permita, de tempos em tempos, avaliar a lista de tarefas e decidir quem irá entrar em execução (função conhecido como escalonador ou scheduler). Em geral, pendura-se uma função em um timer de alta prioridade do sistema e define-se um tempo de avaliação. Este tempo será a resolução mínima a ser usada por uma tarefa e é comumente chamado de “tick do sistema“. Por exemplo, é comum ter sistemas com tick de 10ms ou 1ms para PCs. Isto depende do que se pretende em termos de responsividade das tarefas e de quanto se quer perder de processamento executando o escalonador. Um número muito baixo pode acabar desperdiçando muito processamento no escalonar e um muito alto pode atrasar a resposta de uma tarefa.

A estratégia adotada é dependente dos recursos disponíveis na sua plataforma e, no caso do BRTOS, foi usado um watchdog  timer configurado com tick de 0,5ms, sendo que clock do sistema é de 1MHz. É possível ver isto no arquivo brtos.c. Inicialmente, pendura-se o escalonador de tarefas na interrupção de watchdog, com mostrado no fragmento de código a seguir. A forma de fazer isto vai depender do seu compilador, hardware software de suporte à placa. Lembre que estamos usado GCC para MSP430.

/* RTOS scheduler function is allocated at watchdog interrupt */
static interrupt (WDT_VECTOR)  BRTOS_Scheduler(void);

Depois, na configuração inicial do RTOS, é ajustado o tick, através de uma chamada para BRTOS_ConfigureClock(), dentro de BRTOS_Initialize():

static void BRTOS_ConfigureClock(void)
{
	/* configuring interval timer */
	WDTCTL = WDT_MDLY_0_5;
	usTicksPerSecond = 1000/0.5; /* 2k ticks per second */
}

Mas os problemas (diversão?) apenas começaram. Como fazer a troca de contexto de tarefas ? Como funciona o escalonador ? Como sair da interrupção do escalonador e voltar para o contexto de uma tarefa ? Fica para os próximos posts e, adianto: vai exigir um pouco de Assembly.

6 Comentários

Seguir

Obtenha todo post novo entregue na sua caixa de entrada.

Junte-se a 499 outros seguidores