Implementação em C++ de um escalonador de tarefas, para utilização no controlador de uma máquina de venda de bebidas

Descrição do sistema e requisitos:

  • A máquina de venda de refrigerantes fornece dois tipos de refrigerantes, denominados MEET e ETIRPS. Estes refrigerantes estão disponíveis para escolha pelo usuário a partir de duas teclas no painel com o nome dos refrigerantes. Ambos refrigerantes custam R$1,50 e existe na máquina uma fenda para inserir moedas com um sistema eletromecânico capaz de reconhecer moedas de R$1,00, R$0,50 e R$0,25, e capaz de devolver automaticamente qualquer outro tipo de moeda ou objeto não reconhecido. Além disso, durante a compra, o usuário pode desistir da transação e apertar a tecla DEV que devolve as moedas inseridas até o momento. Somente após acumular um crédito mínimo de R$1,50 o usuário pode obter um refrigerante. A devolução de excesso de moedas é automática sempre que o valor inserido antes de retirar um refrigerante ultrapassar R$1,50. Para simplificar o projeto do controlador, pode ser ignorada a composição exata das moedas inseridas na máquina, atendo-se apenas ao montante total inserido.
  • A interface de entrada e saída deve ser implementada utilizando o conceito de polimorfismo, visando a adaptação do código em C++ para diferentes interfaces. A idéia é ter uma classe “interface”, que possa assumir várias formas (várias implementações), dependendo de onde o programa for executado (ex. microcomputador; kit de desenvolvimento com microcontrolador embarcado em FPGA; kit de desenvolvimento com processador ARM; …).
  • Utilizar uma estrutura de fila para armazenar as informações sobre as vendas realizadas (log). Sempre que uma nova venda for realizada, deverá ser incluído um novo nodo na fila contendo: nome do refrigerante vendido; valor do refrigerante; e data/hora da venda (usar o clock/calendar desenvolvido durante o semestre). A qualquer instante, o operador da máquina poderá realizar as seguintes consultas no log: listar o valor total de vendas; listar a quantidade vendida de cada refrigerante; e listar o período do dia com mais vendas. Lembrar que para realizar essas operações, a fila precisará ser esvaziada (log será reinicializado), e os dados transferidos para outra estrutura de dados (uma lista, por exemplo).
  • Implementar um escalonador de tarefas, com preempção, para possibilitar a gerência da execução concorrente das operações da máquina de venda, principalmente:
    • Entrada e saída de dados (inserção de moedas, botões, fornecimento de refrigerantes, …).
    • Funcionamento da FSM de controle.
    • Operações de log (gravação do log, relatórios, …).
    • Relógio do sistema (ClockCalendar).
  • Projetar o escalonador de acordo com políticas de escalonamento adequadas para esse tipo de aplicação, justificando as decisões de projeto. O objetivo é possibilitar a execução do sistema em uma plataforma computacional sem sistema operacional.
  • Utilizar estruturas de dados do tipo listas duplamente encadeadas, para implementar as filas de tarefas apresentadas na Figura 1:
    • Tarefas que foram criadas, mas ainda não foram encaminhadas para a fila de tarefas prontas para execução.
    • Tarefas prontas para execução (ready).
    • Tarefas bloqueadas (waiting).
    • Tarefas concluídas (terminated).
  • As estruturas de dados utilizadas no desenvolvimento do escalonador devem ser implementadas por intermédio de listas encadeadas, utilizando alocação dinâmica de memória. Não devem ser utilizadas funções da STL.
  • Ao implementar as filas é importante respeitar os conceitos relacionados a esse tipo de estrutura de dados, ou seja, em uma fila só é possível realizar a inclusão no final (após o último nodo), e a leitura na frente da fila (primeiro nodo). Não devem existir facilidades para acesso aos demais nodos da fila, apenas o primeiro (leitura) e o último (escrita) nodo podem ser acessados.Caso necessite realizar alterações ou consultas nos elementos internos de uma estrutura, então deverá ser utilizada uma lista, e não uma fila.
  • As filas devem ser modeladas por intermédio de classes na linguagem C++. Devem ser definidas classes para representar os nodos, e a lista encadeada propriamente dita.
  • As filas devem ser utilizadas para armazenar apenas os blocos de controle de tarefas (Task Control Block – TCB).
  • Utilizar um timer (sugestão de período de 1 ms) para a troca de contexto (chaveamento entre tarefas das filas), de acordo com a(s) política(s) de escalonamento definida.
  • Tanto as estruturas de dados (filas, listas) quanto o TCB devem ser implementados por intermédio de classes, utilizando os diversos conceitos de C++ apresentados durante o semestre.
  • Poderá ser utilizado o conceito de threads (pthread.h) para disparar a execução concorrente das diversas tarefas, mas a política de escalonamento deverá ser implementada com o auxílio das estruturas de dados conforme apresentado na Figura 1.

Capture d’écran 2019-10-14 à 22.28.56

Figura 1. Escalonamento das tarefas de controle da máquina de venda e refrigerantes.

  • Os principais desafios para a implementação do escalonador são:
    • Definir o que será escalonado. Poderia ser, por exemplo, um escalonador de objetos, onde são escalonadas funções (métodos) de classes.
    • Definir quais informações serão armazenadas no TCB, lembrando que deverá ser desenvolvido um escalonador “alto nível”, que não possui acesso aos registradores da CPU.
    • Definir o que consiste exatamente o ponto de interrupção e reinício de uma tarefa. Por exemplo, ao ser preemptada, como saber exatamente qual ponto da execução da tarefa deverá ser retomado.
    • Como fazer para atender uma tarefa bloqueada devido aos comandos de entrada e saída (cin, cout, …), sem interromper a execução das demais tarefas? Uso de threads?
    • Definir como será realizada a contagem do tempo, e a interrupção para realizar o escalonamento das tarefas.
    • Definir quais políticas de escalonamento serão utilizadas.
  • O software final deve possuir as seguintes funcionalidades:
    1. Controle da máquina de venda de refrigerantes (recebe moedas, devolve moedas, fornece produtos, fornece troco).
    2. Escalonamento das tarefas, utilizando listas e filas como estruturas de dados.
  • Dicas e observações:
    • Desenvolver um ÚNICO software (pode ser composto por diversos arquivos .h e .cpp).
    • O software deve ser projetado de forma a ser utilizado tanto em uma placa (sistema embarcado), quanto em um microcomputador (saída na tela do computador hospedeiro).
    • Não existe necessidade de mostrar o funcionamento do software em um sistema embarcado, mas é necessário realizar a implementação (e compilação) visando também uma plataforma alvo a ser escolhida pelos alunos (exemplo: Raspberry Pi, LaunchPad, …).
    • O software precisa ser desenvolvido utilizando classes, herança, polimorfismo, e outros mecanismos de orientação a objetos, conforme discutido nas aulas da disciplina.
    • As tentativas mal sucedidas de utilização de recursos de programação da linguagem C++ no sistema embarcado alvo (devido a limitações do cross-compiler, por exemplo), devem ser relatadas, assim como as soluções adotadas.
    • Preparar uma documentação (relatório técnico) descrevendo a arquitetura do sistema, ferramentas utilizadas, e o fluxo utilizado para o desenvolvimento do software. Incluir comentários sobre a experiência ao utilizar orientação a objetos na implementação desse tipo de sistema embarcado. Quais as vantagens e desvantagens? Quais recursos foram utilizados? Quais recursos gostaria de ter utilizado, e não foi possível devido as limitações do compilador? Porquê gostaria de ter utilizado (ou usou) determinados recursos? (exemplo: Reuso de módulos? Organização do código fonte?). Quais as estratégias adotadas para resolver os desafios apontados nessa definição do projeto?  A documentação é parte fundamental da avaliação, e deverá ser preparada de forma a possibilitar futuras alterações no software desenvolvido.
    • Preparar um manual do usuário, que pode ser incluído no relatório técnico como um apêndice.
  • Avaliação e entrega:
    • Será avaliado se na implementação do programa foram utilizados, pelo menos, os seguintes conceitos de C++:
      • Herança
      • Friends
      • Template
      • Funções virtuais
      • Tratamento de exceções
      • Sobrecarga de operadores
      • Polimorfismo (com classes abstratas)
    • O trabalho de ser desenvolvido individualmente. O projeto e as soluções não devem ser compartilhadas entre os alunos, para evitar situações de plágio.
    • Deve ser utilizado o github para o controle de versão e compartilhamento dos programas.
    • Toda a documentação deve ser preparada e entregue em um único arquivo no formato PDF.
    • O software pode ser desenvolvido e apresentado em um microcomputador, porém é preciso realizar a entrega da implementação necessária para utilização em um sistema embarcado.
    • Aqueles que não pretendem executar o software na plataforma (sistema embarcado) destino, devem apresentar um relatório da compilação sem erros do programa, usando a arquitetura destino como alvo (cross-compiler). Isso é importante para mostrar que o programa não possui restrições para execução em um sistema embarcado sem sistema operacional. IMPORTANTE!!! Não serão aceitos dois programas diferentes (um para o microcomputador, e outro para o sistema embarcado). Deverá ser desenvolvido um único programa que compile/funcione nas duas plataformas. Utilizar diretivas de compilação para o pré-processador do compilador selecionar os fontes que serão utilizados para gerar o binário para a arquitetura alvo.
    • A entrega do trabalho será realizada no moodle, respeitando os prazos estabelecidos, e listados na tabela a seguir.
Data Entrega
24/10
  • Relatório incluindo:
    • Diagrama de classes (preliminar), que pode ser preparado com ferramentas disponíveis na web para desenho de diagramas como, por exemplo, yUML.
    • Funcionamento da máquina de estados (com a tabela de estados) do controlador da máquina de vendas.
    • Funcionamento do escalonador, destacando as possíveis soluções para os desafios listados nessa especificação (ex. definição do TCB, salvamento de contexto, …).
    • Descrição do sistema embarcado alvo (ex. descrição da possível placa a ser utilizada, descrição das bibliotecas necessárias para a implementação, compilador e ferramenta de desenvolvimento a ser utilizada, entre outros).
  • Software para o controlador da máquina de vendas (máquina de estados) implementado e funcionando em C++. Deve ser entregue uma versão funcional do software, sem necessidade de executar o escalonamento das tarefas. Também não é necessário entregar a funcionalidade da fila para armazenar as informações sobre as vendas realizadas (log).
  • Essa entrega será avaliada com um peso de 20% sobre a nota final do projeto.
07/11
  • Relatório incluindo:
    • Diagrama de classes (revisão).
    • Modelagem do módulo de apresentação de mensagens (estruturas de dados utilizadas, operações a ser realizadas sobre as estruturas de dados, algoritmos, …).
    • Modelagem da funcionalidade do escalonador, conforme o que será implementado em C++.
    • Estratégias de polimorfismo utilizadas para permitir a execução do programa tanto em um microcomputador, quanto no sistema embarcado alvo (ex. bibliotecas, funções, …).
  • Filas implementadas e funcionando em C++ (utilizando estruturas de dados encadeadas – listas). Nessa entrega, basta fornecer as filas funcionando, sem necessidade de atender os requisitos do trabalho.
  • Essa entrega será avaliada com um peso de 20% sobre a nota final do projeto.
21/11
  • Relatório incluindo:
    • Diagrama de classes (revisão).
    • Arquitetura do sistema.
    • Ferramentas utilizadas.
    • Fluxogramas.
    • Plano de testes, contendo as sequencias de testes utilizadas para verificar o funcionamento do programa, de acordo com os requisitos. Incluir casos de teste utilizados para mostrar se o programa atende situações de entradas de dados inválidas, e também capacidade de memória para alocação dinâmica de dados.
    • Incluir comentários sobre a experiência ao utilizar orientação a objetos na implementação desse tipo de sistema embarcado. Quais as vantagens e desvantagens? Quais recursos foram utilizados? Quais recursos gostaria de ter utilizado, e não foi possível devido as limitações do compilador? Porquê gostaria de ter utilizado (ou usou) determinados recursos? (exemplo: Reuso de módulos? Organização do código fonte?).
    • Manual do usuário (em um apêndice).
  • Escalonador de tarefas em C++, utilizando as filas implementadas com estruturas de dados encadeadas (listas), conforme os requisitos do trabalho.
  • Essa entrega será avaliada com um peso de 20% sobre a nota final do projeto.
28/11
  • Relatório final
    • Além do conteúdo incluído nas versões anteriores, essa versão final do relatório deverá conter uma análise do desempenho da execução do programa. “Desempenho” não significa apenas velocidade de execução, mas também outros parâmetros como, por exemplo, espaço ocupado, consumo de energia, entre outros. Incluir nesse relatório os parâmetros que conseguir medir (ex. dados obtidos após a compilação) e, também, parâmetros obtidos através de uma análise teórica.
  • Código fonte completo (github) e DOCUMENTADO (com comentários).
  • Demonstração do programa funcionando em um microcomputador OU em um sistema embarcado (ou em ambos).
  • Execução do plano de teste proposto, mostrando que o programa atende os requisitos.
  • Essa entrega será avaliada com um peso de 40% sobre a nota final do projeto.