• Nenhum resultado encontrado

Projecto de AC. Nº João Aguiam Nº Pedro Saraiva Nº Ricardo Nobre

N/A
N/A
Protected

Academic year: 2021

Share "Projecto de AC. Nº João Aguiam Nº Pedro Saraiva Nº Ricardo Nobre"

Copied!
12
0
0

Texto

(1)

Projecto de AC

Nº 57371 – João Aguiam

Nº 57392 – Pedro Saraiva

Nº 57411 – Ricardo Nobre

(2)

Objectivos

O objectivo deste projecto foi a implementação de um sistema de gestão de dois comboios, sobre um circuito desenhado pelos docentes da disciplina de arquitectura de computadores, feita em assembly no processador PEPE (Processador Especial Para Ensino). Este circuito é constituído por semáforos, sensores e agulhas, de modo a que os comboios circulem nele sem chocarem alternando entre a oval interior e exterior.

Introdução

Como referido anteriormente, este projecto foi implementado sobre um processador denominado PEPE. Este processador foi desenvolvido pelos docentes da cadeira de arquictetura de computadores no Instituto Superior Técnico no campus do TagusPark.

Este processador foi desenvolvido especialmente para o ensino, sendo um processador de 16 bits com endereçamento por byte. A sua implementação em termos de hardware é relativamente simples, comparando com outras arquicteturas comerciais; habitualmente mais desenvolvidas.

Muito resumidamente, o PEPE possui um banco de 16 registos; estando alguns reservados para flags(RE), stack pointer(SP), program counter(PC) entre outros; uma unidade lógica aritmética que efectua o processamento dos dados, ou seja possui várias operações, como soma, subtração, and , or entre outras, que manipulam dados dos registos para processar a informação. Como com 16 bits é impossível guardar muita informação, é necessário que haja uma interface de memória para guardar as instruções do programa a implementar e outros dados que sejam usados no próprio programa. O PEPE suporta uma interface de memória com 216 posições (ou seja 64Kbytes devido ao facto de o PEPE ter endereçamento por byte) visto poder endereçar 16 bits.

Outra utilidade muito útil que o PEPE também suporta, é a ligação de periféricos ao processador. Estes periféricos são tratados, pelo processador, como um elemento da interface de memória. Neste projecto, o objectivo é controlar um periférico, lendo e escrevendo dados nele. Este periférico, módulo da pista de comboios, é enderecado apartir da posição 8000H.

Assim como o PEPE, o módulo da pista de comboios também desenvolvido no IST e simula uma pista de comboios, com dois circuitos havendo ligação entre si através das agulhas cuja direcção pode variar. Tanto o módulo da pista de comboios como o PEPE encontram-se no simulador da cadeira de AC que nos possibilita simular a pista real onde o projecto vai ser testado.

Como foi referido anteriormente, o programa que gere os comboios é realizado na linguagem assembly. Esta linguagem é de muito baixo nível, com constantes acessos à memória e registos, todos geridos pelo programador. Apesar desta linguagem ser de baixo nível, existe outra ainda mais baixa, o código máquina, sendo o assembly a transformação desses códigos para instruções mais perceptiveis pelos humanos, utilizando menemónicas como por exemplo a instrução ADD que soma dois valores.

Funcionamento Geral da Pista de Comboios

Na execução deste projecto é suposto controlarmos os dois comboios presentes na pista de forma que:

● Os comboios circulem da oval interior para a exterior e o inverso sem colidirem ou descarilarem.

● No mesmo troço não pode existir mais do que um comboio.

● Um comboio só deve avançar para o troço seguinte se o semaforo desse troço estiver a verde ou amarelo

● Se o comboio estiver na parte final do troço e o semaforo seguinte estiver a vermelho ou amarelo o comboio deve circular com velocidade media

● Se estiver no ultimo sensor e o semaforo estiver vermelho o comboio para, caso contrario anda a velocidade maxima

● O semaforo anterior a um troço só fica verde ou amarelo quando o mesmo está livre

● Um troço fica livre quando um comboio passa no sensor intermedio do sensor seguinte.

● Após um comboio passar no primeiro sensor de um troço, o semáforo do troço anterior fica vermelho e o novo troço fica ocupado.

● Quando um comboio passa na zona da passagem de nivel, os semaforos desta devem piscar alternadamente entre cinzento e vermelho com um periodo de 0,5 segundos.

(3)

● O comboio so pode circular a velocidade media no troço da estação e deve ficar parado uns segundos no final deste troço

Abordagem ao problema

Na abordagem do problema comecámos por analisar ao promenor a pista de comboios, os seus sensores e semáforos e delimitámos a pista em 4 troços bem definidos. A delimitação da pista em troços é necessária para saber em que local se encontra determinado comboio, o que permite entre outras coisas, que um comboio não avance para o troço seguinte se esse estiver ocupado.

Considerámos o troço 0 a zona da estação entre o semáforo 2 e 3; o troço1 entre o semáforo 3 e 1; o troço 2 entre o semóforo 1 e 0; e finalmente o troço 3 entre o semáforo 0 e 2.

Para que os comboios podessem circular na pista sem colidirem foi necessário definir algumas condições, tais como os sensores onde se activam e desactivam as variáveis que indicam o estado do troço, ocupado(1) ou livre(0); o local onde se alteram os semáforos e as agulhas. Decidimos também, como sugerido no enunciado do projecto, criar um gestor de comboios que atendendo à cor dos semáforos, altera o estado do comboio e consequentemente a sua velocidade.

Inicialmente decidimos mudar a cor dos semáforos no gestor da pista, que actua conforme os eventos gerados na pista de comboios. Porém deparámo-nos com a dificuldade em determinar todas as situações de conflito na zona das agulhas, controlada pelos semáforos 0 e 1. Assim decidimos criar um gestor para estes dois semáforos que fosse independente do gestor de pista, ou seja que não reagisse directamente aos eventos ocorridos, mas sim de acordo com o estado dos troços sendos estes actualizados no gestor de pista. Desta forma, um comboio só avança para o troço seguinte se este estiver livre.

Resumindo a abordagem ao problema proposto foi a aseguinte:

● O gestor de pista altera as variáveis de estado (WORD's e TABLE's) que indicam a localização dos comboios na pista com base nos eventos gerados pelos sensores.

● Criámos um gestor dos semáforos 0 e 1 visto poder haver conflitos difíceis de prever pelo gestor de pista na zona das agulhas.

● O gestor de comboios, com base na cor do semáforo do fim do troço em que se encontra o comboio, altera a sua velocidade conforme a sua posição relativa dentro do troço.

Implementação e descrição de rotinas

Para a implementação da nossa abordagem tivemos de definir várias variáveis de estado, uma estrutura de dados, denominada por fila, bem como recorrer a interrupções para ler os eventos da pista de comboios e controlar o tempo de paragem na estação, e também a troca dos semáforos da passagem de nível.

No que diz respeito às variáveis de estado, como o próprio nome indica, estas contêm informação sobre o estado da pista. Achámos importante definir as seguintes variáveis:

TROCO Tabela com 4 bytes que contêm o estado de cada troço (0 – Livre; 1 – Ocupado)

FINAL_TROCO Tabela com 4 bytes, um para cada troço e indica se a zona desse troço entre o penúltimo sensor e último possui algum comboio (0 – Livre; 1 – Ocupado)

ULTIMO_SENSOR Tabela com 4 bytes, um para cada troço e indica se passou algum comboio no último sensor do respectivo troço (0 – Livre; 1 – Ocupado)

SEMAFORO_TROCO Esta tabela associa o respectivo troço ao semáforo que se encontra no seu final

LOCAL_COMBOIO Tabela com 2 bytes, um para cada comboio e contêm o troço em que o comboio se encontra

ESTADO_COMBOIO Tabela que contêm o estado em que o respectivo comboio se encontra

(4)

0 – Parado

1 – Velocidade Máxima 2 – Velocidade Média

ESTADO_SEMAFORO Tabela com 6 bytes, um para cada semáforo e contêm a cor de cada semáforo

PASSAGEM_Q Variável que indica se está algum comboio na zona da passagem de nível (0 – Livre; 1 – Ocupado)

CONTADOR_ESTACAO Variável com o valor do contador da estação

Passando à descrição mais detalhada de cada variável, bem como a sua utilidade. A variável que indica o estado de cada troço é fundamental para o gestor dos semáforos 0 e 1, visto neste ser testado o estado de alguns troços. A rotina que trata do semáforo da estação, também utiliza esta variável para verificar se o troço 1 está livre (ou não), condição necessária para por o semáforo 2 a verde.

Quanto à variável FINAL_TROCO e ULTIMO_TROCO, estas são fundamentais para o gestor de comboios, para saber se o comboio já se encontra na parte final do troço, ou inclusivé no último sensor. Isto porque se estiver na parte final do troco, ou seja entre o penúltimo e último sensor de cada troço, o gestor de comboios reduzirá a velocidade caso o semáforo esteja a vermelho ou amarelo. A variável do último sensor serve para fazer parar o comboio caso o semáforo esteja a vermelho, ou pou-lo a andar se estiver a verde ou amarelo. Outras duas variáveis muito importantes para o gestor de comboios, sao LOCAL_COMBOIO, ESTADO_COMBOIO, que, como foi referido na tabela, tem o local onde o comboio se encontra e o seu estado.

No que diz respeito à variável PASSAGEM_Q esta é fundamental para a interrupção do relógio de tempo real, para chamar a rotina que troca o valor dos semáforos da passagem de nível, caso esteja activada. O CONTADOR_ESTACAO, também é utilizado nesta interrupção, servindo de contador para o tempo de paragem dos comboios na estação.

Como foi enunciado no tópico anterior, tivemos de implementar uma estrutura de dados denominada fila. Esta estrutura de dados, também conhecida por FIFO – Fisrt In First Out, ou seja o primeiro elemento a ser inserido na fila será o primeiro elemento a ser lido, é nos útil para a leitura de eventos através de interrupções. Isto porque ao ser gerada esta interrupção, teremos de ir ao módulo da pista de comboios ler os dois bytes desse evento, e colocá-lo na fila, de modo a que o gestor de pista, quando for processar o evento, possa ler o mais antigo. Se tivessemos implementado esta estrutura através da pilha, FILO – First In Last Out, só teriamos acesso ao último evento gerado (mais recente), o que provocaria defeitos no tratamento dos dados, visto serem executados pela ordem inversa.

Para a implementação desta estrutura decidimos reservar três registos, que guardam o limite máximo da memória para a fila, ou seja, o endereço da primeira célula de memória onde já não se pode inserir o elemento; o endereço do valor a ler da fila e o endereço da célula a escrever na memória. Os registos utilizados sao respectivamente R8, R9 e R10.

Para se ler um elemento da fila, temos de aceder à posição de memória do registo R9 e colocá-lo em R1. Depois é necessário actualizar o R9 para ficar pronto para ler um novo elemento. Assim somamos dois a esse registo e verificamos se é igual ao limite máximo da fila, caso em que se coloca o R9 com o endereço inicial do espaço reservado para a fila. Para a implementação da rotina que insere um elemento a tecnica é a mesma, insere-se a palavra no endereço contido em R10, soma-se dois a esse registo e verifica-se se antigiu o fim do espaço reservado caso em que se processa de maneira igual à rotina para ler da fila.

É de referir que se a fila estiver vazia, o R9 e o R10 são iguais; esta condição é utilizada no gestor de pista. Se estivessemos a implementar o nosso projecto baseado na tecnica do polling, tinhamos de aceder a uma porta do periférico que nos indica se existem ou não eventos pendentes.

Para além das estruturas de dados, decidimos criar várias rotinas que efectuam processamento de elementos da pista de comboios, tais como mudar a velocidade do comboio, mudar estado do semáforo, mudar posição das agulhas, entre outras. Passamos a explicar o funcionamento geral de cada uma delas.

AndarComboio é um rotina que recebe o número do comboio e a velocidade a que se quer meter o respectivo comboio a andar. Para isso seleciona o comboio e envia para a pista de comboios o valor para

(5)

efectuar essa mudança. Posteriormente actualiza o estado do respectivo comboio. É de referir que se a velocidade colocada no comboio for a máxima o estado do comboio é 1, se for a média é o estado 2, caso contrário é o estado parado. O facto de só termos três estados para os comboios será explicado no gestor de comboios, onde será apresentado o diagrama de estados do mesmo.

A rotina MudaAgulha simplesmente envia para um determinado porto o valor recebido em R1 que ao ser interpretada pelo modulo pista de comboios resulta na alteração da direcção das agulhas.

ToOvalExterior e ToOvalInterior, como o próprio nome sugere, são rotinas que mudam as agulhas de modo a que o comboio possa circular da oval interior para a exterior e vice-versa.

No que diz respeito à rotina MudaSemaforo, é de referir que esta, após mudar a cor do semáforo no módulo da pista de comboios, altera a tabela com o estado do respectivo semfáro.

Para escrever no LCD,decidimos criar uma rotina exclusiva para esse efeito, a rotina EscreverLCD. Esta rotina recebe 4 parâmetros, endereço de memória onde a string com os caracteres a escrever se encontra; o tamanho da string; o endereço do LCD onde será escrita a string e finalmente o código ASCII do número de comboio. Este código ascci será escrito após a string, conforme o pretendido pelo enunciado.

Nesta rotina, fazemos um ciclo que começa com o tamanho da string e será decrementado até chegar a 0, altura em que se escreve o nº do comboio. Em cada passo deste ciclo, será enviado para o LCD correspondente um caracter da string. É de referir que, na altura da definição das variáveis, guardámos em memória as duas strings possiveis de serem escritas no LCD. Esta definição é feita recorrendo à instrução STRING que recebe entre pelicas o texto, e guarda em memória o código ASCII correspondente a cada caracter.

Como já referimos, decidimos implementar um gestor de comboios, que apenas recebe o número do comboio a controlar, e conforme o semáforo do troço onde se encontra, irá reagir a esse estado. Como a reação que o comboio irá ter depende do estado actual implementámos um diagrama de estados:

Como se pode observar, todas as transições para o estado “Parado” são feitas através de um semáforo vermelho, para o estado “Andar” através de um semáforo verde e para o estado “A Parar” através de um semáforo amarelo. Porém estas transições não ocorrerão em qualquer lugar da pista. Estas mudanças apenas ocorrem na parte final do troço, ou seja entre o penúltimo e último sensor do respectivo troço; porém as transições para o estado parado só ocorrerão se o comboio passou no último sensor do troço. Quanto à codificação de cada estado, decidimos que o estado “Parado” é representado como 0, o estado “Andar” como 1 e o estado “A Parar” como 2. Esta codificação poderá não parecer muito adequada, mas como o ciclo normal do estado do comboio é “Parado” - “Andar” - “A Parar” implementámos desta forma. Na implementação desta máquina de estados, criámos vários fluxogramas com o intuito de nos facilitar a programação em assembly, visto esta linguagem ser de muito baixo nível e díficil de programar directamente.

(6)

Como se pode observar no fluxograma, esta rotina irá ler da memória o estado do comboio, e conforme o seu estado chama a respectiva rotina. Como só temos três estados possiveis, apenas temos duas comparações. Caso não seja nenhum desses dois estados, “Parado” ou “Andar”, é porque estamos no estado “A Parar”. O processamente do gestor é realizado pelas rotinas de cada estado, que alteram ou não a velocidade do comboio.

Como no gestor de comboios efectuamos vários testes ao valor de um determinado semáforo, decidimos implementar uma rotina que fizesse isso mesmo à qual chamamos CorSemQ. Esta rotina recebe em R1 o número do troço sobre o qual se vai testar a cor contida em R2.

(7)

semáforo correspondente. Esta tabela mantêm-se constante ao longo de todo o programa e é inicializada numa rotina para esse efeito. Após sabermos o número do semáforo, lê-mos a sua cor, também com o acesso a uma tabela, e comparamos com a cor em R2.

No estado “Parado” apenas temos de ver se o semáforo onde o comboio se encotra está a verde ou a amarelo, caso em que o comboio passa para o estado “Andar” ou “A Parar”.

Como se observa pelo fluxograma desta rotina, é lido o local onde o comboio se encontra, e testada a cor dos semáforos como indicado anteriormente. É de notar primeiro é testado se o semáforo está a ver e só depois a amarelo, visto apenas o semáforo que antece a estação está a amarelo. Outro facto que queremos salientar, é que a mudança para o novo estado do comboio é efectuada através da rotina que muda a velocidade do comboio.

A rotina que trata do estado “Andar” é semelhante à anterior mas com condições diferentes. Como se pode observar através da máquina de estados do gestor de comboios, o estado “Andar” apenas transita para o estado “A Parar” ou para ele mesmo. Isto leva a que a rotina que muda a velocidade dos comboios só seja chamada com uma única velocidade, velocidade média. Também é de referir, que esta rotina apenas muda o estado do comboio se esse se encontrar no final do troço.

(8)

Mais uma vez, a rotina do estado “A Parar” se assemelha às anteriores. Assim como no estado “Parado”, a primeira condição a ser testada é a que tem mais probabilidade de ocorrer, ou seja primeiro testa-se o sinal vermelho e só depois o verde. Queremos apenas referir, que se o semáforo passar a verde enquanto o comboio se encontra neste estado, o comboio passa imediatamente para o estado “Andar”.

(9)

Após termos elaborado o gestor de comboios e termos definido algumas variáveis de estado necessárias para este, implementámos o gestor de pista. Como o próprio nome indica, o gestor de pista controla a pista de comboios, alterando as variáveis de estado relacionadas com este. Para além das variáveis, o gestor de sistema também muda o estado do semáforo 3. Os outros semáforos terão gestores próprios que irão mudar os semáforos baseados nas variáveis alteradas pelo gestor de pista.

O gestor de pista, verifica se há eventos pendentes através da leitura dos apontadores da fila, e se houverem vai analisá-los. Para verificar se há enventos pendentes, testa-se se a fila está vazia, ou seja se o apontador para o início da fila é igual ao apontador para o fim desta.

Ao analisarmos o fluxograma deste gestor observa-se a simplicidade deste. Apenas é necessario ler os dois bytes da fila, bytes que se encontram na mesma palavra na nossa estrutura de dados. Após a leitura destes dados e de alguma manipulação para separar os bytes, chama-se a rotina correspondente ao evento acorrido. Esta chamada é feita através do acesso a uma tabela que contêm em cada posição da mesma, o endereço da rotina correspondente a esta.

Para cada sensor, desenvolvemos uma rotina própria com as variáveis a alterar. Estas rotinas estarão resumidas na seguinte tabela.

(10)

RotSensor0

Activa variável do último sensor do troço 2

RotSensor1

Activa variável do último sensor do troço 1

RotSensor2

Local do comboio passa a ser o troço 0

Desactiva variável do último sensor do troço 3

Desactiva parte final do troço 3

Mete semáforo 3 a vermelho

Activa troço 0

Escreve no LCD a mensagem da estação

Activa parte final do troco 0

RotSensor3

Desactiva troço 3

Activa variável do último sensor do troço 0

RotSensor4

Local do comboio passa a ser o troço 1

Muda o semáforo 2 para Vermelho

Apaga LCD de cima

Desactiva variável do último sensor do troço 0

Aciva estado do Troço 1

Desactiva parte final do troço 0

Reinicia contador estação

RotSensor5

Desactiva Troço 0

Activa Final do Troço 1

Mete semáforo 3 a amarelo

RotSensor6

Activa variavel da passagem de nível

Actualiza local do comboio para o troco 3

Escreve no LCD a mensagem da passagem

Mete semáforo 4 a vermelho

Mete semáforo 5 a cinzento

Activa estado do troço 3

Desactiva parte final do troço 2

Desactiva último sensor do troço 2

RotSensor7

Local do comboio passa a ser troco 2

Actualiza estado do troço 2

Desactiva último sensor do troço 1

Desactiva Final do troco 1

RotSensor8

Desactiva troco 1

RotSensor9

Desactiva variavel da passagem de nível

Mete semáforo 4 a cinzento

Mete semáforo 5 a cinzento

Desactiva troço 2

Apagar LCD de baixo

Activa parte final do troço 3

RotSensor10

Activa parte final do troço 2

RotSensor11

Activa Último sensor do troço 3

(11)

Gostariamos de salientar o facto de no sensor 9 desactivarmos a variável da passagem de nível antes de alterarmos a cor dos semáforos 4 e 5, isto porque se fizessemos de ordem inversa poderia ocorrer a situação de ser gerada uma interrupção que trocasse o valos desses semáforos, o que levaria a que os semáforos não ficassem a cinzento. Também queremos referir o facto de termos tido especial atenção a todas as variáveis de estado e às suas modificações, pois qualquer falha teriam repercursões no funcionamente correcto dos comboios.

Como foi referido anteriormente, implementámos um gestor dos semáforos 0 e 1, visto poderem ocorrer situações particulares nas quais não seria fácil de prever através da modificação dos semáforos em alguns sensores.

Este gestor apenas se baseia no estado dos troços alterando os semáforos de forma a que estes nuncam possam estar os dois a verde ao mesmo tempo.

Também criámos uma função que gere o semáforo da estação, ou seja, através da interrupção de tempo real faz com que o comboio fique parado durante alguns segundos nesta zona. Passando esse tempo, esta rotina mete o semáforo da estação a verde, o que implica que o comboio arranque automáticamente. Para ver se o comboio se encontra parado na estação, apenas é necessário verificar se o último sensor do troço da estação está activo, pois o semáforo desse troço encontra-se sempre a vermelho à excepção do tempo entre arrancar e passar pelo primeiro sensor do troço seguinte.

Para além da rotina que gere o semáforo da estação, também criámos uma outra rotina que será chamada durante a interrupção gerada pelo relógio de tempo real. Essa rotina tem o intuito de trocar a cor dos semáforos entre cinzento e vermelho. Após alguma observação, reparámos que para torcar estas cores poderiamos fazendo apenas lendo a cor de um dos semáforos, e utilizando a instrução XOR com a mácara 0001H.

Como o módulo da pista de comboios e o relógio de tempo real geram interrupções é necessário definir as suas rotinas de excepção. Estas rotinas têm uma pequena diferença das outras, visto terminarem com a instrução RFE, que tem um comportamento diferente da instrução RET. A instrução RFE para além de fzr o return normal também repõe o registo de estado com as várias flags.

Na rotina de excepção da interrupção dos eventos gerados pela pista de comboios, temos de ler os dois bytes do porto correspondente do módulo da pista. Aqui testamos se a parte que passou no sensor é o topo de trás, caso em que sai da rotina sem guardar os dados. Caso não seja a parte de trás, temos de guardar os valores na fila para que sejam lidos pelo gestor de sistema.

(12)

Na interrupção do relógio de tempo real, temos de verificar se está algum comboio no troço da estação, situação na qual chamamos a rotina da estação. Também se verifica se está algum comboio na zona da passagem de nível, pois caso esteja lá algum, é necessário trocar a cor desses semáforos.

Para que o nosso programa funcione bem, necessitamos de inicializar algumas tabelas e mudar alguns semáforos. Para isso criámos uma função que processa-se essas inicializações.

É de referir que na inicialização da pista de comboios colocamos todos os semáforos a verde com a excepção dos semáforos da passagem de nível, pois serão incializados a cinzento. Este método permite que os comboios inicializem através do seu próprio gestor e não manualmente.

Outra inicialização que temos de fazer é a fila. Nesta rotina apenas são incializados correctamente os registos da estrutura de dados.

Para que as interrupções possam funcionar, é preciso activá-las. Este passo só pode ser feito após temos incializado a fila.

Referências

Documentos relacionados

Portanto, conclui-se que o princípio do centro da gravidade deve ser interpretado com cautela nas relações de trabalho marítimo, considerando a regra basilar de

O score de Framingham que estima o risco absoluto de um indivíduo desenvolver em dez anos DAC primária, clinicamente manifesta, utiliza variáveis clínicas e laboratoriais

nesta nossa modesta obra O sonho e os sonhos analisa- mos o sono e sua importância para o corpo e sobretudo para a alma que, nas horas de repouso da matéria, liberta-se parcialmente

Durante este estágio, passei a maior parte do tempo no internamento do serviço mas também estive algumas noites no serviço de urgências, para além das consultas externas

Taking into account the theoretical framework we have presented as relevant for understanding the organization, expression and social impact of these civic movements, grounded on

Em síntese, no presente estudo, verificou-se que o período de 72 horas de EA é o período mais ad- equado para o envelhecimento acelerado de sementes de ipê-roxo

Neste estudo foram estipulados os seguintes objec- tivos: (a) identifi car as dimensões do desenvolvimento vocacional (convicção vocacional, cooperação vocacio- nal,

5 “A Teoria Pura do Direito é uma teoria do Direito positivo – do Direito positivo em geral, não de uma ordem jurídica especial” (KELSEN, Teoria pura do direito, p..