Introdução aos Sistemas Operacionais Desenvolvimento de

Propaganda
Introdução aos Sistemas
Operacionais
Desenvolvimento de
Aplicações Embarcadas
Eleri Cardozo
FEEC/Unicamp
Aplicações Embarcadas
Aplicações embarcadas, ou sistemas embarcados, executam em
processadores instalados (embarcados) em dispositivos cuja função
precípua não é o processamento da informação. Exemplos de tais
dispositivos incluem equipamentos eletrodomésticos, robôs, veículos
e máquinas operatrizes.
Do ponto de vista do sistema operacional, o mesmo pode ser de livre
escolha do desenvolvedor, ou se apresentar como um requisito da
aplicação.
Vamos examinar 4 arquiteturas básicas de aplicações embarcadas.
Aplicações de Laço Único
A aplicação de laço único (simple control loop) consiste de uma única tarefa
que nunca será interrompida ou, no máximo, será interrompida apenas para
o tratamento de interrupções.
Estas aplicações comumente executam uma tarefa muito especfica, por
exemplo, verificar as condições operacionais de um equipamento.
Em muitos casos tais aplicações embarcadas executam em processadores
mais simples como microcontroladores.
Aplicações de Laço Único
Arduino Due
Atmel ATmega2560:
Flash 256k bytes (8k usada pelo bootloader) - memória de programa
(~ área de texto)
SRAM 8k bytes - memória de variáveis (~ área de dados/pilha)
EEPROM 4k byte - memória persistente
O Arduino não possui SO, mas um bootloader que instala e executa
programas transferidos via porta serial (USB).
Aplicações de Laço Único
Aplicações Controladas por
Interrupções
Nesta arquitetura a aplicação consiste de uma tarefa principal e de um
conjunto de tratadores de interrupção. A tarefa principal pode se reduzir a
um laço com uma única função tipo wait. Neste caso, toda a lógica da
aplicação está dispersa nos tratadores de interrupção.
Aplicações que seguem esta arquitetura usualmente executam em
hardware especializado onde as interrupções estão associadas a valores
de grandezas físicas, por exemplo, uma temperatura que ultrapassa um
valor limite.
O tratamento de interrupções pode ser preemptivo ou não preemptivo.
No caso preemptivo associa-se prioridades às interrupções e um tratador
de interrupção pode sofrer preempção para que outro associado a uma
interrupção de prioridade mais alta possa ser invocado.
No caso não preemptivo, uma interrupção é escalonada para tratamento
caso outra interrupção esteja sendo tratada.
Aplicações Multitarefa Cooperativas
Nesta arquitetura a aplicação consiste de um conjunto de tarefas executadas de
forma não preemptiva e escalonadas segundo a política FIFO.
Tarefas são interrompidas apenas para o tratamento de interrupções, tratamento
este também não preemptivo.
O sistema operacional TinyOS foi concebido para esta arquitetura de aplicações.
TinyOS possui uma linguagem de programação associada, nesC, com sintaxe
muito semelhante à linguagem C.
nesC é uma linguagem orientada a componentes. Um componente provê interfaces
e declara as interfaces de outros componentes que utiliza. nesC define tarefas,
equivalentes a processos.
TinyOS não suporta proteção de memória e modos do processador (ou seja, o
sistema operacional e as aplicações possuem os mesmos privilégios).
A vantagem desta arquitetura de aplicações é a inexistência de condições de
corrida e a desvantagem é o escalonamento de tarefas que recai sobre o
desenvolvedor.
Aplicações Multitarefa Preemptivas
Nesta arquitetura a aplicação consiste de um conjunto de tarefas escalonadas
de forma preemptiva. Para estas aplicações o sistema operacional deve ter
núcleo preemptivo e oferecer mecanismos de sincronização.
Tarefas podem tratar interrupções, executar ações periódicas, ou processar
informação em função do estado da aplicação. Tarefas são implementadas
como threads escalonadas por prioridades.
Usualmente, o sistema operacional é baseado em um núcleo preemptivo como
o Linux e executa em um processador com um ou mais cores.
A vantagem desta arquitetura de aplicações é a flexibilidade no mapeamento
das funcionalidades da aplicação em tarefas correspondentes, bem como a
atribuição de prioridades a estas tarefas. A desvantagem é a dificuldade em se
prever e evitar a ocorrência de deadlocks, estarvação de tarefas e inversões de
prioridades.
Aplicações Multitarefa Preemptivas
Raspberrry PI:
• Alimentação de 5V
• 512 MB RAM
• 2 USBs
• Vídeo HDMI
• Vídeo analógico
• Fast Ethernet
• Interface I2C
• Interface MIPI (câmera)
• Linux (Raspiam - Debian)
Aplicações Embarcadas
Bootloader
Laço Único
Vetor de Interrupções
Controladas por Interrupções
Legenda:
Tarefa
Controle
Escalonador FIFO
Escalonador Preemptivo
Multitarefas Cooperativas
Multitarefas Preemptivas
Arquiteturas em Camadas
Nem sempre uma aplicação embarcada emprega unicamente um dos
modelos de aplicação descritos anteriormente. Na prática, uma
combinação destes modelos é comum.
Para compor estes modelos uma arquitetura em camadas pode ser
empregada. Em uma arquitetura em camadas as funcionalidades da
aplicação são organizadas em camadas de tal forma que uma camada
oferece serviços por meio de interfaces bem definadas à camada
superior.
O próprio sistema operacional emprega esta arquitetura. Arquiteturas
em camadas são empregadas em redes de computadores, aplicações
Web e padrões de projeto de software (design patterns).
Exemplo de Arquiteturas em
Camadas
Aplicações-fim
Camada de Aplicação
Cliente/Servidor
Camada Executiva
Troca de Mensagens
Camada de Controle
de Tempo Real
Hardware
Camada de Controle de Tempo Real
A camada de controle de tempo real interage diretamente com o hardware, que
pode ser considerado uma camada abaixo desta (mas não pertencente à
arquitetura).
A interação com o hardware se dá por meio de registradores, barramentos e
portas, por exemplo, interface serial RS-232, barramento I2C (Inter-Integrated
Circuit) e barramento SPI (Serial Peripheral Interface Bus).
A camada de controle de tempo real tem suas funções comumente
implementadas em microcontroladores como o Arduino e executa operações
com período da ordem de milisegundos. Operações típicas incluem
controladores (por exemplo, PID), filtragem, emissão de alarmes e geração de
sinais (por exemplo, PWM)
Esta camada provê uma interface para a camada executiva (via porta serial
RS-232, rede Ethernet, etc.), bem como define um protocolo de interação
tipicamente baseado em passagem de mensagens.
Camada Executiva
As funções da camada executiva são comumente realizadas em processadores
de pequeno e médio porte tais como o Raspberry Pi, com sistema operacional
instalado (Linux, na maioria dos casos).
Esta camada executa operações com período da ordem de centenas de
milisegundos. Tais operações são implementadas com processos e threads
(comumente em C/C++) e utilizam as funções providas pela camada de controle
de tempo real. Operações típicas da camada executiva incluem sensoriamento,
estimação, atuação, proteção e fusão de dados.
Para a implementação desta camada as seguintes funcionaliadades do
sistema operacional são utilizadas: threads, escalonamento por prioridades,
bibliotecas dinâmicas, sistema de arquivos em memória, programação de
módulos.
A camada executiva provê uma interface de mais alto nível para a camada de
aplicação baseada, tipicamente, em protocolos de comunicação cliente/servidor
tais como RPC (Remote Procedure Call) e HTTP.
Camada de Aplicação
A camada de aplicação oferece funções de alto nível que são utilizadas
pelas aplicações-fim. Note que esta camada não implementa as aplicaçõesfim, mas sim facilidades para a implementação conveniente e eficaz destas
aplicações.
As funções presentes nesta camada são dependentes do domínio de
aplicação. Por exemplo, no domínio da robótica móvel, estas funções
incluem algoritmos de localização, de mapeamento, de planejamento de
trajetória e de locomoção. Tais funções executam em processadores mais
poderosos (ou mesmo em uma nuvem) e são codificadas em linguagens de
alto nível como o Matlab, Python e Java.
Desta forma, a interface que esta camada oferece para as aplicações-fim
são baseadas em componentes, frameworks e classes de objetos, que são
abstrações de software de mais alto nível comparado com protocolos
cliente/servidor e passagem de mensagens.
Exemplo de Aplicação Embarcada
Controlar um robô móvel com movimentos musculares da face
(piscadas).
TCC da aluna Julia Amaya, publicado no XI Simpósio Brasileiro
de Automação Inteligente (SBAI 2013).
Módulo EMG Shimmer
(executa TinyOS)
Exemplo de Aplicação Embarcada
Os sensores Shimmer utilizam um microcontrolador MSP 430 (TI) e
interface de comunicação Bluetooth e IEEE 802.15.4 (rádio de curta
distância utilizado em redes de sensores sem fio).
Este sensores empregam o sistema operacional TinyOS e sua linguagem
de programação nesC. nesC define tarefas (tasks), equivalentes a
processos. Uma tarefa pode escalonar (postar) outras tarefas. TinyOS é
um sistema operacional simples:
• Não preemptivo (tarefas executam até completarem), exceto tarefas
que tratam interrupções;
• Tarefas são escalonadas com política FIFO;
• Sem proteção de memória;
• Sem modos do processador (SO e aplicações posuem os mesmos
privilégios);
• Sem chamadas de sistema (o interfaceamento com o SO é via nesC).
Exemplo de Aplicação Embarcada
Tipicamente, tarefas no TinyOS lêem dados dos sensores
presentes no módulo com determinada frequência, executa
algumas operações (por exemplo, cálculo de tendência), e
envia as leituras para um nó sorvedouro. O envio pode ser
hop-by-hop utilizando um protocolo de roteamento. O
sorvedouro é um nó com capacidade maior de processamento (ex, PC) que realiza filtragem, fusão, correlação, etc.,
dos dados transmitidos pelos nós sensores.
Na aplicação em questão, o nó sorvedouro é um smartphone
com o sistema operacional Android.
Exemplo de Aplicação Embarcada
Android é um sistema operacional desenvolvido sobre o nucleo
do Linux.
Aplicações em Android são desenvolvidas em Java e
executam um uma máquina virtual Java que por sua vez
executa em um processo Linux.
Android provê uma série de Frameworks (classes Java para
telefonia, apresentação de mídias, etc.) que são utilizados no
desenvolvimento de aplicações denominadas atividades
(activities).
Atividades podem utilizar múltiplas threads e não têm acesso
às chamadas de sistema do Linux. Recebem um callback de
pausa/reinício quando perdem/ganham "visibilidade".
Exemplo de Aplicação Embarcada
A detecção de piscada
intencional é realizada
via threshold. Taxa de
acerto: 96%.
Exemplo de Aplicação Embarcada
A seguinte convenção foi adotada. Uma ação é iniciada e
terminada com o mesmo comando (piscada).
• piscada do olho direito: o robô gira para a direita a 7 o/s;
• piscada do olho esquerdo: o robô gira para a esquerda a 7 o/s;
• piscada de ambos os olhos: o robô se locomove a 150 mm/s.
Exemplo de Aplicação Embarcada
Camada de Aplicação
Bluetooth
Aplicação Robótica
ARIA API
HTTP
WiFi
Processador de Bordo
RS-232
ARCOS
Camadas Executiva e de Controle
Microcontrolador
protocolo de
mensagens
Exemplo de Aplicação Embarcada
A aplicação ilustrada utiliza 3 sistemas operacionais: TinyOS, Android e
Linux.
A programação de aplicações nestes sistemas seguem modelos
diferentes: tarefas, atividades e threads/processos.
É imprescindível conhecer as características dos sistemas operacionais.
Por exemplo:
• tarefas TinyOS são sequenciais (escalonamento FIFO) e portanto não
necessitam de sincronização;
• atividades Android executam com permissões de usuários diferentes
(por que?);
• threads Linux devem ser sincronizadas porque o núcleo é preemptivo.
A maioria das aplicações são embarcadas ou possuem componentes
embarcados. Sistemas operacionais para estas aplicações são diferentes
dos tradicionais e devemos conhecer suas restrições e capacidades para
utilizá-los adequadamente.
Download