Olá caros leitores, continuando com a série de artigos sobre o MQX RTOS, neste terceiro artigo iremos falar um pouquinho sobre Escalonador (Scheduling).

O Scheduling ou Escalonador é um algoritmo responsável por escolher qual a próxima tarefa (task) será executada. É complacente ao padrão POSIX.4 e fornece como opções de funcionamento: FIFO Scheduling (baseado em prioridades e a tarefa ativa permanece em funcionamento enquanto outra com maior prioridade ainda não estiver ativa), Round Robin (parecido com o modelo anterior e também baseado em prioridade, mas possui um tempo de execução chamado de “Time-slice” que não pode ser estrapolado) e Explicit (usando listas de tasks – tasks queues). Para detalhes de cada tipo, sugere-se que seja lido o Manual do Usuário MQX RTOS.

Escalonador

O RTOS pode interromper a execução de uma tarefa para executar uma outra tarefa nas seguintes situações:

Como já foi dito anteriormente o escalonador é o algoritmo responsável de decidir qual tarefa deve ser executada em seu determinado momento e por quanto tempo previamente estabelecido.

No MQX RTOS as prioridade de uma tarefa vão 0 a N, onde 0 corresponde à tarefa com maior prioridade. É recomendado configurar as tarefas da aplicação a partir da prioridade 09, pois o MQX RTOS utiliza tarefas com maiores prioridades.

O escalonador do MQX RTOS cria uma fila de tarefas prontas (Ready) para serem executadas em cada nível de prioridade. E sempre será executada a tarefa de maior prioridade pronta.

Política de Escalonamento

O MQX RTOS contém duas políticas de escalonamento para tarefas de mesma prioridade, FIFO (Firts-in, First-out) e Round Robin.

Por padrão o MQX RTOS adota FIFO, podendo ser alterada para Round Robin individualmente para cada tarefa.

Alterar a politica de escalonamento para o Round Robin basta atribuir os seguintes atributos no Templates de Tarefas (Task Template List). MQX_HAS_TIME_SLICE: habilita o escalonador do tipo Round Robin. E o valor Time Slide (tempo de execução) em milissegundos.

A seguir exemplo de Templates de Tarefas. Uma tarefa com atributo do escalonamento Round Robin e com time-slice de 50 milissegundos.

const TASK_TEMPLATE_STRUCT  MQX_template_list[] =
{
   { MAIN_TASK, main_task, 0xC00, 10, "main_task", MQX_AUTO_START_TASK,MQX_HAS_TIME_SLICE,0,50},
   { 0L,        0L,        0L,    0L,  0L,         0L }
}; 

FIFO

Tarefa que esteja utilizando a política de escalonamento no modo FIFO apenas será interrompida caso uma tarefa com maior prioridade fique pronta para execução. Tarefas de mesma prioridade ficarão bloqueadas até o momento que a tarefa em execução libere a CPU.

Escalonador no MQX RTOS

O MQX RTOS possui recurso API para liberar a CPU. A função “_sched_yield(void)” libera a CPU e coloca a tarefa ativa no final da fila das prontas. A seguir o exemplo de uso da API para liberar a CPU.

/* libera a CPU */
//void _sched_yield(void);

/* Exemplo de aplicação */ 
void tarefa_A(uint32_t data)
{
	while (1) 
	{
		processo();
		_sched_yield();
	}
}

Vantagens:

Desvantagens:

Round Robin

O escalonador Round Robin é semelhante ao FIFO, mas se diferencia no seguinte aspecto. Cada tarefa na política de escalonamento Round Robin tem um determinado tempo de execução, esse tempo é chamado de Time-Slice. O valor padrão do time-slice é dez vezes o valor do período da interrupção do Timer.

O MQX RTOS permite que o valor do time-slice possa ser alterado em cada tarefa através do atributo DEFAUT_TIME_SLICE. O MQX RTOS permite também alterar o período e execução da tarefa utilizando as  API’s _sched_set_rr_interval () e _sched_set_rr_interval_ticks().

A seguir temos os protótipos das funções das API’s sitadas anteriormente:

uint32_t _sched_set_rr_interval(
 _task_id task_id,		/* ID da tarefa */ 
 uint32_t ms_interval)		/* Valor do time-slice em milissegundos */

uint32_t _sched_set_rr_interval_ticks(
 _task_id task_id,				/* ID da tarefa */ 
 MQX_TICK_STRUCT_PTR new_rr_interval_ptr,	
 MQX_TICK_STRUCT_PTR old_rr_interval_ptr)       

A seguir temos um exemplo de uso de API, onde é alterado o time-slice da tarefa em execução.

if(_sched_set_rr_interval(_task_get_id(), 50) != MQX_OK)
{
	printf("\n\rFalha em alterar o time-slice da tarefa ");
        _task_block();
}

Para uma tarefa ser escalonada com a política de Round Robin o atributo MQX_HAS_TIME_SLICE deve estar habilitado. Para habilitar o mesmo, deve abrir o arquivo “lite_config.h” e alterar MQX_HAS_TIME_SLICE para 1. E em seguida deve compilar o projeto que se encontra o arquivo.

/*
** When MQX_HAS_TIME_SLICE is defined as 1,
** then code is compiled in to support time sliced tasks.
*/
#ifndef MQX_HAS_TIME_SLICE
#define MQX_HAS_TIME_SLICE 1
#endif

Neste modo de operação, a tarefa terá o direito a uma fatia de tempo de execução do sistema (Time-Slice) e será interrompida ao final deste tempo para a execução de outra tarefa de mesma prioridade.

Quando expira o tempo do time-slice, o MQX RTOS salva o contexto da tarefa em execução. E em seguida posiciona a tarefa ao final da fila das tarefas prontas (Ready). O MQX RTOS executa a próxima tarefa da fila de tarefas prontas (Ready). A figura abaixo ajuda a ilustrar o processo.   

Escalonador no MQX RTOS

Vantagens:

Desvantagens:

Conclusão 

O MQX RTOS disponibiliza duas políticas de escalonamento para tarefas de mesma prioridade, que são FIFO (Firts-in, First-out) e Round Robin. O mesmo disponibiliza diversas APIs para trabalhar com o escalonador.

Neste artigo também foram apresentadas as principais características das políticas de escalonamento. Fica a cargo do desenvolvedor decidir qual escalonador utilizar em sua aplicação de acordo com sua necessidade.

Para saber mais sobre MQX RTOS

Este artigo teve como referência os slides do treinamento do Sergio Prado sobre MQX RTOS.

Referências

MQX™ Software Solutions

MQX™ RTOS for Kinetis SDK v1.3

MQX Lite ™ RTOS – Reference Manual

Treinamento do Sergio Prado sobre o MQX RTOS

Fonte das Imagens: NXP MQX™ RTOS