• Nenhum resultado encontrado

Desenvolvimento de um µkernel SMP de tempo-real para plataformas ARM multicore

N/A
N/A
Protected

Academic year: 2020

Share "Desenvolvimento de um µkernel SMP de tempo-real para plataformas ARM multicore"

Copied!
125
0
0

Texto

(1)

Raphael Gomes Gonçalves

Universidade do Minho

(2)
(3)

Dissertação de Mestrado

Ciclo de Estudos Integrados Conducentes ao Grau de

Mestre em Engenharia Eletrónica Industrial e Computadores

Trabalho efectuado sob a orientação do

Professor Doutor Adriano Tavares

Universidade do Minho

(4)
(5)

Agradecimentos

As minhas primeiras palavras de agradecimento são direcionadas aos meus pais, Luís Gonçalves e Agostinha Gomes, e a minha irmã, Eliana Gonçalves, pelo apoio, disponibilidade e motivação que que sempre foram prestados durante o meu per-curso académico, pois sem eles a realização desta dissertação não seria possível.

Ao meu orientador, Professor Doutor Adriano Tavares, pelo apoio e confiança depositada em mim para a concretização deste trabalho.

Ao meu “co-orientador”, Mestre Sandro Pinto, pela excelente orientação, motiva-ção, conhecimentos transmitidos, e sobretudo pela disponibilidade e paciência nos momentos cruciais desta dissertação.

Ao grupo Embedded System Research Group (ESRG) do Departamento de Eletró-nica Industrial da Universidade do Minho, que me acolheu e disponibilizou todas as condições necessárias para a elaboração desta dissertação.

A minha amiga Andreia Faria, pela paciência e ajuda prestados durante esses de 4 anos de trabalho em conjunto.

Ao Diogo Lima e ao Carlos Fernandes, pela amizade e pela entreajuda que sempre foram demonstrados ao longo desta dissertação.

Aos meus restantes amigos e colegas de curso, pela alegria e amizade demonstrada ao longo destes percurso académico.

E por último agradeço aos meus amigos de longa data Fábio, Zeka, Poças, Joana, Ângela, Armanda, Zé Manel e Carlos pela amizade ao longo destes anos.

(6)
(7)

Resumo

Vivemos numa era onde a aposta na tecnologia multicore é cada vez maior. Moti-vado pelo facto das arquiteturas singlecore terem atingido o limite da viabilidade do aumento do desempenho à custa do aumento da frequência de relógio, tornou-se portanto inevitável a migração para as arquiteturas multicore. Naturalmente, esta também atingiu os dispositivos embebidos, que cada vez mais procuram in-cluir novas e mais complexas funcionalidades e simultaneamente reduzir o consumo energético.

Contudo, o desenvolvimento de software (bare-metal) para este tipo de arquitetu-ras não é uma tarefa simples, muito porque a mudança de paradigma sequencial para paralelo não é trivial. Garantir requisitos como o time-to-market torna-se es-sencial num mercado cada vez mais competitivo, e por isso, recorre-se à utilização de sistemas operativos para simplificar e acelerar o desenvolvimento das aplicações. Os sistemas operativos que suportam multicore seguem sobretudo duas filosofias: AMP (Asymmetric Multiprocessing) e SMP (Symmetric Multiprocessing). A pri-meira abordagem caracteriza-se por apresentar um enorme overhead de memória, já que consiste na replicação da imagem do kernel pelos diferentes cores. Por sua vez, a segunda abordagem, como requer a inclusão de sincronismo no acesso aos recursos partilhados, pode comprometer o cariz de tempo-real do sistema.

Neste sentido, a presente dissertação consiste no desenvolvimento de um sistema operativo de tempo-real (RTOS) baseado em microkernel e com suporte SMP. O conjunto de funcionalidades obrigatórias de um RTOS será implementado a partir da análise de três soluções existentes de referência (FreeRTOS, µC-OS/II,

µTKernel). O suporte SMP será cuidadosamente desenhado para minimizar a

necessidade de sincronismo, bem como garantir a escalabilidade da solução.

Palavas-chaves: Sistema operativo, RTOS, multicore, SMP, ARM, Sistemas

(8)
(9)

Abstract

We live in the age where the applications of the multicore technology are growing. Motivated by the fact that the singlecore architecture has reached the limit of increasing performance at the expense of increasing clock frequency, the migration for multicore architecture became inevitable. Naturally, this reached the embed-ded field that increasingly sought to include new and complex functionalities and simultaneously reduce the power consumption.

However, the software development, in bare-metal, for this architecture is not simplistic task, since the change from sequential paradigm to parallel is not trivial. Guaranteening time-to-market requirements, becomes essential in a market that is more and more competitive, and for this, we resort to the utilization of operating systems to simplify and accelerate the application development. Operating systems that support multicore , have essencially two philosophies: AMP (Asymmetric Multiprocessing) and SMP (Symmetric Multiprocessing). The first approach is characterized by presenting a huge memory overhead, since it has a replicated image of the kernel in all cores. In turn, the second approach requires the inclusion of synchronize mechanisms in access of shared resources, that may compromise the real-time nature of the system.

In this sense, the present dissertation consists of the development of one real-time operating system (RTOS) based in microkernel and with SMP support. All obligatory functionalities of RTOS will be implemented based on the analyses of three existing reference solutions (FreeRTOS, µC-OS/II, µTKernel). The SMP support will be carefully designed to minimize the necessity of synchronization, as well as ensuring the scalability of the solution.

(10)
(11)

Conteúdo

1 Introdução 1 1.1 Contextualização . . . 1 1.2 Motivações e Objetivos . . . 2 1.3 Organização da Dissertação . . . 4 2 Estado da Arte 7 2.1 Sistemas Embebidos . . . 7 2.2 Sistemas Operativos . . . 9

2.2.1 Arquitetura de Sistemas Operativos . . . 9

2.2.2 Sistemas Operativos de Tempo-Real . . . 10

2.3 Suportes ao Multicore . . . . 19 2.3.1 Asymmetric multiprocessing . . . . 19 2.3.2 Symmetric multiprocessing . . . . 20 2.4 Soluções de RTOS . . . 21 2.4.1 µC/OS-II . . . . 22 2.4.2 µTKernel . . . . 22 2.4.3 FreeRTOS . . . 23 3 Especificação do Sistema 25 3.1 Arquitetura da ARM . . . 25 3.1.1 Introdução . . . 25 3.1.2 ARM Cortex-A9 . . . 26 3.2 Ambiente de Desenvolvimento . . . 31

3.2.1 Xillinx ISE Desing Suite . . . 31

3.2.2 ARM Fast Models . . . 32

3.3 Arquitetura do RT-ARM(M)OS . . . 33

3.3.1 Tarefas . . . 34

(12)

3.3.3 Heap . . . . 39

3.3.4 Mutexes . . . 40

3.3.5 Singlecore vs Multicore SMP . . . . 41

4 Implementação do RT-ARM(M)OS 45 4.1 Componentes básicos de implementação . . . 45

4.1.1 Convenções . . . 45 4.1.2 Erros . . . 49 4.1.3 Estrutura de Ficheiros . . . 50 4.2 Inicialização do Kernel . . . . 52 4.2.1 Configurações do OS . . . 52 4.2.2 Mapa da Memória . . . 54 4.2.3 Sequência do Boot . . . 56 4.3 Gestor de Tarefas . . . 58 4.3.1 Criar Tarefa . . . 58 4.3.2 Iniciar Tarefa . . . 60 4.3.3 Eliminar Tarefa . . . 61 4.3.4 Terminar Tarefa . . . 62

4.3.5 Terminar e Apagar Tarefa . . . 63

4.3.6 Mudar de Prioridade . . . 65 4.3.7 Suspender Tarefa . . . 66 4.3.8 Retomar Tarefa . . . 68 4.4 Escalonador . . . 69 4.4.1 Bitmap . . . . 69 4.4.2 Dispatch . . . . 72 4.4.3 SwitchTask . . . 74 4.5 Heap . . . . 77 4.5.1 Malloc . . . . 77 4.5.2 Free . . . 78 4.6 Mecanismos de Sincronização . . . 80 4.6.1 Criar Mutex . . . . 80 4.6.2 Apagar Mutex . . . . 81 4.6.3 Bloquear Mutex . . . . 82 4.6.4 Desbloquear Mutex . . . . 85 5 Avaliação 87 5.1 Ferramentas de Avaliação . . . 87

(13)

5.1.2 Size . . . 88 5.2 Avaliação RT-ARM(M)OS . . . 88 5.2.1 Footprint de Memória . . . 88 5.2.2 Desempenho . . . 89 5.3 RT-ARM(M)OS vs FreeRTOS . . . 98 6 Conclusões 101 6.1 Conclusão . . . 101 6.2 Trabalho Futuro . . . 102 Bibliografia 103

(14)
(15)

Lista de Figuras

2.1 Exemplos da utilização de sistemas embebidos soft e hard real-time 8 2.2 Arquiteturas dos Sistemas Operativos: Monolítico vs Microkernel . 10

2.3 Diferença de resposta: soft real-time (a) hard real-time (b) . . . . . 11

2.4 Diferentes estados das tarefas . . . 12

2.5 Exemplo de preempção no escalonamento Round Robin. . . . 13

2.6 Diferentes divisões de memória cada uma com diferentes tamanhos . 15 2.7 Tarefas a pedir acesso ao recurso. . . 16

2.8 Inversão de prioridade. . . 17

2.9 Enviar e receber mensagens a partir da queue . . . 18

2.10 Gestão de mensagens com semáforos. . . 19

2.11 Arquitetura AMP . . . 20

2.12 Arquitetura SMP . . . 21

3.1 Processador Cortex-A9 . . . 27

3.2 Conjunto dos registos ARM . . . 29

3.3 Program status register (PSR). . . . 30

3.4 Diagrama de blocos do modelo FVP_VE Cortex-A9x2 . . . 33

3.5 Ilustração da TCB do RT-ARM(M)OS. . . 34

3.6 Estados presentes no RT-ARM(M)OS. . . 36

3.7 Representação HPF e FCFS. . . 38

3.8 Estrutura Ready task do RT-ARM(M)OS. . . . 39

3.9 Estrutura da heap do RT-ARM(M)OS. . . . 40

3.10 Estrutura do mutex do RT-ARM(M)OS. . . . 41

4.1 Arquitetura de software do RT-ARM(M) OS. . . . 51

4.2 Layout das secções da memória. . . . 55

4.3 Sequência do boot SMP. . . . 56

4.4 Sequência da inicialização do RT-ARM(M)OS. . . 57

(16)

4.6 Fluxograma: API K_TM_TaskStart. . . 60

4.7 Fluxograma: API K_TM_TaskDele. . . 61

4.8 Fluxograma: API K_TM_TaskEnd. . . 63

4.9 Fluxograma: API K_TM_TaskEndAndDele. . . 64

4.10 Fluxograma: API K_TM_TaskChangPrio. . . 65

4.11 Fluxograma: API K_TM_TaskSus. . . 67

4.12 Fluxograma: API K_TM_TaskRes. . . 68

4.13 Representação do bitmap. . . . 70

4.14 Fluxograma: Dispatch . . . 73

4.15 Fluxograma: Dispatch (Continuação). . . 75

4.16 Fluxograma: SwitchTask. . . 76

4.17 Fluxograma: SwitchTask (Continuação). . . 77

4.18 Fluxograma: API K_MM_Malloc. . . 78

4.19 Fluxograma: API K_MM_Free. . . 79

4.20 Fluxograma: API K_MX_CreateMutex. . . 80

4.21 Fluxograma: API K_TM_TaskRes. . . 81

4.22 Fluxograma: API K_MX_LockMutex. . . 83

4.23 Fluxograma: API K_MX_LockMutex (Continuação). . . 84

4.24 Fluxograma: API K_MX_UnlockMutex. . . 85

4.25 Fluxograma: API K_MX_UnlockMutex (Continuação). . . 86

5.1 Evolução do desempenho . . . 98

(17)

Lista de Tabelas

3.1 Modos de execução do processador Cortex-A9 . . . 28

3.2 Tabela API do gestor de tarefas . . . 37

4.1 Identificação de cada camada. . . 46

4.2 Identificação dos serviços da camada do kernel . . . . 47

5.1 Footprint de memória do RT-ARM(M)OS . . . 89

5.2 Avaliação da API K_TM_TaskCreat. . . 90

5.3 Avaliação da API K_TM_Start_Task. . . 90

5.4 Avaliação da API K_TM_TaskDele. . . 91

5.5 Avaliação da API K_TM_TaskEnd. . . 91

5.6 Avaliação da API K_TM_TaskEndAndDele. . . 92

5.7 Avaliação da API K_TM_TaskSus. . . 93

5.8 Avaliação da API K_TM_TaskRes. . . 93

5.9 Avaliação da API K_TM_TaskChangePrio. . . 94

5.10 Avaliação da API K_MM_Malloc. . . 94

5.11 Avaliação da API K_MM_Free. . . 95

5.12 Avaliação da API K_MX_CreateMutex. . . 95

5.13 Avaliação da API K_MX_DeleteMutex. . . 95

5.14 Avaliação da API K_MX_LockMutex. . . 96

5.15 Avaliação da API K_MX_UnlockMutex. . . 96

(18)
(19)

Lista de Listagens

1 Estrutura dos cabeçalhos dos ficheiros . . . 48

2 Estrutura de comentários das funções . . . 48

3 Definição dos tipos de dados . . . 49

4 Definição de erros . . . 50

5 Configuração do número de tarefas. . . 52

6 Configuração do número de prioridades. . . 52

7 Configuração da stack das tarefas. . . . 52

8 Confirmação do tamanho mínimo das stacks. . . . 53

9 Configuração do tamanho de cada bloco da heap. . . . 53

10 Configuração do número de mutexes . . . . 53

11 Configuração do número de CPU . . . 53

12 Configuração do número de CPU . . . 54

13 Configuração singlecore ou SMP. . . . 54

14 Estrutura tTask_Data. . . 58

15 Função para ativar bit no bitmap . . . 70

16 Função para limpar o bit no bitmap . . . . 71

17 Função para procurar o mais significativo bit no bitmap ( máximo 32 prioridades) . . . 71

(20)
(21)

Capítulo 1

Introdução

Neste capítulo pretende-se contextualizar a presente dissertação, bem como apre-sentar a motivação e os objetivos centrais a serem atingidos. O capítulo termina com uma breve descrição da organização da dissertação.

1.1

Contextualização

Os sistemas embebidos estão cada vez mais enraizados na sociedade. Os avanços na tecnologia de microprocessadores continuam a abrir novos campos de aplica-ções, permitindo hoje em dia, a utilização de sistemas embebidos para controlar a maior parte dos pequenos e grandes dispositivos tecnológicos. Estes estão presen-tes nas diversas áreas, tais como a medicinal, a militar, a indústria automóvel e de aviação, a aeroespacial ou até nos dispositivos eletrónicos de consumo

(smartpho-nes, tables, leitores de música,...). O enraizamento nestas áreas deve-se muito às

suas características: pequenos e leves, de baixo consumo, elevados desempenhos e programáveis. Esta última característica, talvez seja a mais importante, devido à possibilidade de programar o sistema para diferentes propósitos.

Entretanto, a rápida evolução das tecnologias eletrónicas e de computadores, per-mitiu a introdução dos sistemas operativos, idealizando-os como um componente essencial e necessário de um sistema embebido [5]. Programar sistemas embebidos nem sempre é fácil, principalmente quando se está a programar em bare-metal que exige um estudo profundo do hardware, que por sua vez, pode comprometer requi-sitos como time-to-market. A utilização de sistemas operativos - componente de

(22)

software que gere e partilha os recursos de um sistemas computacional [6] -

per-mite ao programador abstrair-se da camada do hardware e aproveitar os serviços disponibilizados pelo mesmo para uma melhor gestão dos recursos. Por outro lado, outra das vantagens da utilização de um SO, é o multikasking, que assim, permite agrupar várias aplicações num único sistema embebido.

Contudo, devido aos poucos recursos de um sistema embebido e da porventura pressão dos mercados para o desenvolvimento de aplicações que exigem tempo-real, levou à utilização dos RTOS (sistema operativo de tempo-real). Os RTOS distinguem-se dos sistemas operativos de propósito geral, pois estes são eficientes, compactos para sistemas com poucos recursos e são especificamente desenhados para ter respostas em tempo-real [6]. Existem várias vantagens com a utilização de um RTOS nestes sistemas, como por exemplo, na otimização no desenvolvimento do software. Com a crescente complexidade do software das novas aplicações e a pressão do time-to-market[7] é estritamente necessário reduzir o ciclo de de-senvolvimento, assim a utilização dos RTOS, facilita o programador abstrair-se da camada de hardware, permitindo assim um código mais limpo, uma eficiente gestão dos recursos e uma melhor distribuição e sincronização das tarefas [4, 6].

As exigências ao nível do processamento das novas aplicações motivou a migração dos sistemas embebidos para arquiteturas multicore, por se traduzirem num melhor desempenho e menores consumos de energia em relação a arquitetura single-core [2, 3, 4]. A utilização das novas arquiteturas multicore nos sistemas embebidos obrigou à extensão dos RTOSes de forma a dar suporte a multicore. Para tirar o máximo proveito do hardware, foi necessário desenvolver mecanismos para permitir a execução em simultâneo de várias tarefas nos diferentes cores [8, 9]. As filosofias mais abordadas para este tipo de arquitetura são sobretudo o AMP (asymmetric

multiprocessing), onde existe uma cópia do kernel para cada core mas que por

sua vez aumenta o overhead de memória, e SMP (symmetric multiprocessing), caracterizando-se pela inclusão de sincronismo no acesso aos recursos partilhados, podendo comprometer o cariz de tempo-real do sistema [3, 10].

1.2

Motivações e Objetivos

A arquitetura dos sistemas operativos atuais seguem sobretudo duas filosofias:

monolithic kernel ou microkernel. Atualmente os mais conhecidos são os que usam

(23)

estes apresentam grande desempenho mas que por sua vez o seu elevado tamanho torna num sistema muito complexo, inseguro e muito vulnerável a bugs muito por causa de cada componente do sistema operativo serem dependentes uns dos outros [11, 12]. A outra filosofia, microkernel, contém outras características, tais como menor overhead de memória, isolamento das falhas dos componentes do sistema operativo, flexibilidade e escalabilidade.

Entretanto, grande parte dos sistemas operativos que requerem tempo-real (RTOS), são baseado no microkernel. Os serviços considerados críticos (ex:device drivers) que contraem grande parte dos bugs de um sistema operativo, estão presentes no espaço do utilizador, permitindo a isolamento do serviço na ocorrência de bug, de forma a não comprometer o sistema. Contudo, as novas arquiteturas

multi-core exigem aos RTOS alterações a nível de suporte. Existem duas abordagens:

SMP(Symmetric Multiprocessing) e AMP (Assymmetric Multiprocessing). A abor-dagem SMP permite um menor footprint de memória e uma melhor relação entre performance e consumo de energia. Estas vantagens devem-se à utilização de um único sistema operativo a controlar os diversos cores, logo, não existe replicação de sistemas operativos em cada core como acontece nos sistemas AMP [13]. Por outro lado, o controlo dos cores permite que seja possível distribuir as diferentes tare-fas pelos diferentes cores beneficiando a escalabilidade do sistema, ou até mesmo, suspender cores no caso de não serem necessários, permitindo uma melhor gestão do consumo energético do sistema [14]. Mas esta abordagem bem como qualquer outra tem as suas desvantagens. A partilha dos vários recursos pelos diferentes

cores presentes no hardware, necessita de mecanismos de sincronização de forma a

eliminar os conflitos no caso de múltiplos core solicitarem o mesmo recurso. Con-tudo, a complexidade deste mecanismo pode isto levar a um aumento do overhead caso não consiga acompanhar as necessidades dos vários cores.

É neste contexto que a presente dissertação se propõe no desenvolvimento de um sistema operativos de tempo-real (RTOS) com suporte a SMP para arquiteturas ARM multicore. Os objetivos que se pretendem atingir são os seguintes:

• Desenvolver e caracterizar o RTOS para single-core. A implementação terá que conter os serviços mínimos requeridos pelo microkernel (gestor de tarefas, gestor de memória, escalonador e mecanismo de sincronização);

• O segundo objetivo passa pela criação de um suporte SMP para o RTOS desenvolvido. Esta terá que apresentar o menor footprint de memória e o melhor mecanismo de sincronização permitindo assim reduzir o overhead do

(24)

sistema.

• O último objetivo passa pela avaliação/caracterização final do RTOS

1.3

Organização da Dissertação

Este documento é constituído por seis capítulos. Inicia com uma introdução e uma contextualização do trabalho, e posteriormente são apresentados as motivações e os objetivos desta dissertação.

O segundo capítulo apresenta a fundamentação teórica dos conceitos abordados na dissertação, desde aos sistemas embebidos, os sistemas operativos tradicionais e aos sistemas operativos de tempo-real. Para além desses conceitos, também são abordados os suportes dados pelo sistema operativo ao multicore, o AMP e o SMP. O capítulo termina com a descrição de três sistemas operativos de tempo-real existentes no mercado.

O terceiro capítulo começa com uma introdução geral das arquiteturas ARM, passando depois para a descrição do processador Cortex-A9. A próxima secção apresenta o ambiente de desenvolvimento, constituído por todas as ferramentas utilizadas para a implementação do RTOS. Para terminar, é especificada a arqui-tetura do RTOS a implementar, especificando os seus serviços e das diferenças as abordagens seguidas para sistema singlecore e multicore SMP.

O quarto capítulo descreve a implementação do RTOS. Inicia com a apresentação dos componentes básicos de implementação, descrevendo as convenções utilizadas, os erros que o sistema emite e a sua estrutura de ficheiro. Posteriormente, apresenta as várias configurações disponíveis do RTOS, o mapa de memória e a sequência do boot utilizada. Para terminar, são apresentadas todas as API implementadas no RT-ARM(M)OS.

No quinto capítulo são apresentados os resultados experimentais dos testes reali-zados. Inicia com a introdução das ferramentas utilizadas e, posteriormente são apresentadas as avaliações dos desempenhos dos serviços implementados, e uma avaliação do desempenho do sistema no modo singlecore e dual-core. Termina o capítulo com uma comparação do desempenho do gestor de tarefas do RTOS implementado com o FreeRTOS.

(25)

assim como são referidas algumas sugestões para trabalho futuro, visando melhorar e expandir o trabalho desenvolvido.

(26)
(27)

Capítulo 2

Estado da Arte

A presente dissertação enquadra-se no desenvolvimento de um sistema operativo de tempo-real com suporte a processadores multicore. Desta forma, torna-se funda-mental efetuar uma revisão bibliográfica e descrever o estado da arte das principais temáticas inerentes à mesma. Sendo assim, na secção 2.1 é abordado o conceito de sistemas embebidos e a utilidade de arquiteturas multicore para este tipo de siste-mas. Posteriormente, na secção 2.2, é feita uma descrição dos sistemas operativos e das suas arquiteturas monolithic kernel e microkernel, bem como a definição de tempo-real nestes sistemas. A secção 2.3 introduz e explica o conceito de multicore nos sistemas embebidos, descrevendo as duas principais filosofias seguidas. Final-mente, a secção 2.4 apresenta e descreve suncitamente algumas soluções relevantes de sistemas operativos de tempo-real.

2.1

Sistemas Embebidos

As necessidades computacionais que tem vindo a aparecer nos sistemas eletrónicos permitiu a presença dos chamados sistema embebidos. Apesar de não existir uma definição precisa sobre os sistemas embebidos, grande parte traduzem-no num sistema computacional integrado em outros sistemas com propósito de exercer um conjunto de funções restritas. Contudo, a evolução da tecnologia permitiu alargar as restrições destes sistemas. As necessidades de utilizar sistemas computacionais pequenos e de baixo consumo nos diversos sistemas eletrónicos, permitiu ampliar o número de funções exigidas num sistema embebido, discordado assim ao seu propósito inicial.

(28)

Existem dois conceitos usados em sistemas embebidos, o soft real-time e o hard

real-time. O soft real-time é utilizado em grande parte de sistemas de consumo,

como sistemas áudios, televisores, eletrodomésticos, em que a necessidade de criar

deadline a certos eventos não é crítica. Por outro lado, o hard real-time é usado

em outras áreas que premeiam a fiabilidade, como sistemas aeronáuticos, aeroes-paciais, na medicina, nos automóveis. Estes requerem um sistema completamente

real-time, caso contrário, o não cumprimento do deadline, pode ser catastrófico [1].

Hard Real-Timer Soft

Real-Timer

Figura 2.1: Exemplos da utilização de sistemas embebidos soft e hard real-time

A introdução de novas e mais complexas aplicações, revolucionou a arquitetura destes sistemas, permitindo a introdução das arquiteturas multicore. Esta é uma arquitetura que tem vindo a ganhar cada vez mais popularidade e está em cons-tante evolução, isto porque se baseia no paralelismo entre cores permitindo o pro-cessamento em paralelo, melhorando assim o desempenho e diminuindo o consumo de energia do sistema.

Contudo, estas arquiteturas têm as suas desvantagens. A paralelização dos cores aumentou a complexidade do hardware implicando num estudo mais profundo para os programadores destes sistemas. A complexidade está na partilha dos recursos pelos diferentes cores, necessitando assim de mecanismos de sincronização para o acesso de determinados recursos, impedindo assim, que ocorra mais que um acesso em simultâneo. Outra das dificuldades está no processamento do código, pois este tem que ser analisado para que cada segmento de código seja distribuído pelos diferentes cores sem que estes sejam dependentes de outros, isto é, a utilização de funções com retorno para o argumentos da outras, não podem ser processadas por diferentes cores em simultâneo.

(29)

2.2

Sistemas Operativos

Um sistema operativo pode ser definido simplificadamente como uma camada de

software que permite criar uma ligação entre as aplicações usadas pelo utilizador e

o hardware do sistema a ser utilizado, permitindo assim ao utilizador e ao progra-mador abstrair-se do hardware que está utilizar. Esta camada é uma componente fundamental, pois este gere todas as operações e os vários dispositivos de hardware presentes no sistema. Basicamente o objetivo de um sistema operativo é simplificar a tarefa do programador, disponibilizando recursos e meios para uma execução de múltiplos programas de forma simplificada, organizada e eficiente.

2.2.1

Arquitetura de Sistemas Operativos

Os sistemas operativos são divididos em duas camadas, a camada do utilizador e a camada do kernel (núcleo). A diferença de importância entre cada processo originou a criação de camadas de modo a que processos de uma camada tenham privilégios em relação a processos de outra camada. Sendo assim, a camada com privilégio passa pela camada do kernel pois esta é constituída pelas partes mais críticas do sistema operativo e a camada sem privilégios passa pela camada do utilizador. Neste sentido, existem dois modelos arquiteturais que permitem carac-terizar os sistemas operativos: monolíticos e microkernel.

Na figura 2.2, primeira arquitetura, monolítica, os serviços como o gestor de tarefas, gestor de memória, device drivers, sistema de ficheiros, etc., estão incorporados no

kernel e organizados em camadas, em que cada camada só pode comunicar com

camadas adjacentes. Desta forma, a camada inferior começa com as gestões mais básicas, como o gestor de tarefas e de memória, a camada seguinte, está presente o gestor de I/O e os device drivers, as duas camadas superiores pertencem ao IPC (comunicação entre processos) e os ficheiros do sistema. A inclusão dos vários serviços no kernel traz alguns inconvenientes tal como o elevado tamanho do kernel requerendo uma avultada quantidade de memória. Quando existe um bug no sistema torna-se muito difícil e a perda de muitas horas a fazer o debug ou quando se pretende adicionar um novo recurso, torna-se muito moroso, pois é necessário recompilar todo o kernel. Sendo assim, podemos concluir que é uma arquitetura de difícil manutenção e extensibilidade.

(30)

arquite-Sistema Operativo Monolitico Sistema Operativo baseado no

Microkernel

Aplicação Sistema de Ficheiros Comunicação entre Processo (IPC)

Gestor de Tarefas,Gestore de Memória hardware Aplicação Bibliotecas Sistema de Ficheiros

Gestor de Tarefas, Escalonador, IPC, Gestor de Memória

hardware Device Drivers ... Espaço do kernel Espaço do Utilizador

Figura 2.2: Arquiteturas dos Sistemas Operativos: Monolítico vs Microkernel

tura anterior, pois apresenta outra estratégia de redução de serviços presentes no

kernel, transferindo os outros serviços para a camada do utilizador. Sendo assim,

o kernel é constituído pelos chamados serviços básicos, como o escalonador, gestor de memória e a comunicação entre processos, garantindo a esses serviços uma exe-cução privilegiada. Os outros serviços, como o sistema de ficheiro, device drivers migraram para a camada do utilizador sendo estes considerados processos nor-mais. Como a comunicação entre estes serviços deixou de ser direta, foi necessária a criação de mecanismos de comunicação. Estes mecanismos denominados por mensagens, semelhante à arquitetura cliente/servidor, permite aos serviços comu-nicarem com o microkernel. Caso a mensagem seja válida, é garantido acesso ao hardware. Basicamente, esta arquitetura apresenta um kernel de tamanho redu-zido, permitindo uma fácil manutenção, e extensibilidade, pois basta acrescentar os serviços na camada do utilizador sem a necessidade de ter que recompilar o

kernel [15, 18].

2.2.2

Sistemas Operativos de Tempo-Real

Os sistemas operativos de tempo-real são utilizados para vários propósitos tais como em sistemas de controlo ou no processamento de dados onde estes requerem

(31)

tempo-real. A principal característica deste sistema está no cumprimento de certas

deadlines. Existem dois tipos de RTOS: o soft e o hard real-time (figura 2.3).

Sistemas áudio utilizam o soft real-time pois no sistema em que se insere é tolerável uma falha de cumprimento de uma deadline, mas em sistemas como aeronáuticos o não cumprimento de uma deadline pode tornar-se fatal, por isso a utilização hard

real-time torna-se importante porque promove o determinismo e a satisfação de

todos os deadlines [18]. Deadline t v(t) Deadline t v(t) (a) (b)

Figura 2.3: Diferença de resposta: soft real-time (a) hard real-time (b)

Sistemas como estes são valorizados pela rapidez e previsibilidade de resposta e não na quantidade de tarefas realizadas num determinado tempo. A maior parte destes sistemas optam por três comportamentos: escalonamento e mecanismos que permitem a execução prioritária de tarefas de alta prioridade; previsibilidade na sincronização entre as tarefas, permitindo saber o tempo e duração necessária de cada execução; e ter um comportamento determinístico [6]. A junção destes comportamentos e a minimização das latências de interrupções e das comutações entre tarefas torna a implementação destes sistemas muito complexo.

Gestor de Tarefas

Uma grande vantagem de ter um sistema operativo é a possibilidade de correr várias aplicações em simultâneo. O multitasking, é um processo utilizado que permite o escalonamento e comutação pelos CPU das várias tarefas presentes no sistema operativo dando essa sensação que estão a correr em simultâneo. O TCB (task control block), uma estrutura de dados que contém informações referentes a cada tarefa. Como informações básicas está o seu contexto ( program counter e registos com contextos), o seu nome ou número de identificação, o seu estado e a

(32)

sua prioridade. A importância de guardar o contexto de cada tarefa, deve-se ao escalonamento das tarefas. Estas podem ser interrompidas durante a sua execução, levando assim à necessidade de guardar as informações necessárias para permitir executar a tarefa no ponto que foi interrompida (figura 2.4). As informações estão relacionados com o conteúdo presente em cada registo de CPU utilizados, na posição da stack que pertence a dita tarefa e na posição anterior do program

counter no momento da interrupção. Este processo é designado por context switch.

Inativa Disponível para execução Em execução Pendente Tarefa criada Em espera por um evento Context switch Evento disponível Tarefa eliminada Tarefa Preempted Tarefa eliminada

Figura 2.4: Diferentes estados das tarefas

O gestor de tarefas é um serviço que disponibiliza ferramentas para a criação, manutenção e eliminação de tarefas. Este é responsável pela inicialização e gestão da TCB de cada tarefa. Contudo, o gestor de tarefas varia consoante o sistema operativo. O número máximo de tarefas disponíveis pode estar limitado pela memória (de código e de dados) ou pelo número máximo definido pelo sistema, o número de estados existentes para cada tarefa e o seu tipos de escalonamento também pode variar.

O gestor de tarefas pode restringir as tarefas em prioridades fixas ou em prioridades dinâmicas. Prioridades fixas, o sistema não permite que a tarefa possa mudar de prioridade, sendo que esta durará até ao seu fim de vida. Prioridades dinâmicas, o gestor de tarefas permite alterar a prioridade da tarefa permitindo assim conjugar

(33)

os momentos onde é mais importante que essa tarefa seja execute e vice-versa [21, 20].

Escalonador

Existem vários algoritmos de escalonamentos que podem variar consoante o pro-pósito do sistema operativo. Sistemas operativos que se baseiam no algoritmo HPF (Highest Priority First) baseiam-se num escalonamento por prioridade. A prioridade das tarefas varia consoante a sua importância: tarefas de maior prio-ridade prevalecem sobre as tarefas de menor prioprio-ridade, e estas só executam no término de tarefas de maior prioridade. A atribuição da prioridade neste tipos de escalonamentos deve ser cuidada para não acontecer o chamado starvation. Este fenómeno pode ocorrer no caso de tarefas em loop terem maior prioridade que outras, impossibilitando assim que a tarefa de menor prioridade seja executada.

O Round Robin é outro algoritmo de escalonamento. Este é usado na maior parte dos sistemas, sendo usado como algoritmo de desempate para o escalonamento de tarefas com prioridade iguais. Baseia-se no estado de cada tarefa, dando-lhe uma execução sequencial dos vários estados existentes no sistema até ao seu fim de execução. Contudo, este escalonamento é muito usado com um time slicing, figura 2.5. Em cada tarefa é dado um tempo limite de execução. A expiração desse tempo obriga a tarefa a suspender a sua execução dando oportunidade da execução de outras tarefas pendentes ou sem estarem inicializadas.

Prioridade Tarefa A Tarefa B Tarefa A Tarefa C Tarefa A Tarefa B Time slice t - Fim da tarefa - Ação preemptive

Figura 2.5: Exemplo de preempção no escalonamento Round Robin.

(34)

tam-bém é usado na existência de tarefas com a mesma prioridade. Esta filosofia é mais simples que a anterior, baseia-se também nos estados mas o seu escalona-mento é baseado na primeira tarefa que entra no estado de RUN ou de READY obtém maior precedência. Contudo chamadas ao sistema podem facilitar a mudar a relação de precedências entre tarefas com a mesma prioridade [21, 20].

Gestor de Temporização

A maior parte dos sistemas operativos necessitam de temporizadores, tanto para um funcionamento a nível do kernel com a nível das aplicações. Este serviço ofe-rece ao sistema e às aplicações, um maior controlo com a utilização de interrupções periódicas na forma de delays ou de timeouts. Uma dessas necessidades está pre-sente no escalonamento por Round Robin com time-slice. Este serviço auxilia o escalonador para utilização de timeouts com finalidade de interromper uma tarefa no caso destas se tratarem de tarefas em loop.

A utilização deste serviço está baseada num timer geral chamado de Clock Tick. Este é usado para a frequência geral do sistema sendo usado para aumentar ou diminuir a resolução das aplicações. A frequência pode ser ajustada consoante o propósito da aplicação, pois a utilização de frequências altas do tick permite uma maior resolução mas como consequência pode aumentar o overhead do sistema.

Neste sentido, o gestor de temporização disponibiliza um número de serviços de gestão de tempos, como delays ou suspensão depois de “N” ticks, delays de se-gundos ou milissese-gundos para um propósito específico, obter o valor do tick, ou atribuir o valores ao tick ou entre outros tipos funcionalidades que podem ser exigidas a um temporizador [21, 20].

Gestor de Memória

A necessidade de algumas aplicações requisitarem blocos de memória exigiu a introdução de um gestor de memória. Fazer a gestão da memória em si não é algo trivial. Geralmente o uso de funções como o malloc() e free() é usado de forma não determinística, criando assim fragmentações de memória. Chama-se fragmentação de memória ao desenvolvimento de descontinuidades de pequenos blocos de memória livre na memória do sistema. Isto pode-se tornar perigoso em sistemas embebidos de tempo-real, pois leituras erradas ou perdas de dados podem

(35)

corromper o seu funcionamento.

Uma das maneiras de contornar as descontinuidades de memória resume-se à di-visão da memória em pequenos blocos iguais e agrupá-los com intuito de formar partições de memória contínua (figura 2.6). Este mecanismo permite ao kernel alocar as aplicações para uma partição, possibilitando organizar e guardar o con-texto dessa mesma, num bloco contínuo de memória. Assim, à eliminação de uma aplicação, resume-se a eliminação da partição, e não na eliminação de pequenos blocos memória descontínuos. Estes dois tipos de eventos, alocação e eliminação de partições, já se podem considerar determinísticos, pois geralmente é possível prever quando vão ser eliminados ou criadas partições de aplicações.

Tamanho da partição

Tamanho do bloco

Partição #1 Partição #2 Partição #3

Figura 2.6: Diferentes divisões de memória cada uma com diferentes tamanhos

Contudo, partições podem conter diferentes tamanhos. Isto acontece porque não existe aplicações iguais e cada aplicação tem os seus requisitos mínimos de memó-ria. Por isso, cada aplicação deve saber o espaço necessário de memória que irá precisar para ser feita a alocação da partição e esta deverá ser apresentada num bloco contínuo[21, 20].

Sincronização

Os serviços de sincronização permitem a gestão de recursos partilhados. Estes re-cursos partilhados são considerados secções críticas e estão tipicamente na forma de variáveis (estáticas ou globais), estruturas de dados, ou registos de

(36)

dispositi-vos de input/output. Esta necessidade deveu-se ao ambiente multitasking com a conveniência de tarefas ou interrupções poderem comunicar ou partilhar recursos de forma segura entre elas. Os mecanismos mais conhecidos que permitem fazer a gestão do acesso exclusivo a determinados resursos são: (i) desativação das in-terrupções, (ii) semáforos e (iii) mutexes. Contudo, estes mecanismos têm que ser cuidadosamente usados, garantindo que cada tarefa tenha acesso exclusivo aos dados, evitando assim a contenção e corrupção dos dados. O primeiro mecanismo, desabilitar e habilitar interrupções, não é muito aconselhável para sistemas de tempo-real, pois mesmo usando para aceder a dados de forma muito rápida pode ter impacto na latência das interrupções.

Esperar pelo semáforo() Pode aceder ao buffer

Fim do semáforo()

Esperar pelo semáforo() Pode aceder ao buffer

Fim do semáforo() Buffer Tarefa B Tarefa A

Figura 2.7: Tarefas a pedir acesso ao recurso.

O segundo mecanismo, semáforos, são divididos em dois tipos: semáforos binários e semáforos contadores. Como o seu nome indica, os semáforos binários contém apenas dois valores: 0 e 1. Por outro lado, os semáforos contadores dependem da quantidade de bits que têm disponíveis. A escolha sobre o tipo de semáforos depende do número tarefas que necessitam do acesso ao mesmo tempo a um certo tipo de recurso. A funcionalidade do semáforo serve para sinalizar um pedido de acesso a um recurso. Imagine-se, por exemplo, que um determinado dado está “fechado à chave” e nesse preciso momento, uma tarefa em execução necessita dessas informações para poder avançar no seu processo. Esta, com a utilização do semáforo, faz um pedido e espera até poder obter a “chave” para abrir o acesso aos dados como está apresentado na figura 2.7.

Entretanto, este tipo de sincronização em sistemas de tempo-real baseado na pre-emptividade pode originar um fenómeno designado de inversões de prioridade. Isto acontece quando tarefas de diferentes prioridades requisitam o mesmo

(37)

re-curso. Uma tarefa com prioridade alta pode ser posta em espera devido a um recurso não estar disponível por este já ter sido requisitado por uma tarefa de prioridade menor. É possível dizer que a tarefa de prioridade alta teve que reduzir a sua prioridade, para a mesma prioridade da tarefa de prioridade menor. Por esse mesmo motivo, este método não é aconselhado para sistemas com requisito de

deadlines. O exemplo da figura 2.8 retrata esse fenómeno: (1) a tarefa C de menor

prioridade está a ser executada e pede ao semáforo;(2) a tarefa A de maior priori-dade interrompe a tarefa C e começa a ser executada; (3) a tarefa A tenta obter o semáforo;(4) a tarefa C interrompe a tarefa A para libertar o semáforo, mas no preciso momento a tarefa B entra em execução deixando a tarefa C pendente;(5) a tarefa C volta a ser executada e liberta o semáforo;(6) a tarefa de maior prioridade volta a ser executada obtendo o semáforo [21, 20].

Prioridade Tarefa C Tarefa A Tarefa B t Prioridade Invertida (1) (2) (3) (4) (5) (6)

Figura 2.8: Inversão de prioridade.

A situação da inversão de prioridade pode ser resolvida com a utilização de mutex. Se fosse utilizado um mutex no exemplo anterior, tarefa de menor prioridade pas-saria a ter o valor de prioridade igual à tarefa que necessitava do mesmo recurso até libertar o recurso. Terminado, voltaria a prioridade inicialmente dada. Con-tudo, este mecanismo apresenta também as suas desvantagens: deadlock. Isto pode ocorrer no seguimento de mais do que uma tarefa estar à espera de um recurso que está a ser usado por outra tarefa.

(38)

Mensagens

Como anteriormente descrito, tarefas e ISR partilham recursos, e consequente-mente a partir desses recursos podem trocar informações entre elas. Chama-se

inter-task communication a troca de informações entre tarefas ou ISR. Esta troca

de informações pode ser feita de duas formas: por variáveis globais ou por mensa-gens. A partir de variáveis globais a troca de informações é executada passando a informação nas variáveis globais, contudo, não existe mecanismos que informem da existência de troca de informação, a menos que sejam utilizados sinais ou então que seja verificado periodicamente uma determinada flag. O conceito de envio de informação por mensagem está baseado na troca de informação a partir do intermediário chamado de “message queue”, figura 2.9.

ISR Receber() Enviar () Enviar () Message queue Tarefa B Tarefa A

Figura 2.9: Enviar e receber mensagens a partir da queue

Message queue é um objeto alocado no kernel que disponibiliza mecanismo para

as tarefas poderem criar uma queue, mandar uma mensagem a partir da queue ou esperar por uma mensagem. Neste sentido, as ISR também podem utilizar este objeto estando limitadas só ao mecanismo de envio de mensagem a partir da queue, pois a rapidez que as ISR necessitam de ser processada não permite estarem em modo de espera para uma possível mensagem. Dependendo do kernel as message

queue podem ter dois tipos de comportamentos: FIFO (first-in,first-out) ou LIFO

(last-in,first-out). Nem todos os kernel disponibilizam o comportamento LIFO, contudo, este mecanismo pode ser bastante benéfico, no caso de dar prioridade a certas mensagens consideradas como urgentes. Neste caso e na existência de uma fila com várias mensagens, a mensagem “urgente” seria processada em primeiro lugar.

(39)

Receber() Enviar ()

Message queue

Enviar sinal() Esperar por sinal()

Tarefa A

Tarefa B

Figura 2.10: Gestão de mensagens com semáforos.

devido a estas não serem processadas ao mesmo nível que são enviadas. Neste sentido, o modelo mais adequado é a utilização de semáforos contadores permitindo limitar o envio de mensagens consoante o nível disponível de processamento [21, 20].

2.3

Suportes ao Multicore

O aparecimento das arquiteturas multicore permitiu aos sistemas operativos tirar o proveito da paralelização dos cores para um melhores escalonamento das suas tarefas. Com isto, permitiu a introdução de novas configurações nos sistemas operativos. É neste contexto que é abordado dois tipo de ideologias de arquiteturas usadas nos sistemas operativos multicore: AMP (asymmetric multiprocessing) e SMP (symmetric multiprocessing).

2.3.1

Asymmetric multiprocessing

Na arquitetura AMP (figura 2.11) cada core tem o seu próprio sistema operativo, promovendo múltiplos ambientes de execução em paralelo semelhante a de um sistema singlecore. Neste sentido, cada core é independente e cada um tem o seu propósito específico. A fácil compreensão dos programadores neste sistema, deve-se a cada core comportar-deve-se como um sistema operativo singlecore, no deve-sentido em que cada um tem os seus próprios processos, escalonamento e gestão de memória. Esta arquitetura pode ser considerada homogénea no caso do sistema operativo

(40)

que é executado em cada core é o mesmo, ou pode ser considerada heterogéneo no caso da execução de sistemas operativos diferentes em cada core.

O ambiente homogéneo permite ao utilizador escolher em qual dos cores pretende executar a aplicação enquanto que comunica via IPC com os outros serviços do sistema (ex:device drivers) que estão presente nos outros cores. Este sistema per-mite que o cores não estejam sobrecarregados. No caso do ambiente heterogéneo como sistemas operativos serem diferentes em cada core, os utilizadores devem ter cuidado pois poderá ser necessário reformular o IPC entre os sistemas operativos. Outros dos possíveis conflitos destes ambiente está no acesso aos recursos. Um dos possíveis métodos para resolver, está em normalizar os mecanismos de acesso ao

hardware [9, 23].

Aplicação 1 Aplicação 2 Aplicação N

OS 1 OS 2 OS N

CPU 1 CPU 2 CPU N

Interconexão do sistema

Memória SO 1 Memória SO 2

... Memória SO N I/O I/O I/O I/O

Contolador de Memória

...

Figura 2.11: Arquitetura AMP

2.3.2

Symmetric multiprocessing

Na arquitetura SMP (figura 2.12), por outro lado, apenas um sistema operativo controla os vários cores dos sistema. O SO considera todos os cores de forma homogénea sendo que cada um tem acesso a memória comum. Deste modo, não restringe os cores dando-lhes a possibilidade de poderem partilhar os diferentes processos do SO. Este tratamento de igualdade, permite que cada core seja

(41)

in-dependente, dando a ideia que são vários singlecores a trabalharem em sintonia para um mesmo propósito. Esta arquitetura, permite que o código ser possa ser visto e ser processado em qualquer core, promovendo um paralelismo atraente e transparente para o programador. Contudo, os cores não são livres de fazer o que querem. Devido à concorrência dos cores, que os sistema operativo SMP utilizas-sem novos métodos controlo e de sincronização para o acesso aos seus recursos e novos métodos de escalonamento, permitindo distribuir da melhor forma as tarefas pelos diversos cores possibilitando um aumento da performance do sistema.

Aplicação OS

CPU 1 CPU 2 CPU N

Interconexão do sistema

Memória SO I/O I/O I/O I/O

Contolador de Memória

...

Figura 2.12: Arquitetura SMP

A generalidade dos sistemas de tempo-real tem primeiramente o requisito obter a capacidade de resposta rápida e só depois interessa a capacidade de transferência. Contudo, isto varia consoante as aplicações. Estas podem exigir mais throughput dando ênfase ao multicore do que propriamente capacidade de resposta rápida. Entretanto conjugar maior throughput com a característica de resposta rápida nas arquiteturas SMP pode ser considerado um dos maiores desafios para os progra-madores de sistemas operativos [9, 23].

2.4

Soluções de RTOS

A lista de RTOS existentes ultrapassa a centena. Nesta subsecção serão apresen-tadas e descritas sucintamente três das mais relevantes soluções.

(42)

2.4.1

µC/OS-II

O µC-OS/II, desenvolvido por Jean J.Labrosse, é um RTOS open-source com um kernel implementado em ANSI C e com apenas algumas linhas de código em

assembly, permitindo assim que este RTOS seja portável para vários processadores.

Este, derivado a sua arquitetura pode correr nos microprocessadores de 8-bit, 16-bit, 32 e 64-bit ou até mesmo em microcontroladores e DSPs. Contudo estes microprocessadores têm que disponibilizar o acesso ao stack pointer e aos registos do CPU de forma que seja possível fazer os push e os pop da stack.

O propósito deste RTOS está em aplicações embebidas, é personalizável pois é possível eliminar os serviços que não são necessários permitindo assim uma redução do footprint de memória. É um RTOS que pode executar 64 tarefas diferente mas que 8 pertencem ao sistema, restando assim outras 56 tarefas para aplicações. O seu algoritmo de escalonamento tem por base no HPF (Highest Priority First) e também viabiliza mecanismos de preemtividade possibilitando que as tarefas de maior prioridade interrompam tarefas de menor prioridade. Por esse motivo, neste RTOS, cada tarefa tem uma prioridade única. Contudo a tarefa de maior prioridade pode ser interrompida na ocorrência de um evento assíncrono (ISR), sendo esta logo executada no fim da interrupção.

O µC-OS/II contém serviços como mailbox, queues, semáforos, partições de memó-ria, etc. A simplicidade e o pequeno kernel ajusta-se perfeitamente para sistemas embebidos que requerem uma alta performance. Contudo, a possibilidade de usar 56 tarefas e cada uma com prioridade única são algumas das limitações apontadas [16, 22].

2.4.2

µTKernel

A empresa T-Engine Forum é a responsável pelo desenvolvimento do µT-Kernel. Este é um sistema operativo de tempo-real que conta com duas versões 1.0 e 2.0 para singlecore e outras duas para multicore, o SMP Kernel e o AMP T-Kernel. Este RTOS, desenvolvido com finalidade comercial e educacional, está implementado em C permitindo ser adaptado para várias plataformas que tenham arquiteturas até 32-bits. Este RTOS apresenta um vasto leque de API com três tipo de finalidades: funções relacionadas com o sistema operativo, funções relacionadas com a gestão do hardware e, por último, para dar apoio ao debug do sistema.

(43)

A configuração neste sistema permite adicionar alguns recursos sendo só preciso fazer uma pequena recompilação, ou então fazer uma pequena mudança. O seu escalonamento é baseado no HPF, no caso de existir duas ou mais tarefas com a mesma prioridade, a política de desempate é o FCFS (First-Come First-Served). Contudo, estas tarefas podem ser interrompidas de duas formas: por interrupções ou por exceções de tarefas. Estas exceções permitem que estas tarefas sejam tratadas como interrupções por software, caso contrário, as interrupções provêm de eventos do hardware.

Como o RTOS anterior, este também contém os serviços mailbox, queque, semáfo-ros, partição de memória, etc. Contudo, como desvantagem deste RTOS relativa-mente a outros, esta está no maior uso de memória ROM [3, 6, 17].

2.4.3

FreeRTOS

O FreeRTOS é um RTOS open-source e desenvolvido por Richard Barry. Neste momento este RTOS dá suporte a vinte sete diferentes arquiteturas e permite licença para uso educacional e comercial tendo tido 107000 downloads no ano de 2013 [24]. É um RTOS implementado em C e com um kernel de tamanho máximo de 9k bytes. Possui uma quantidade razoável de API para acesso ao sistema e a serviços como semáforos (binários e contadores), semáforos recursivos,

queqes, mutexes. O escalonamento é baseado em prioridades e no caso da existência

de tarefas com a mesma prioridade, a política de desempate é o Round Robin. Este RTOS está dividido em duas camadas: a camada “hardware independent” e “portable layer ”. A primeira camada, hardware independent, está responsável pela implementação da maior parte das funções do sistema operativo. A segunda camada, portable layer, está responsável pelo software específico da arquitetura, como por exemplo, o context switching [19].

Resumindo, é um RTOS com o intuito de ser simples e pequeno, perdendo em re-lação a outros RTOS na quantidade de serviços disponibilizados [6]. Contudo, este RTOS não tem limites execuções de tarefas, o que pode ser considerado vantajoso em comparação ao µC-OS/II.

(44)
(45)

Capítulo 3

Especificação do Sistema

Este capítulo tem como objetivo apresentar a especificação do RT-ARM(M)OS desenvolvido e as ferramentas necessárias para a sua realização. Para isso, este capítulo está dividido em três subcapítulos. Primeiramente é abordado a arquite-tura do hardware para que foi desenvolvido o RT-ARM(M)OS. Inicia-se com uma introdução geral às arquiteturas ARM e seguidamente é realizada uma descrição mais focada no processador Cortex-A9. Depois disto, é descrito o ambiente e as ferramentas usadas no desenvolvimento e depuração/simulação do software. Por último, são apresentadas as especificações do RT-ARM(M)OS, começando com a apresentação dos serviços que irão ser implementados e terminando com os meca-nismos necessários, que permitirão o seu funcionamento tanto em singlecore como em multicore.

3.1

Arquitetura da ARM

3.1.1

Introdução

Hoje em dia, grande parte dos sistemas embebidos de 32-bit são acompanhados por processadores com arquiteturas ARM. A ARM proveniente das siglas Advanced

RISC Machine, é uma empresa cujo o seu principal objetivo não é fazer o seu

próprio chip, mas sim vender as especificações e a propriedade intelectual às outras empresas, como, STMicroelectronics, Intel, Nvidia, Texas Instruments e Samsung, sendo que estas representam mais de mil milhões de processadores produzidos até os dias de hoje [25][26].

(46)

O principal objetivo da arquitetura da ARM é um design simples mas poderoso e adotando uma filosofia aproximada ao RISC (Reduce Instruction Set

Compu-ter ). A arquitetura RISC tem por base fornecer um reduzido número de simples

e poderosas instruções, que possam ser executadas num único ciclo de relógio.

Atualmente, a ARM adotou dividir as suas arquiteturas em três familias Cortex: Cortex-A, Cortex-R e Cortex-M [7][26].

• A família Cortex-A são orientados para aplicações genéricas e com requisito de performance. Normalmente permitem a execução de GPOS (como o Linux e Windows), de forma a disponibilizarem poderosas interfaces gráficas ao utilizador. Estes são geralmente usados nos smartphones, tablets, PDA ou

laptops.

• A família Cortex-R são orientados para sistemas de tempo-real. Estes, em comparação à família Cortex-A, oferecem menores latências a pedidos de interrupções e são mais determinísticos nos tempos de resposta. Geralmente são usados para controlar sistemas críticos que exigem tempo de resposta rápida.

• A família Cortex-M são orientados para sistemas que requerem baixo con-sumo. Operam com uma frequência de relógio menor que as outras duas famílias, e geralmente são usados em micro-controladores que desempenham funções com múltiplas entradas e saídas. Estes podem ser encontrados em robôs ou em aparelhos eletrónicos de consumo.

3.1.2

ARM Cortex-A9

Em 2008 a ARM lançou o processador Cortex-A9. Este processador ganhou popu-laridade por manter o equilíbrio entre alta performance e consumo de energia. O Cortex-A9 contêm um ciclo de relógio aproximado a 1GHz, originando um aumento superior a 50% em relação ao anterior processador, o Cortex-A8 [7]. Baseado na arquitetura ARMv7, este processador pode ser configurado até quatro cores, possi-bilitando o aumento da fluidez de execução das aplicações. Aqui são apresentadas algumas das suas características:

• Caches de nível 1(L1) associative-way de 16, 32 ou 64KB. • Tecnologia NEON para processamento multimédia.

(47)

• Unidade de Floating-point.

• Controlador de interrupções - Generic Interrupt Controller (GIC). • 9 a 12 estados do pipeline.

• Snoop Control Unit (SCU).

• Accelerator Coherency Port (ACP).

• Tecnologia ARM CoreSight Multicore Debug e Trace

ARM Cortex-A9 Core 4 Core 3 Core 2 Core 1 ARMv7 32b CPU 16-64k I-Cache 16-64k D-Cache NEON Data Engine Floating Point Unit

ARM CoreSight Multicore Debug and TRACE

ACP SCU

Dual 64-bit AMBA 3 AXI Generic Interrupt Controller

Figura 3.1: Processador Cortex-A9

Modos

Existem vários modos de execução dos processadores na arquitetura ARM, dei-xando o programador escolher o modo mais adequado para as suas aplicações. A utilização dos diferentes modos está associada às suas limitações. Para isso, os modos foram caracterizados por conterem, ou não, privilégios a determinadas operações, como por exemplo, o acesso à MMU. No total existem nove modos na ar-quitetura ARM. Destes modos, oito deles são caracterizados por terem privilégios

(48)

(abort, fast interrupt request, interrupt request, supervisor, monitor, hypervisor,

system e undfined), e apenas um sem privilégios (user ) [7]. A tabela 3.1 sumariza

as funcionalidades destes modos.

Tabela 3.1: Modos de execução do processador Cortex-A9

Modo Funcionalidade

Supervisor

(SVC)

Entra no modo na ocorrência de reset ou quando uma instrução SVC é executada.

FIQ Entra no modo na ocorrência de uma fast interrupt. IRQ Entra no modo na ocorrência de uma interrupt.

Abort (ABT) Entra no modo na ocorrência uma violação no acesso a memória.

Undefined Entra no modo na ocorrência de uma execução de uma instrução.

não definida

Monitor (MON) Modo para acesso ter acesso ao mundo seguro (TrustZone).

Hypervisor (HYP) Modo para a extensão de suporte à virtualização. Acedido com

a execução da instrução HVS(Hypervisor ).

System (SYS) Modo privilegiado obtendo os mesmos registos do modo user.

User (USR) Modo não privilegiado, onde ocorrem a maior parte das aplicações.

Register

O register file da arquitetura ARM é composto por dezoito registos de 32-bits: dezasseis deles são registos de dados, enquanto que os outros dois pertencem ao estado do processador. Conforme as especificações do EABI (embedded application

binary interface), dos dezasseis registos de dados referidos, normalmente os quatro

primeiros (R0-R3) são usados para os argumentos das funções. Caso esses registos não sejam suficientes para os argumentos, então estes devem ser guardados na

stack. Outra função que é atribuída ao registo R0 é o valor de retorno da função. Na

ocorrência do valor retorno ser superior aos 32-bits, este será distribuído também ao registo R1. Os registos R4 a R12 tipicamente são registos de uso geral, ou seja, podem ser usados para qualquer tipo de cálculos. Os três últimos registos de dados (R13, R14, R15) têm uma função especializada, nesse sentido, são atribuídas labels de forma a se poderem diferenciar dos restantes registos. As funções desses registos são os seguintes:

• O R13, denominado por stack pointer (sp), desempenha como função apon-tar para o topo da stack pertencente ao modo à que está em execução o processador;

(49)

• O R14, denominado por link register (lr), desempenha a função de guardar o endereço de retorno na chamada de uma sub-rotina;

• O R15, denominado por program counter (pc), desempenha a função de con-ter o endereço da próxima instrução a ser executada pelo processador.

R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 (sp) R14 (lr) R15 (pc) R10 R11 R12 R13 (sp) R14 (lr) User mode R0-R7,R15 e CPSR R8 R9 R13 (sp) R14 (lr) User mode R0-R12,R15 e CPSR R13 (sp) R14 (lr) User mode R0-R12,R15 e CPSR R13 (sp) R14 (lr) User mode R0-R12,R15 e CPSR R13 (sp) R14 (lr) User mode R0-R12,R15 e CPSR CPSR SPSR SPSR SPSR SPSR SPSR User and System

FIQ IRQ ABT SVC UND

R13 (sp) R14 (lr) User mode R0-R12,R15 e CPSR SPSR MON R13 (sp) User mode R0-R12,R15 e CPSR SPSR HYP

Figura 3.2: Conjunto dos registos ARM

Contudo, o uso dos registos depende do modo como o software está a ser processado e se o modo permite o seu uso. Por outras palavras, certos registos estão alocados fisicamente em diferente áreas, sendo eles restritos ao modo a que pertencem, não permitindo que sejam visíveis a outros modos. A figura 3.2 mostra todos os registos existentes e separados pelos seus modos. Como é possível ver, grande parte dos primeiros registos (r0-r12) e r15 são partilhados pelos vários modos, com exceção do modo FIQ, onde só é partilhado do r0-r7 e o r15. Por outro lado, os registos que estão de cor cinza, são os registos únicos e só visíveis ao próprio modo.

Os registos CPSR e SPSR presentes na figura 3.2, são os registos de acesso ao estado do processador (PSR), denominados de Current Program Status Register (CPSR) e de Save Program Status Register (SPSR). O CPSR é um registo que apresenta os valores do PSR durante a execução do processo, enquanto o SPSR é

(50)

um registo que consiste no valor do PSR que será carregado quando existir uma troca de modos do processador. O PSR (program status register ) está dividido em quatro campos de oito bits: flags, estado, extensão e controlo. No atual design, o campo da extensão e do estado são reservados para uso futuro, enquanto que o campo das flags destina-se às condition flags (negative, carry, zero, overflow), e o campo de controlo contém o modo do processador, o estado e os bits de máscara de interrupções (figura 3.3), [7][25][26]. N Z C V I F T MODE 31 30 29 28 7 6 5 4 0 Bit Campo Função

Flags Estado Extenção Controlo

Condição de Flags Máscaras de Interrupções Estado Thumb Modo do Processador

Figura 3.3: Program status register (PSR).

Generic Interrupt Controller

A arquitetura do GIC (Generic Interrupt Controller ) foi desenhada com o pro-pósito de cumprir com os requisitos propostos pelos perfis das arquitetura ARM A e R . Ele define quais os recursos de hardware que gerem as interrupções num sistema single ou multicore [27]. Os seus registos mapeados em memória pos-sibilitam a configuração das fontes de interrupções e dos seus comportamentos: ativar/desativar interrupções e atribuição de prioridades (em hardware).

A sua arquitetura apresenta-se em dois grandes blocos funcionais:

• Distributor: Possui os registos que controla as prioridades individuais de cada interrupção e decide, num sistema multicore, para qual das CPU

Inter-face deve ser enviado a interrupção.

• CPU Interface: Existe uma CPU Interface para cada core e é responsável por receber as suas interrupções. Os seus registos são acessíveis por software e permitem identificar e controlar o estado das interrupções recebidas.

(51)

As fontes de interrupções são identificadas por um ID único, onde cada core pode aceder até a um máximo de 1020 interrupções. As interrupções são divididas em três tipos:

• SGI (Software Generated Interrupt:) São interrupções geradas por

software. Na generalidade são utilizadas para a comunicação entre cores,

onde podem ser destinadas para qualquer core ou grupo específico. Os IDs reservados para estas interrupções vão desde 0 até 15.

• PPI (Private Peripheral Interrupt:) São interrupções geradas por pe-riféricos privados do core. Os IDs reservados para estas interrupções vão desde 16 até 31.

• SPI (Shared Peripheral Interrupt:) São interrupções geradas por peri-féricos partilhados por todos o cores presentes no hardware. Os IDs reserva-dos para estas interruções vão desde 32 até 1019.

3.2

Ambiente de Desenvolvimento

Este subcapítulo tem como finalidade descrever as ferramentas utilizadas para o desenvolvimento do software. Inicialmente são abordadas as ferramentas de edição, compilação e emulação, e seguidamente, são abordadas abordado as ferramentas de simulação física (plataforma e o seu SoC).

3.2.1

Xillinx ISE Desing Suite

A Xilinx oferece um grande conjunto de ferramentas de desenvolvimento desig-nado de Integrated Software Environment (ISE) Design Suite. Este conjunto está dividido em 3 edições: Logic Edition, Embedded Edition e DSP Edition. Neste sentido, só é abordada a edição (Embedded Edition) que foi utilizada para a reali-zação desta dissertação. Nesta edição, é adicionado ao EDK todas as ferramentas e capacidades da Logic Edition.

(52)

Embedded Development Kit (EDK)

O Embedded Development Kit (EDK) é um ambiente de desenvolvimento para de sistemas embebidos. Este integra as seguintes ferramentas:

• Xilinx Plataform Studio (XPS), para o desenvolvimento e configura-ção de componentes de hardware presentes numa arquitetura de um sistema embebido;

• Software Development Kit (SDK), é uma ambiente de desenvolvimento integrado para complemento do XPS para criação e verificação de aplicações embebidas. Baseado na framework Eclipse open-source que utiliza o compi-lador e depurador GNU C/C++, [31][32][33].

3.2.2

ARM Fast Models

Uma das formas para validar a aplicação criada proveniente do SDK, é a utiliza-ção da framework Fast Models. O Fast Models é um ambiente de fácil criautiliza-ção de modelos virtuais de plataformas e que permite rápidas simulações. As platafor-mas geradas são equipadas com o Cycle Accurate Debug Interface (CADI) onde disponibiliza uma API que permite às plataformas serem executadas de forma independente.

Os Versatile Express (VE) Fixed Virtual Platforms (FVP) são executáveis for-necidos pela ARM de modelos de plataformas virtuais estáticas, ou seja, não é possível personalizá-las. Estas contêm virtualmente a implementação de

mother-board, daughterboards cada uma com um processador ARM e estão associados por

inter-conectores como pode ser visto na figura 3.4.

System Canvas

O System Canvas é um GUI (Graphical User Interface) que permite a representa-ção gráfica do modelo, visualizando os componentes do sistema, portas externas e internos, conexões com esses portos. A natureza gráfica do System Canvas é uma ajuda para uma criação rápida e configuração de componentes ou sistemas que consistem em múltiplos componentes. Além disso, a partir da API fornecida pelo CADI do modelo, o System Canvas permite fazer o debug passo a passo, dando

(53)

Figura 3.4: Diagrama de blocos do modelo FVP_VE Cortex-A9x2

uma representação gráfica de todos os valores dos registos presentes no modelo [34][35][36].

3.3

Arquitetura do RT-ARM(M)OS

O RT-ARM(M)OS, acrónimo de “Real-Time ARM (Multicore) Operating System”, será o nome dado ao RTOS que será desenvolvido em linguagem C e em ARM

assembly. Será desenhado para plataformas com arquitetura ARM (ARMv7), e

disponibilizará API para a gestão dos seus serviços. Mais concretamente, para o escalonador, para a gestão de tarefas, para a gestão da heap e para a gestão dos

mutexes que será o serviço utilizado para a sincronização de tarefas. Para além

disso, disponibilizará ao utilizador a configuração desses mesmos serviços. Neste sentido, será possível quantificar o número de tarefas e o número de níveis de pri-oridade, definir o tamanho da heap e qual o tamanho de cada bloco e por último, quantificar o número de mutexes que estarão disponíveis no RTOS. Contudo, tam-bém será possível informar o número de cores disponíveis no hardware permitindo alterar o seu funcionamento em singlecore ou em multicore SMP.

Imagem

Figura 2.1: Exemplos da utilização de sistemas embebidos soft e hard real-time A introdução de novas e mais complexas aplicações, revolucionou a arquitetura destes sistemas, permitindo a introdução das arquiteturas multicore
Figura 2.2: Arquiteturas dos Sistemas Operativos: Monolítico vs Microkernel tura anterior, pois apresenta outra estratégia de redução de serviços presentes no kernel, transferindo os outros serviços para a camada do utilizador
Figura 2.4: Diferentes estados das tarefas
Figura 2.6: Diferentes divisões de memória cada uma com diferentes tamanhos Contudo, partições podem conter diferentes tamanhos
+7

Referências

Documentos relacionados

De seguida, vamos adaptar a nossa demonstrac¸ ˜ao da f ´ormula de M ¨untz, partindo de outras transformadas aritm ´eticas diferentes da transformada de M ¨obius, para dedu-

Este trabalho buscou, através de pesquisa de campo, estudar o efeito de diferentes alternativas de adubações de cobertura, quanto ao tipo de adubo e época de

O objetivo do curso foi oportunizar aos participantes, um contato direto com as plantas nativas do Cerrado para identificação de espécies com potencial

esta espécie foi encontrada em borda de mata ciliar, savana graminosa, savana parque e área de transição mata ciliar e savana.. Observações: Esta espécie ocorre

Dessa forma, os níveis de pressão sonora equivalente dos gabinetes dos professores, para o período diurno, para a condição de medição – portas e janelas abertas e equipamentos

O valor da reputação dos pseudônimos é igual a 0,8 devido aos fal- sos positivos do mecanismo auxiliar, que acabam por fazer com que a reputação mesmo dos usuários que enviam

17 CORTE IDH. Caso Castañeda Gutman vs.. restrição ao lançamento de uma candidatura a cargo político pode demandar o enfrentamento de temas de ordem histórica, social e política

O enfermeiro, como integrante da equipe multidisciplinar em saúde, possui respaldo ético legal e técnico cientifico para atuar junto ao paciente portador de feridas, da avaliação